As APIs HTTP autenticam os chamadores com uma credencial no header Authorization — uma API key ou bearer token (Authorization: Bearer <token>). Os esquemas mais fortes assinam cada pedido com HMAC sobre um pedido canónico para que as credenciais nunca sejam repetíveis, usam OAuth 2.0 client-credentials para tokens máquina-a-máquina e acrescentam mutual TLS onde é exigida identidade ao nível do transporte.
Bearer tokens e API keys
A autenticação mais simples é uma credencial bearer: o cliente apresenta um token secreto no header Authorization e o servidor valida-o. A RFC 9110 define o header Authorization e o seu prefixo de esquema, e o OAuth 2.0 define o esquema Bearer — Authorization: Bearer <token> — cuja propriedade definidora é que a mera posse concede acesso, pelo que o token deve viajar apenas sobre TLS e nunca aparecer num URL, log ou mensagem de erro. Uma API key é a mesma ideia com um segredo mais longevo, muitas vezes não expirável. Como uma credencial bearer é repetível se capturada, é a base e não o teto: é fácil de integrar e perfeitamente adequada sobre TLS para a maioria do tráfego, mas as operações de alto valor sobrepõem-lhe muitas vezes a assinatura de pedidos.
POST /v1/messages HTTP/1.1
Host: api.example
Authorization: Bearer eyJhbGciOi... # secret; TLS only, never logged
Content-Type: application/jsonAssinatura HMAC de pedidos
A assinatura de pedidos eleva a fasquia: em vez de enviar o segredo, o cliente usa-o para calcular um HMAC sobre uma representação canónica do pedido e envia apenas a assinatura. O servidor, detendo o mesmo segredo, recalcula a assinatura e compara. Como a assinatura cobre o método, o path, os headers-chave e um hash do corpo, uma assinatura capturada não pode ser repetida contra um pedido diferente, e como o próprio segredo nunca sai do cliente, capturar um pedido não revela a credencial. A construção espelha a assinatura de webhooks no sentido inverso e é o mesmo primitivo HMAC-SHA256 (RFC 2104 / RFC 6234). A parte delicada é o pedido canónico: ambos os lados têm de concordar byte a byte sobre como o serializar, ou toda a assinatura falha.
canonical =
HTTP-METHOD + '\n' +
URI-PATH + '\n' +
SORTED-QUERY + '\n' +
SIGNED-HEADERS (name:value, sorted, '\n'-joined) + '\n' +
HEX(SHA256(raw_body))
signature = HMAC_SHA256(secret, canonical)
Authorization: SIGV1 Credential=<key-id>,
SignedHeaders=host;x-date;content-type, Signature=<hex>Headers assinados e a data do pedido
Dois detalhes tornam sólida a assinatura de pedidos. Primeiro, uma lista explícita SignedHeaders nomeia exatamente que headers estão cobertos, para que um intermediário que acrescente ou reordene headers não relacionados não invalide a assinatura, ao passo que qualquer header que o cliente escolheu assinar fica à prova de adulteração. Segundo, uma data de pedido (um X-Date assinado ou o header Date padrão) faz parte do pedido canónico e é verificada contra o relógio do servidor dentro de uma tolerância — a mesma defesa contra replay dos webhooks, aplicada às chamadas de API de entrada. Em conjunto, significam que um pedido assinado está ligado ao seu conteúdo exato, aos seus headers declarados e a uma janela de tempo estreita; um pedido capturado é inútil poucos minutos depois.
Âmbito e rotação de chaves
As credenciais devem ter o menor privilégio que funcione e ser rotativas sem downtime. O âmbito (scoping) associa permissões a uma chave — que operações pode chamar, de que origem, a que ritmo — para que uma chave que só envia mensagens não possa ler definições de conta, e o raio de dano de uma chave exposta fique limitado. A rotação segue o padrão de chaves sobrepostas: emitir uma nova credencial, correr ambas em paralelo enquanto os clientes migram e depois revogar a antiga, para que nada quebre a meio do voo. As chaves devem ser identificáveis (um key id não secreto viaja no pedido para que o servidor saiba contra que segredo verificar e que âmbito aplicar) e revogáveis individualmente, para que uma integração comprometida seja cortada sem perturbar as restantes.
| Esquema | O que trafega | Força / uso |
|---|---|---|
| Chave API | Segredo de longa duração no Authorization | Base simples; somente TLS; fácil de expor em logs |
| Bearer token (OAuth 2.0) | Token de acesso de curta duração | Com expiração e âmbito; renovado via endpoint de token |
| Assinatura HMAC de solicitações | Assinatura (o segredo fica local) | Resistente a replay e com evidência de adulteração em cada solicitação |
| mTLS | Certificado X.509 do cliente | Identidade na camada de transporte; forte, porém com operação mais pesada |
Mutual TLS
O mutual TLS autentica o cliente na camada de transporte: além de o servidor apresentar um certificado, o cliente apresenta o seu próprio certificado X.509 durante o handshake, e o servidor admite apenas ligações cujo certificado encadeie até uma CA de confiança e corresponda a uma identidade inscrita. Isto liga a identidade de API a uma chave criptográfica gerida ao nível da ligação, em vez de um segredo bearer num header, o que é atrativo para ligações máquina-a-máquina de alta garantia e para fixar (pinning) um parceiro a certificados específicos. O custo é operacional — emissão, distribuição, rotação e revogação de certificados — pelo que o mTLS é normalmente reservado às integrações mais sensíveis, muitas vezes combinado com um bearer token ou uma assinatura para autorização de granularidade fina por cima da identidade de transporte grosseira.
OAuth 2.0 client-credentials para M2M
Para integrações servidor-a-servidor sem utilizador final presente, o OAuth 2.0 (RFC 6749) define o grant client-credentials. O cliente autentica-se num token endpoint com o seu client_id e client_secret (ou um certificado de cliente) e recebe um access token de curta duração, que apresenta depois como bearer token nas chamadas de API até expirar e ser renovado. A vantagem sobre uma API key estática é o tempo de vida e o âmbito: os tokens são de curta duração, pelo que um token capturado expira depressa, e trazem âmbitos explícitos, pelo que um token gerado para envio não pode administrar a conta. Este é o padrão standard para acesso de API máquina-a-máquina e o mecanismo que o guia de autenticação da BroadNet documenta de forma concreta para os seus endpoints.
POST /oauth/token HTTP/1.1
Host: auth.example
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id=<id>
&client_secret=<secret>
&scope=messages:send
-> { "access_token": "...", "token_type": "Bearer",
"expires_in": 3600, "scope": "messages:send" }Perguntas frequentes
Qual é a diferença entre um bearer token e a assinatura HMAC?
Um bearer token é enviado em cada pedido e concede acesso por posse, pelo que um token capturado é repetível até expirar. A assinatura HMAC nunca envia o segredo — o cliente assina um pedido canónico e envia apenas a assinatura, pelo que um pedido capturado não pode ser repetido contra uma chamada diferente e a própria credencial nunca é exposta.
Porque é que a assinatura HMAC precisa de um pedido canónico?
Porque ambos os lados têm de calcular a string idêntica para obter assinaturas correspondentes. O pedido canónico fixa exatamente como o método, o path, a query ordenada, os headers assinados e o hash do corpo são serializados. Qualquer divergência — ordem dos headers, whitespace, um corpo re-codificado — produz uma assinatura diferente e o pedido é rejeitado mesmo sem adulteração.
O que me dá o OAuth 2.0 client-credentials face a uma API key?
Tempo de vida curto e âmbito explícito. O cliente troca as suas credenciais num token endpoint por um access token de curta duração e com âmbito (RFC 6749). Um token capturado expira depressa, e um token gerado para envio não pode administrar a conta. Uma API key estática, por contraste, é longeva e tipicamente ampla.
Como devem as API keys ter âmbito e ser rotacionadas?
Conceda o menor privilégio — restrinja cada chave às operações, origens e ritmo de que precisa — para que uma fuga fique contida. Rode com chaves sobrepostas: emita uma nova credencial, corra ambas em paralelo enquanto os clientes migram e depois revogue a antiga. As chaves devem trazer um key id não secreto e ser revogáveis individualmente para que uma integração comprometida seja cortada isoladamente.
Quando compensa o mutual TLS pelo seu custo operacional?
Quando precisa de identidade criptográfica ao nível do transporte para uma ligação máquina-a-máquina de alta garantia, ou para fixar um parceiro a certificados específicos. O mTLS admite apenas clientes cujo certificado X.509 encadeie até uma CA de confiança. É mais pesado de operar — emissão, rotação, revogação — pelo que costuma ser reservado às integrações mais sensíveis, muitas vezes acamado com um token ou assinatura para autorização.
Porque é que as credenciais bearer nunca devem aparecer num URL ou log?
Porque uma credencial bearer concede acesso apenas por posse. Os URLs são registados por proxies, guardados no histórico do browser e expostos pelo header Referer, e os logs de aplicação são amplamente legíveis, pelo que um token em qualquer deles fica efetivamente divulgado. As credenciais bearer devem viajar apenas no header Authorization sobre TLS e ser removidas dos logs.
Especificações de origem
Os padrões publicados nos quais esta página se baseia. Abre num novo separador.