▸ API · Fundamentos

Autenticação e escopos

A chave gsk_ no header Authorization, o que cada escopo libera, 401 vs 403 e rotação.

atualizado em 2 set 2026versão v1

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.

header
Authorization: Bearer gsk_a1b2c3d4KZ8mQvR7tYw2NpX5LhJ0eSg6UdF9BcA3iOk

A 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

Formatogsk_ + 43 caracteres base64url (256 bits). Atravessa header, URL e variável de ambiente sem escape.
Onde criarConfigurações → Desenvolvedores. Só quem é dono da conta cria e revoga.
Nome2 a 40 caracteres. Diga onde ela roda (ci-producao, deploy-vercel).
SegredoAparece UMA vez, na criação. Depois, só os 8 primeiros caracteres (o hint) — pra reconhecer qual revogar.
Teto10 chaves ativas por conta. Revogadas não contam.
EscoposFixados na criação. Pra trocar, crie outra chave.
DeclaraçãoObrigató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.

EscopoLiberaEndpoints
scans:readLer rondas e relatóriosGET /me · GET /scans · GET /scans/{id} · GET /scans/{id}/report · GET /scans/{id}/report.pdf
scans:writeDisparar e cancelar rondasPOST /scans · POST /scans/{id}/cancel
apps:readListar os apps monitoradosGET /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 /scans não pede authorized no 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: trueveja as opções da ronda.
Por que na chave, e não em cada ronda.
Um booleano exigido a cada chamada vira constante no cliente: todo mundo deixa fixo em 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

SignificaO que fazer
401Nã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.
403Sei 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.
401 · WWW-Authenticate: Bearer realm="guarita", error="invalid_token"
{
  "error": "unauthorized",
  "message": "Chave de API ausente ou inválida. Envie `Authorization: Bearer gsk_...` — crie a sua em Configurações > Desenvolvedores."
}
403 · application/json
{
  "error": "insufficient_scope",
  "message": "Esta chave não tem a permissão \"scans:write\".",
  "required": "scans:write"
}
A API não diz “essa chave existe mas foi revogada”: ajudaria mais quem sonda chaves do que quem esqueceu de trocar a variável. E um recurso de outra conta responde 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 401 no 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.

  1. Crie a chave nova com os mesmos escopos.
  2. Troque a variável de ambiente em todos os lugares onde a antiga roda.
  3. Confirme com GET /me usando a nova.
  4. 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_id de GET /me basta pra identificar a chave.
Achou algo errado ou faltando? help@guarita.dev — com o x-request-id, se for sobre uma resposta.