# Escopos de API para agentes autônomos de programação que contêm riscos

Um agente autônomo de programação deve receber uma credencial para uma tarefa definida, não uma credencial que simplesmente faça os erros desaparecerem. A dificuldade não está em encontrar um rótulo de escopo chamado `write`, mas em provar que o token consegue concluir uma tarefa e falha em ações próximas que não fazem parte dela.

Já vi equipes começarem com um token pessoal porque o agente precisava «apenas começar». Semanas depois, esse token consegue ler todos os repositórios que o desenvolvedor já acessou, editar configurações de implantação e fazer solicitações destrutivas que a tarefa original nunca exigiu. O agente não criou esse risco. O problema foi o limite de permissões definido de forma descuidada.

## Uma tarefa é mais específica que uma função

Uma tarefa de agente descreve um resultado e um conjunto limitado de mudanças de estado. Uma função descreve uma pessoa ou um serviço em termos amplos. Quando o acesso é concedido com base na função, quase sempre se concede mais do que a tarefa exige.

Considere uma solicitação como: «Atualizar uma dependência no serviço de pagamentos, executar a suíte de testes e abrir um pull request». O agente pode precisar ler um repositório, criar uma branch, enviar commits para essa branch e criar um pull request. Talvez precise de acesso de leitura aos logs de compilação se o serviço de testes os expuser por uma API. Ele não precisa administrar a organização, editar regras de proteção de branches, alternar credenciais de implantação nem fazer merge do próprio trabalho.

Escreva contratos de tarefa como verbos aplicados a recursos identificados. Não escreva «escrita no repositório». Descreva o que o agente pode fazer:

- Ler o código-fonte, as issues e os pull requests existentes em `payments-service`.
- Criar e atualizar branches cujos nomes começam com `agent/`.
- Criar um pull request dessa branch para a branch base definida.
- Ler o status e os logs do workflow iniciado por esse pull request.
- Publicar um comentário contendo o resultado dos testes.

Isso não é burocracia. A lista revela decisões que ainda faltam. O agente pode fechar uma issue? Pode editar o pull request de outra pessoa? Pode executar novamente um workflow caro? Precisa baixar um pacote de um registro privado? Cada verbo conquista uma permissão ou é removido.

Um contrato de tarefa também diferencia um efeito colateral necessário de um efeito conveniente. Um agente pode querer atualizar o rótulo de uma issue depois de abrir um pull request. Isso pode ser útil, mas não é necessário para atualizar a dependência. Deixe essa ação fora do primeiro conjunto de permissões. Adicione-a depois, somente quando alguém aceitar o efeito e testar o limite.

Trate tarefas recorrentes como tarefas separadas, mesmo quando um único processo de agente as executa. Uma verificação noturna de dependências, uma promoção de release e uma reversão em produção têm consequências diferentes. Uma identidade com um acúmulo de permissões torna as três tarefas mais difíceis de revisar e impossível de revogar de forma limpa.

## Os nomes dos escopos não são limites de permissão

Uma string de escopo é uma entrada para a autorização, não uma prova de que uma chamada de API é segura. Os provedores usam a palavra «escopo» para mecanismos diferentes: strings OAuth, permissões de repositório, funções de projeto, concessões de instalação e tokens limitados a uma lista de recursos. Eles não são intercambiáveis.

A RFC 6749 do OAuth 2.0 define escopo como um conjunto de strings separadas por espaços que limita o acesso de um token. Ela deixa deliberadamente o significado de cada string para o servidor de autorização. Essa flexibilidade é útil para os provedores, mas significa que `repo:write`, `projects.write` e `api` não dizem quase nada até que você examine a documentação dos endpoints do provedor e teste o token.

A RFC 8707 acrescenta indicadores de recurso. Um cliente pode solicitar um token para um recurso protegido específico, em vez de tratar todos os endpoints atrás de um servidor de autorização como um único destino. Isso ajuda quando o emissor oferece esse recurso. Porém, não corrige um provedor que mapeia um único escopo amplo para todos os projetos ou todos os endpoints destrutivos dentro desse recurso.

Mantenha estas três camadas separadas nas suas anotações de projeto:

| Camada | Pergunta respondida | Falha quando há confusão |
|---|---|---|
| Escopo do token | Quais rótulos de permissão o emissor colocou neste token? | Você presume que um rótulo amigável representa uma ação específica. |
| Concessão de recurso | Quais repositórios, projetos, contas ou ambientes essa identidade pode alcançar? | O token pode atuar sobre um recurso vizinho. |
| Regra do endpoint | Qual método e caminho a API aceitará nesta solicitação? | Uma concessão de escrita permite exclusão ou administração. |

A recomendação ruim mais comum é «use apenas leitura e escrita». Ela é popular porque cabe em um guia de configuração e costuma funcionar na primeira tentativa. Está errada porque a escrita frequentemente cobre vários verbos sem relação entre si. Criar um pull request, excluir um repositório, alterar um webhook e modificar o controle de acesso podem estar atrás da mesma concessão ampla.

Quando o provedor oferecer apenas um escopo amplo, não finja que resolveu o menor privilégio dando-lhe um nome cuidadoso. Restrinja a camada de recursos. Crie um repositório, projeto, ambiente ou conta de serviço dedicado, com acesso apenas ao destino. Se o agente precisar realizar uma ação em produção, dê-lhe uma identidade separada para essa ação e exija aprovação explícita. O modelo grosseiro do provedor continua grosseiro, mas a credencial alcançará menos recursos.

## Crie um inventário de endpoints antes de emitir um token

Um inventário de endpoints transforma uma solicitação vaga em um projeto de permissões que pode ser revisado. Ele registra cada chamada que o agente pode fazer, por que precisa dela, qual recurso pode tocar e qual permissão exata a habilita.

Comece pela sequência de ações, não pela página de permissões do provedor. Um agente que abre um pull request costuma precisar de mais chamadas do que as pessoas esperam: lê a revisão base, cria uma referência, cria ou atualiza arquivos, obtém o status do workflow e envia o pull request. Uma página de permissões raramente informa qual dessas chamadas é essencial para o workflow escolhido.

Use um inventário como este. Substitua os caminhos ilustrativos pelos caminhos documentados pelo seu provedor.

```yaml
task: update dependency and open pull request
resource: org/payments-service
calls:
  - method: GET
    path: /repos/org/payments-service/contents/package-lock.json
    purpose: read current dependency lockfile
    permission: contents:read

  - method: POST
    path: /repos/org/payments-service/git/refs
    constraint: "ref starts with refs/heads/agent/"
    purpose: create working branch
    permission: contents:write

  - method: PUT
    path: /repos/org/payments-service/contents/package-lock.json
    constraint: "branch starts with agent/"
    purpose: commit updated lockfile
    permission: contents:write

  - method: POST
    path: /repos/org/payments-service/pulls
    constraint: "base is main; head starts with agent/"
    purpose: request review
    permission: pull_requests:write

forbidden_calls:
  - DELETE /repos/org/payments-service
  - PATCH /repos/org/payments-service/branches/main/protection
  - POST /repos/org/organization-hooks
  - GET /repos/org/another-service/contents/secrets.yml
```

O campo `constraint` importa porque as permissões de endpoints frequentemente ficam aquém das permissões da tarefa. Uma API pode permitir a criação de branches, mas não oferecer uma restrição nativa ao prefixo `agent/`. Registre essa lacuna. Talvez você precise de um serviço intermediário de ações, de um repositório separado ou de uma etapa de revisão, pois um escopo não consegue aplicar a regra de branch desejada.

Não dependa de uma instrução do agente para manter as restrições. Um prompt pode descrever o prefixo pretendido para a branch, mas não consegue rejeitar uma solicitação enviada para `main`. O ponto de aplicação deve ser o provedor da API, as configurações do recurso de destino ou um gateway de ações que verifique a solicitação antes de enviá-la.

O inventário deve incluir chamadas de leitura com a mesma seriedade das chamadas de escrita. Ler um segredo de implantação, uma exportação de clientes, um aviso de segurança ou um segundo repositório pode expor mais do que um commit incorreto. A maioria das revisões de permissões concentra toda a atenção nas escritas porque elas são visíveis. A janela de contexto do agente também torna as leituras amplas perigosas.

## Separe o acesso para descoberta do acesso para alteração

O acesso para descoberta e o acesso para alteração normalmente devem usar credenciais diferentes, porque um agente precisa de contexto amplo com mais frequência do que precisa de autoridade ampla para mudar o estado.

Um agente de planejamento pode precisar pesquisar código, inspecionar issues, examinar resultados de compilação e comparar versões em vários repositórios. Um agente de aplicação de patches pode precisar apenas escrever em uma branch de um único repositório. Se os dois trabalhos compartilharem um token, o agente de aplicação herdará a ampla superfície de leitura do planejador, enquanto o planejador herdará uma capacidade de escrita de que nunca precisa.

Divida o trabalho em etapas quando o provedor permitir. A etapa de descoberta produz um plano limitado ou uma proposta de patch. Um segundo processo recebe esse artefato e uma credencial mais específica para fazer a alteração solicitada. Uma pessoa pode revisar a transferência quando a mudança afetar uma área protegida.

Essa separação captura uma falha prática que prompts não conseguem corrigir. Imagine que um planejador pesquise na organização referências a um pacote e encontre um repositório interno antigo com anotações de implantação. Se o mesmo token puder fazer push para todos os resultados lidos, uma chamada de ferramenta equivocada mais tarde poderá alterar o repositório errado. O modelo pode entender perfeitamente a tarefa e ainda escolher o identificador errado. Restringir o escritor ao repositório pretendido transforma esse erro em uma solicitação negada.

Não divida tokens apenas para criar mais tokens. Divida-os quando o conjunto de recursos ou os verbos permitidos forem diferentes. Um único token de leitura pode apoiar uma investigação coerente. Um único token de escrita pode apoiar edições estreitamente relacionadas dentro de um destino. O objetivo é que a resposta à pergunta «o que este processo pode fazer?» seja curta o bastante para que uma pessoa de engenharia a verifique sem precisar adivinhar.

No controle de código-fonte, separe a autoridade para escrever em branches da autoridade para fazer merge sempre que o provedor permitir. Uma branch é uma mudança proposta. Um merge altera a base compartilhada e frequentemente inicia implantações, releases ou automações posteriores. O agente pode abrir um pull request útil sem receber permissão para fazer merge.

## Restrinja o recurso antes de aperfeiçoar o escopo

Um escopo específico ligado a uma credencial que alcança toda a organização pode ser pior do que um escopo amplo ligado a um destino descartável e isolado. O escopo controla os verbos. Os limites de recurso controlam onde esses verbos atuam. Você precisa dos dois, mas os limites de recurso geralmente tornam os erros suportáveis.

Dê aos agentes autônomos identidades de serviço em vez de tokens pessoais. Tokens de acesso pessoais tendem a herdar associações antigas de uma pessoa, concessões temporárias de administrador e acesso a projetos que ninguém lembrou durante a configuração. Revogar um deles mais tarde também pode interromper trabalhos sem relação, fazendo com que as equipes adiem a revogação. É assim que exceções temporárias se tornam acesso permanente.

Uma identidade dedicada deve começar sem acesso e receber apenas as concessões de recursos listadas no inventário de endpoints. Se o agente trabalha em um repositório, conceda acesso a esse repositório, não à organização inteira. Se atualiza uma implantação de staging, conceda acesso ao ambiente de staging, não a todos os ambientes. Se grava registros de uma conta de cliente, conceda acesso a essa conta, não a uma credencial de API global.

Use destinos separados que não sejam de produção para testar permissões. Testar um token fazendo escritas reais em produção mostra se ele funciona, mas não prova que está adequadamente restrito. Um repositório ou projeto de teste permite exercitar criação, atualização, falha, revogação e auditoria sem deixar trabalho de limpeza em um sistema ativo.

O isolamento de recursos também compensa APIs com modelos de escopo inadequados. Alguns serviços emitem um token que tem um único escopo `api` e nenhuma granularidade por endpoint. Ainda é possível criar um projeto dedicado contendo apenas os recursos que o agente pode operar, negar a ele a administração da organização e usar uma identidade distinta para cada ambiente. Isso é menos elegante do que uma API detalhada, mas é muito melhor do que entregar um token para todos os fins a um processo que constrói solicitações dinamicamente.

Não dê a um agente acesso à produção apenas porque o código que ele altera chegará à produção mais tarde. O sistema de release deve controlar essa transição por um caminho aprovado e autorizado separadamente. Se a tarefa realmente incluir uma operação em produção, escreva um contrato separado para ela. O contrato deve nomear o ambiente de destino, o método permitido, os parâmetros aceitáveis, o comportamento de reversão e a pessoa que aprova a ação.

## Teste o sucesso e a negação como um único contrato

Um conjunto de permissões está incompleto até que você demonstre duas coisas: o agente consegue terminar o trabalho atribuído e as ações próximas, mas não atribuídas, falham. Testar apenas o caminho feliz prova conveniência. Não diz nada sobre contenção.

Use uma identidade de teste limpa para cada mudança de permissão. Credenciais existentes frequentemente têm concessões armazenadas, funções herdadas ou um segundo caminho de autenticação que faz um teste parecer bem-sucedido pelo motivo errado. Registre o assunto do token, os recursos pretendidos, os escopos emitidos e a validade antes da execução.

Uma sequência prática de teste é esta:

1. Crie um recurso de destino descartável e uma credencial com as concessões propostas.
2. Execute o agente ou um conjunto determinístico de solicitações em todas as chamadas permitidas pelo inventário.
3. Verifique o estado esperado, como uma branch, um pull request, um comentário ou um registro atualizado.
4. Envie cada chamada proibida usando a mesma credencial e espere uma negação.
5. Remova a credencial ou revogue a sessão, depois repita uma chamada antes permitida e espere uma negação.

Use solicitações diretas junto com uma execução do agente. Solicitações diretas eliminam a incerteza da seleção de ferramentas e mostram se o próprio provedor aplica o limite. Este fixture de shell ilustra o formato do teste. Ele pressupõe uma API que retorna JSON e usa `403` para uma identidade autenticada que não tem permissão.

```sh
base="https://api.example.internal"
auth="Authorization: Bearer $AGENT_TOKEN"

curl -sS -o allowed.json -w "%{http_code}\n" \
  -H "$auth" \
  -X POST "$base/repos/acme/payments-service/pulls" \
  -H "Content-Type: application/json" \
  -d '{"head":"agent/dependency-bump","base":"main","title":"Update parser"}'
# Expected output: 201

curl -sS -o denied.json -w "%{http_code}\n" \
  -H "$auth" \
  -X DELETE "$base/repos/acme/payments-service"
# Expected output: 403

cat denied.json
# Expected shape: {"message":"Resource not accessible by integration"}
```

Não verifique apenas o código de status. Inspecione o estado resultante das operações permitidas. Algumas APIs aceitam uma solicitação e a processam de forma assíncrona, ou retornam sucesso ignorando um campo do qual o agente dependia. Para negações, diferencie `401` de `403`. Um `401` pode significar que a credencial de teste estava malformada ou expirada. Um `403` depois de uma autenticação bem-sucedida demonstra melhor que a autorização bloqueou a chamada. Os provedores variam, portanto documente a semântica deles no fixture.

Mantenha um teste negativo para cada limite de permissão perigoso. Se um agente pode criar uma implantação, teste se ele não consegue promovê-la. Se pode comentar em uma issue, teste se não consegue editar rótulos ou responsáveis. Se pode gravar o valor de um segredo de staging, teste se não consegue lê-lo de volta, caso a API permita escrever sem ler. Esses testes impedem que uma alteração posterior de escopo amplie o acesso silenciosamente.

## Um 403 malsucedido deve mudar a tarefa ou a concessão

Uma resposta `403 Forbidden` traz evidências sobre o contrato. Ela deve desencadear uma decisão, não um pedido automático pela permissão mais ampla do provedor.

Já vi este padrão de falha muitas vezes. Um agente cria uma branch e faz commit de uma correção, mas recebe uma negação ao tentar abrir um pull request. Alguém descobre que a permissão de pull requests do provedor também permite dispensar revisões ou editar discussões de forma mais ampla. A permissão é concedida porque o agente precisa terminar. Alguns dias depois, o mesmo agente começa a «limpar» pull requests antigos e edita trabalhos fora da sua atribuição.

A primeira negação continha uma pergunta de projeto: abrir um pull request exige essa capacidade mais ampla e a equipe aceita os efeitos colaterais? Há várias respostas honestas:

- Conceder a permissão depois de testar toda a superfície de endpoints e registrar o risco aceito.
- Alterar a tarefa para que o agente prepare uma branch e uma pessoa abra o pull request.
- Usar outra identidade do provedor ou outro recurso em que a concessão ampla alcance apenas o repositório pretendido.
- Colocar um serviço de ações específico diante da API do provedor, aceitando apenas uma solicitação de criação de pull request com restrições fixas de recurso e branch.

A resposta errada é adicionar todos os escopos que transformam respostas vermelhas em verdes. Isso converte erros de autorização em incidentes adiados.

Os corpos das solicitações também merecem atenção. Muitos modelos de permissão de API autorizam um endpoint, mas não distinguem valores seguros de valores prejudiciais. `POST /deployments` pode aceitar `staging` e `production` com a mesma permissão. `PATCH /projects/{id}` pode permitir uma atualização inofensiva de descrição e uma alteração perigosa de visibilidade. Se o provedor não consegue separar essas operações, o limite deve ficar acima do endpoint. Exija aprovação humana, use um destino dedicado ou exponha uma operação criada para esse fim em vez do acesso à API bruta.

Registre no inventário a chamada negada e o motivo pelo qual você a adicionou ou rejeitou. Daqui a seis meses, esse registro explicará por que o agente pode criar uma branch, mas não renomear um repositório. Sem ele, alguém considerará o limite arbitrário e o ampliará durante uma correção apressada.

## Etapas de aprovação capturam as chamadas que ainda têm grandes consequências

Permissões específicas no provedor reduzem o que um agente pode tentar. Etapas de aprovação ajudam com ações permitidas que ainda merecem uma decisão humana, como uma operação de pagamento externo, um comando SSH em um host importante ou uma escrita em um serviço de produção.

Não use a aprovação como desculpa para dar credenciais amplas ao agente. Uma confirmação de um clique pode interromper uma solicitação obviamente ruim, mas as pessoas aprovam cartões repetitivos rapidamente, sobretudo quando um agente precisa de várias chamadas rotineiras para terminar um trabalho. O limite de permissões deve rejeitar categorias inteiras de ações antes que qualquer cartão de aprovação apareça.

Use a aprovação quando o contexto humano mudar a decisão. Uma implantação pode estar tecnicamente autorizada, mas ser inadequada durante um incidente. Uma solicitação para excluir uma branch pode ser permitida, mas estar errada se outra pessoa estiver usando-a. Um prompt de aprovação pode mostrar o destino real e a ação solicitada no momento em que a pessoa pode avaliá-los.

O Sallyport mantém credenciais de API e SSH em seu cofre criptografado do macOS e executa a ação solicitada sem expor o segredo ao agente. A autorização de sessão e os controles de aprovação por credencial podem colocar uma pessoa no caminho de chamadas que merecem esse controle, mas o desenho dos escopos no provedor ainda determina o que uma credencial aprovada pode alcançar.

Mantenha registros de auditoria que respondam a duas perguntas distintas: qual processo de agente recebeu permissão para agir e quais chamadas individuais de API ele fez. Esses são registros diferentes. A aprovação de um processo prova que uma pessoa permitiu que aquela execução usasse uma credencial; ela não explica se a execução criou um pull request, alterou uma variável de ambiente ou tentou excluir algo sem sucesso. Revise os dois registros depois de uma mudança de permissão e depois de um incidente.

## As revisões de escopo precisam de um gatilho, não de uma promessa no calendário

As revisões de permissões funcionam quando um evento de engenharia as desencadeia. Um lembrete trimestral vago tende a encontrar tokens antigos depois que ninguém mais lembra sua finalidade. Vincule a revisão a mudanças de tarefa, novos endpoints, expansão de recursos, mudanças nas permissões do provedor e alterações no workflow do agente.

Mantenha o inventário de endpoints junto do código que invoca o agente. Quando um pull request alterar as instruções de ferramentas do agente ou adicionar uma chamada de API, exija uma atualização do inventário e dos testes positivos e negativos. Isso coloca a decisão de permissão ao lado do comportamento que precisa dela.

Revise a revogação antes de precisar dela. Remova uma credencial de teste e confirme que uma solicitação antes permitida falha. Desative a identidade de serviço e confirme que um agente em execução não consegue continuar por meio de uma sessão armazenada. Verifique se o provedor emitiu tokens de atualização ou credenciais duplicadas que mantêm o mesmo acesso ativo. As equipes costumam descobrir esses caminhos durante um incidente, quando a resposta é menos útil.

Fique atento ao crescimento de permissões em pequenas mudanças. Uma solicitação para ler logs de workflows pode virar permissão para executá-los novamente. Uma solicitação para atualizar uma issue pode virar administração de issues em toda a organização. Uma solicitação para acessar um ambiente pode virar um fallback de produção «por precaução». Cada chamada adicionada deve passar pela mesma pergunta: o agente consegue concluir a tarefa declarada sem ela?

Se a resposta for não, adicione a menor concessão que habilite a chamada e acrescente um teste de negação ao redor do vizinho prejudicial mais próximo. Se a resposta for sim, deixe-a de fora. Essa disciplina torna as falhas do agente mais visíveis no curto prazo. Também impede que uma instrução malformada, um modelo confuso ou um processo comprometido herde uma autoridade que ninguém pretendia conceder.
