Uma chave de API é uma string única que identifica o app que chama uma API; segurança de chaves de API é a disciplina de limitar o escopo e proteger a chave. Precisão primeiro, porque a maioria das definições embaralha isso: uma chave identifica a aplicação, fornece apenas autenticação fraca (é uma credencial bearer — quem a segura, é você) e carrega autorização grosseira (o escopo que foi anexado na criação). Usuários são autenticados por tokens; apps são identificados por chaves — e nenhuma RFC define a chave de API. É uma convenção, e é exatamente por isso que a segurança dela é a sua configuração, não a garantia de um padrão.
Principais pontos
| Pergunta | Resposta |
|---|---|
| O que uma chave faz | Identifica o app · mede o uso · ancora rate limits |
| Os dois bichos | Chaves publicáveis (feitas para embarcar) vs. chaves secretas (classe senha) |
| A escada do armazenamento | Hardcoded: nunca → variáveis de ambiente: o mínimo → gerenciador de segredos: o padrão |
| A lei de ferro | Qualquer coisa em um bundle de cliente é pública — planeje para a extração |
| Resposta a vazamento | Revogar → substituir → limpar o histórico → auditar — em minutos, não dias |
A requisição, e os dois tipos de chave
GET /v1/search?q=espresso HTTP/1.1
Host: api.example.com
X-Api-Key: pk_live_7f2c… ← em um HEADER — URLs acabam em logs,
histórico e referrers
Dois bichos diferentes dividem um nome:
chave publicável embarca em bundles web/mobile · identifica o app,
mede o uso · projetada sabendo que SERÁ extraída
chave secreta só no servidor · credencial bearer classe senha ·
quem a segura é você
O modelo publicável na prática — chaves que embarcam porque a segurança vive em outro lugar:
// JavaScript / Node.js — Back4app JS SDK
// Publishable keys: safe to ship BECAUSE authorization lives server-side
Parse.initialize(APP_ID, JS_KEY); // both ship in your bundle — by design
Parse.serverURL = 'https://parseapi.back4app.com';
// What protects data isn't key secrecy — it's CLPs + ACLs checked per request
// The one key that never ships: the Master Key bypasses every ACL and CLP.
// Server-only (Cloud Code / trusted backend), read from env or secret manager. // Flutter / Dart — Back4app Flutter SDK
// Publishable keys: safe to ship BECAUSE authorization lives server-side
await Parse().initialize(
appId, // ships in the app — by design
'https://parseapi.back4app.com',
clientKey: clientKey, // publishable, extractable, NOT a secret
);
// What protects data isn't key secrecy — it's CLPs + ACLs checked per request
// The Master Key bypasses every ACL and CLP: server-only, never in the app. // iOS / Swift — Back4app Swift SDK
// Publishable keys: safe to ship BECAUSE authorization lives server-side
ParseSwift.initialize(
applicationId: appId, // ships in the IPA — by design
clientKey: clientKey, // publishable, extractable, NOT a secret
serverURL: URL(string: "https://parseapi.back4app.com")!
)
// What protects data isn't key secrecy — it's CLPs + ACLs checked per request
// The Master Key bypasses every ACL and CLP: server-only, never in the app. // Android / Kotlin — Back4app Android SDK
// Publishable keys: safe to ship BECAUSE authorization lives server-side
Parse.initialize(
Parse.Configuration.Builder(context)
.applicationId(APP_ID) // ships in the APK — by design
.clientKey(CLIENT_KEY) // publishable, extractable, NOT a secret
.server("https://parseapi.back4app.com")
.build()
)
// What protects data isn't key secrecy — it's CLPs + ACLs checked per request
// The Master Key bypasses every ACL and CLP: server-only, never in the app. Chaves de API vs. tokens vs. JWTs
| Chave de API | Access token OAuth | JWT | |
|---|---|---|---|
| Identifica | A aplicação | O usuário (e o grant) | O que suas claims disserem |
| Emissão | Uma vez, por um admin | A cada login, por um fluxo | É um formato, não uma emissão |
| Vida útil | Até rotacionar (muitas vezes nunca) | Minutos a horas | O que o exp disser |
| Escopo | Fixo na criação | Escopos por grant | Definido pelas claims |
| Padrão | Nenhum — convenção | OAuth 2.0 | RFC 7519 |
| Trabalho certo | Identificação server-to-server, medição | Acesso a API delegado pelo usuário | Transporte de claims assinadas |
A comparação colapsa em uma frase que vale memorizar: chaves identificam apps; tokens autenticam usuários. Usar uma chave onde a identidade do usuário importa é reconstruir autenticação mal feita; usar tokens por usuário para medição anônima de apps é maquinário sem propósito.
Onde as chaves vivem: a escada do armazenamento
Hardcoded — nunca. Código-fonte é copiado, forkado e commitado; o git lembra para sempre, e bots de varredura de segredos encontram chaves em commits públicos em minutos. Variáveis de ambiente — o mínimo, com a ressalva sobre a qual o cheat sheet da OWASP é direto: env vars vazam por logs de erro, dumps de processo e definições de contêiner; elas mantêm segredos fora do git, não fora de problemas. Um gerenciador de segredos — o padrão do time: criptografado em repouso, com acesso controlado por serviço, auditado por leitura, rotacionável centralmente (opções open-source incluem Vault, SOPS e Infisical). Adicione a higiene que torna vazamentos sobreviváveis: chaves geradas com aleatoriedade criptográfica, prefixadas (estilo sk_live_…) para que scanners as reconheçam, armazenadas com hash no lado do provedor como senhas, uma chave por app por ambiente — e varredura de segredos (gitleaks, trufflehog) plugada no CI, para que o commit que vaza uma chave falhe antes de chegar ao repositório.
O problema do client-side, com honestidade
Todo explicador diz “não coloque chaves secretas no código do cliente”; quase nenhum diz a segunda metade: seu bundle é público. JavaScript web é legível por definição; binários mobile são desempacotados e vasculhados por strings rotineiramente; a ofuscação eleva o esforço de minutos para horas, uma única vez. Duas consequências seguem. Primeira: as únicas chaves que pertencem a clientes são as publicáveis — projetadas para identificar, não para proteger, com a autorização real aplicada server-side a cada requisição. Segunda: quando um cliente precisa usar um serviço de terceiros com chave secreta, o segredo fica atrás do seu próprio backend — o padrão proxy:
Quando uma chave vaza: o runbook
O relógio importa — bots monitoram repositórios públicos e exploram chaves commitadas em um a cinco minutos. Em ordem: 1 · Revogue a chave no provedor — antes de investigar, antes da daily. 2 · Substitua — emita a nova chave e faça o deploy dela via configuração, não código. 3 · Limpe — remova do código-fonte e do histórico do git; uma linha apagada segue viva em cada clone. 4 · Audite — logs do provedor na janela do vazamento: o que foi lido, criado, gasto. 5 · Amplie — qualquer coisa co-localizada com a chave (o mesmo .env, o mesmo repo) presume-se queimada; rotacione também. E a ressalva que separa resposta real de ritual: a revogação impede o uso futuro — ela não desexfiltra dados. O que foi levado durante a janela é um incidente, não uma rotação.
Rotação sem downtime
A rotação limita o valor de vazamentos não detectados — uma chave roubada com 60 dias restantes é um ativo diferente de uma válida para sempre. Cadência baseada em risco: 30–90 dias para chaves de escopo amplo ou compartilhadas externamente, até um ano para as internas de escopo estreito, imediatamente em suspeita de exposição ou saída de alguém que a teve. O movimento de zero downtime é a sobreposição de chave dupla: emita a nova chave enquanto a antiga segue válida, migre os deploys com calma e então revogue a antiga — o mesmo truque que sistemas de refresh token formalizam. Regimes de compliance cada vez mais exigem o calendário; o argumento de segurança nunca precisou dele.
Casos de uso comuns
- Integração server-to-server — o habitat nativo da chave: um serviço se identificando para outro.
- Medição de uso e cobrança — a chave como a unidade que provedores contam, limitam e faturam.
- Identificação publicável de cliente — bundles de app carregando chaves feitas para exposição, com a autorização em outro lugar.
- Separação de ambientes — chaves de teste e de produção mantendo acidentes de staging fora dos dados de produção.
- Contenção de abuso — rate limits por chave e revogação como os controles de raio de dano.
Qual credencial você deveria usar? Matriz de decisão
| Situação | Use |
|---|---|
| Backend chamando uma API de terceiros | Chave secreta, em um gerenciador de segredos |
| Identificar seu app a partir de web/mobile | Chave publicável + autorização server-side |
| Agir em nome de um usuário logado | Tokens OAuth, não chaves |
| Claims assinadas entre serviços | JWTs |
| Cliente precisa de um serviço com chave secreta | Seu backend como proxy — o segredo nunca embarca |
| Máquina-a-máquina com auth no estilo usuário | Fluxo client credentials do OAuth |
Limitações e trade-offs
- Chaves não provam posse. Uma string bearer não oferece vínculo criptográfico com o chamador; para auth de serviço de alta garantia, TLS mútuo e requisições assinadas existem por um motivo.
- Credenciais estáticas envelhecem mal. Sem expiração, todo vazamento fica em aberto até ser notado; a rotação é o substituto manual do ciclo de vida que tokens ganham de graça.
- Escopos grosseiros compartilham demais. Uma chave com permissões amplas é uma chave-mestra; escopo granular custa administração e paga em raio de dano.
- Chaves identificam, não autenticam. Construir confiança em nível de usuário sobre identificação em nível de app é o padrão de broken authentication que auditores procuram primeiro.
- Deriva de inventário é real. Chaves sem uso de integrações antigas seguem válidas até serem deletadas — a prima credencial-zumbi dos endpoints zumbis.
Chaves de API no Back4app
O Back4app é uma plataforma open-source de Backend as a Service (BaaS) que combina banco de dados gerenciado, APIs REST e GraphQL geradas automaticamente, autenticação, armazenamento de arquivos e funções serverless com Cloud Code. Seu modelo de chaves é a seção do client-side tornada concreta: o Application ID e as client keys embarcam dentro dos seus apps por design — a própria documentação do Back4app é explícita: client keys não são mecanismos de segurança — porque a autorização nunca depende delas: toda requisição é verificada server-side contra permissões em nível de classe e ACLs, então uma chave extraída concede ao atacante exatamente o que um usuário anônimo tem. O único segredo de verdade é a Master Key, que ignora toda ACL e CLP: ela vive apenas no servidor — Cloud Code, backends confiáveis, env ou gerenciador de segredos — e nunca em um bundle. As abas de código mostram a divisão na prática; o runbook se aplica só à master key, e esse é o ponto: um segredo para guardar é postura de segurança, quarenta é uma planilha.
Perguntas frequentes
O que é uma chave de API?
Uma string única que um provedor de API emite para uma aplicação registrada, enviada com cada requisição — idealmente em um header — para que o servidor identifique o chamador, aplique suas permissões, meça o uso e imponha rate limits. Detalhe notável: nenhum padrão a define — chaves de API são uma convenção, não um protocolo.
Chave de API é uma senha?
Uma chave secreta é funcionalmente da mesma categoria das senhas: é uma credencial bearer, então qualquer um que a segure é tratado como você — mesma disciplina de armazenamento, mesmas consequências de violação. As diferenças: chaves identificam aplicações, não pessoas, e muitas nunca expiram, a menos que você as rotacione.
Qual a diferença entre chave de API e token?
Chaves identificam apps; tokens autenticam usuários. Uma chave é estática, gerada por um admin e com escopo de aplicação; um access token OAuth é emitido no login, tem vida curta, é renovável e carrega as permissões de um usuário específico. Identificação server-to-server combina com chaves; qualquer coisa específica de usuário pertence a tokens.
Onde devo armazenar chaves de API?
Nunca no código-fonte. Variáveis de ambiente em um arquivo fora do versionamento são o mínimo — com a ressalva de que vazam por logs, dumps de processo e definições de contêiner — e um gerenciador de segredos é o padrão de time: criptografado em repouso, com controle de acesso, auditado e rotacionável.
Posso colocar uma chave de API no frontend ou no app mobile?
Apenas uma chave publicável, projetada para isso. Qualquer coisa em um bundle JavaScript ou binário de app é pública — a extração é rotineira e a ofuscação só a atrasa. Chaves secretas ficam no servidor; quando um cliente precisa de um serviço com chave secreta, roteie a chamada pelo seu próprio backend.
O que fazer quando uma chave de API vaza?
Imediatamente: revogue a chave, faça o deploy de uma substituta, limpe-a do código e do histórico do git, audite os logs de uso em busca de abuso e rotacione tudo que estava armazenado junto dela. Aja rápido — bots testam chaves commitadas em repositórios públicos em minutos — e lembre: a revogação impede o uso futuro, não desfaz os dados já levados.
Com que frequência devo rotacionar chaves de API?
Baseie no risco: a cada 30–90 dias para chaves de escopo amplo ou expostas externamente, mais tempo para as internas de baixo risco, e imediatamente em suspeita de exposição ou saída de alguém do time. Rotação sem downtime usa uma janela de sobreposição em que a chave antiga e a nova valem juntas enquanto os deploys se atualizam.
Como chaves de API vazam?
Em ordem de infâmia: commitadas em repositórios git, embarcadas em bundles de cliente e binários mobile, colocadas em URLs onde logs de servidor e histórico do navegador as capturam, impressas em logs de aplicação e de CI, e coladas em chats e tickets. Todo vetor é prevenível, e é isso que torna a lista deprimente.