Autenticação e escopos
A chave gsk_ no header Authorization, o que cada escopo libera, 401 vs 403 e rotação.
O header
Toda chamada leva a chave no header Authorization, esquema Bearer. Não há chave por query string nem por cookie — chave em URL vaza em log, histórico e Referer.
Authorization: Bearer gsk_a1b2c3d4KZ8mQvR7tYw2NpX5LhJ0eSg6UdF9BcA3iOkA sessão do painel não vale aqui, de propósito: ela dura 7 dias, carrega a identidade da pessoa e morre na troca de senha. Uma credencial de máquina precisa viver o tempo da integração, ser revogável sozinha e fazer só um pedaço do que a pessoa faz.
A chave
| Formato | gsk_ + 43 caracteres base64url (256 bits). Atravessa header, URL e variável de ambiente sem escape. |
| Onde criar | Configurações → Desenvolvedores. Só quem é dono da conta cria e revoga. |
| Nome | 2 a 40 caracteres. Diga onde ela roda (ci-producao, deploy-vercel). |
| Segredo | Aparece UMA vez, na criação. Depois, só os 8 primeiros caracteres (o hint) — pra reconhecer qual revogar. |
| Teto | 10 chaves ativas por conta. Revogadas não contam. |
| Escopos | Fixados na criação. Pra trocar, crie outra chave. |
| Declaração | Obrigatória com scans:write: a checkbox “só escaneio apps meus ou com autorização expressa”. Gravada com data, versão dos Termos, IP e user-agent — veja abaixo. |
Escopos
Cada endpoint exige um escopo, e a chave só carrega os que você marcou. Uma chave de leitura vazada não dispara ronda nem gasta cota — expõe relatórios, o que já é grave, mas não vira gerador de tráfego e de fatura.
| Escopo | Libera | Endpoints |
|---|---|---|
scans:read | Ler rondas e relatórios | GET /me · GET /scans · GET /scans/{id} · GET /scans/{id}/report · GET /scans/{id}/report.pdf |
scans:write | Disparar e cancelar rondas | POST /scans · POST /scans/{id}/cancel |
apps:read | Listar os apps monitorados | GET /apps |
Regra prática: o passo de CI que só decide falhar o build pelo risco da última ronda precisa de scans:read e nada mais. Dê scans:write só à integração que dispara.
A declaração de autorização
Ao criar uma chave com scans:write, você marca a checkbox “só escaneio apps meus ou com autorização expressa do responsável”. A Guarita grava a declaração com data, versão dos Termos, IP e user-agent — uma vez, na chave, como nas integrações da Vercel e do Lovable.
- Vale pra toda ronda disparada com a chave. Por isso
POST /scansnão pedeauthorizedno corpo. - Chave só de leitura não declara nada: ela não escaneia.
- Cada ronda continua registrando a autorização (data, versão dos Termos, IP e user-agent) — a declaração da chave é a origem dela.
- O modo agressivo pede uma confirmação a mais, por ronda:
authorized_intrusive: true— veja as opções da ronda.
true e ninguém lê. Declarar uma vez, com data, Termos e IP registrados, é evidência de verdade — e é como as integrações da Vercel e do Lovable já funcionavam.401 vs 403
| Significa | O que fazer | |
|---|---|---|
| 401 | Não sei quem você é: chave ausente, fora do formato, inexistente, revogada — ou o plano deixou de incluir a API. O corpo é o mesmo em todos os casos. | Confira a variável de ambiente, o estado da chave no painel e o plano. Nunca repita a chamada. |
| 403 | Sei quem você é, e essa chave não pode isso: falta o escopo da rota. | Crie uma chave com o escopo em required. Retry nunca resolve. |
{
"error": "unauthorized",
"message": "Chave de API ausente ou inválida. Envie `Authorization: Bearer gsk_...` — crie a sua em Configurações > Desenvolvedores."
}{
"error": "insufficient_scope",
"message": "Esta chave não tem a permissão \"scans:write\".",
"required": "scans:write"
}404, não 403 — um 403 confirmaria que o id existe.Plano
A API faz parte dos planos Pro e Business. O plano é reavaliado em toda requisição, não só na criação da chave:
- Conta cai pra um plano sem API → toda chamada responde
401no mesmo instante. As chaves não são revogadas nem apagadas. - Conta volta pra um plano com API → as mesmas chaves voltam a funcionar. Nada pra reemitir.
- Revogar funciona em qualquer plano. Tirar acesso nunca depende de pagar.
Um 401 repentino numa integração estável há meses costuma ser cobrança, não credencial. Confira o plano antes de rotacionar.
Rotacionar e revogar
Revogar vale na hora: a chave é resolvida por hash a cada request, com o filtro de revogação dentro da própria consulta. Não há cache nem token auto-contido que sobreviva.
- Crie a chave nova com os mesmos escopos.
- Troque a variável de ambiente em todos os lugares onde a antiga roda.
- Confirme com
GET /meusando a nova. - Revogue a antiga. As duas convivem enquanto durar a troca.
A lista de chaves mostra a data do último uso — é por ela que você acha a chave esquecida antes de revogar.
A chave é uma senha
- Não vai pro repositório. Nem em exemplo, nem em commit que você pretende reescrever. Git guarda tudo.
- Não vai pro front-end. Segredo em código que roda no navegador é público. Chame a API do servidor, do CI ou de uma função serverless. O CORS da Guarita libera só a origem do painel, então do navegador nem funcionaria.
- Não vai pro suporte, print ou log. Apareceu em um desses? Considere vazada e rotacione. O
key_idde GET /me basta pra identificar a chave.
x-request-id, se for sobre uma resposta.