# Permissões de infraestrutura para agentes de IA em aplicações seguras

Agentes de IA não devem receber uma permissão permanente que signifique «aplicar alterações de infraestrutura». Eles devem receber uma autorização restrita e com validade limitada para aplicar uma alteração revisada a uma única conta de destino confirmada, com um procedimento de recuperação que um operador tenha lido e aceitado.

Já vi equipes confundirem um plano do Terraform com um controle de segurança e um botão de aprovação com uma decisão. Nenhum dos dois basta sozinho. Um plano pode ser gerado novamente contra outra conta. Uma aprovação pode continuar válida depois que o commit mudou. Uma nota de rollback pode dizer «reverter» quando a alteração destrói dados ou modifica uma dependência que já não existe.

O limite útil exige mais: o agente prepara as evidências, uma pessoa revisa essas evidências e o caminho de execução se recusa a prosseguir se elas já não descrevem a ação. Isso parece excesso de cuidado até a primeira vez que um assistente herda o perfil de nuvem errado, lê um snapshot de estado obsoleto e direciona um comando perfeitamente válido para a produção.

## A permissão deve estar vinculada a uma ação, não a um cargo

As permissões de infraestrutura para agentes de IA devem autorizar uma alteração concreta, não uma categoria como «implantar», «Terraform» ou «operações de produção». Categorias amplas parecem convenientes porque as pessoas pensam em funções. As APIs de nuvem, porém, executam solicitações, e as solicitações têm destinos, parâmetros, identidades e consequências.

Uma autorização de aplicação útil deve vincular pelo menos estes fatos:

- A revisão imutável da origem e o diretório de configuração usados para criar o plano.
- O artefato de plano revisado ou seu resumo SHA-256.
- A conta de nuvem ou a identidade do tenant de destino informada pela credencial de execução.
- A identidade de execução, função, assinatura, projeto e região permitida, quando aplicável.
- Um prazo de validade e uma referência de recuperação que informem ao operador o que acontece se a aplicação precisar ser interrompida ou revertida.

A diferença entre ter permissão para *calcular* uma alteração e ter permissão para *fazê-la* é importante. Permita que o agente inspecione repositórios, chame APIs somente de leitura, execute validações e proponha um plano. Não trate essas atividades silenciosamente como prova de que ele pode alterar a produção. O acesso de descoberta tende a expor detalhes operacionais. O acesso de alteração modifica a conta, a disponibilidade e, às vezes, as evidências disponíveis depois de um incidente.

Uma função chamada `InfrastructureDeployer` não é um objeto de aprovação. É um detalhe de implementação. Se ela puder aplicar qualquer coisa em todas as contas sempre que um processo a obtiver, seu processo de aprovação dependerá de as pessoas se lembrarem de usá-la corretamente. Os agentes são rápidos o bastante para transformar esse teste de memória em um incidente.

## Um plano revisado precisa ser exatamente o artefato aplicado

Um plano revisado só tem valor se o comando de aplicação consumir esse mesmo plano. Executar `terraform plan` novamente depois que alguém aprova a saída cria um novo artefato, mesmo quando os arquivos parecem inalterados.

A documentação de comandos do Terraform deixa essa diferença clara. `terraform plan -out=FILE` grava um arquivo de plano destinado a `terraform apply FILE`; `terraform apply` sem um plano salvo cria um novo plano antes de pedir confirmação. A segunda forma é adequada para uma sessão humana interativa. Ela é errada para um fluxo de agente que afirma ter recebido revisão humana das alterações propostas.

Use um plano salvo e gere sua representação JSON para revisão. Uma sequência mínima de shell se parece com esta:

```sh
set -euo pipefail

git rev-parse HEAD > evidence/source-revision.txt
terraform init -lockfile=readonly
terraform plan -out=evidence/change.tfplan
terraform show -json evidence/change.tfplan > evidence/change.json
shasum -a 256 evidence/change.tfplan > evidence/change.tfplan.sha256
terraform providers lock -platform=darwin_arm64
```

A saída do resumo tem um formato simples:

```text
f1f5f2...a94c  evidence/change.tfplan
```

O registro de aprovação deve copiar o resumo completo, não apenas anexar uma captura de tela do terminal. O runner de aplicação então o verifica antes da execução:

```sh
shasum -a 256 -c evidence/change.tfplan.sha256
terraform apply -input=false evidence/change.tfplan
```

Isso evita uma falha comum: o agente abre um pull request, produz um plano, recebe um comentário de aprovação, busca a versão mais recente da branch main e executa um plano novo. Um colega pode ter integrado uma alteração diferente entre essas ações. O plano posterior pode adicionar uma exclusão, trocar a versão de uma imagem ou apontar para outro alias de provedor. O revisor aprovou o grafo proposto no dia anterior, não aquilo que o runner encontra agora.

Um plano binário do Terraform pode conter valores sensíveis. Não o cole em tickets ou chats. A representação JSON também pode revelar material sensível, dependendo dos esquemas e valores dos provedores, portanto faça a redação apenas por meio de um processo de revisão que você conheça. A redação não deve remover endereços de recursos, ações, identidade de destino ou alterações de dependências. Esses são justamente os fatos de que o aprovador precisa.

O padrão de plano salvo é mais forte quando o ambiente de execução também está fixado. Use o mesmo arquivo de lock dos provedores, a mesma versão do Terraform, as mesmas variáveis, a mesma configuração de backend e a mesma seleção de workspace que criaram o plano. Se qualquer uma dessas entradas mudar, descarte o plano e gere um novo pacote para revisão. Tentar aproveitar uma aprovação antiga é como transformar um controle sensato em encenação.

## O destino nomeado deve vir da credencial, não de um rótulo

Um destino chamado `prod` prova quase nada. Os repositórios copiam nomes de diretórios. Os workspaces sofrem alterações. Variáveis de ambiente permanecem nos shells. Um agente pode seguir fielmente uma configuração chamada produção enquanto está autenticado em uma conta de sandbox ou, pior, em uma conta de produção selecionada por um perfil herdado.

Exija que a identidade de execução pergunte ao plano de controle da nuvem quem ela é antes do planejamento e novamente imediatamente antes da aplicação. Armazene o resultado no pacote de evidências e compare-o com o destino aprovado.

Para uma ação baseada em AWS, uma verificação pode ser tão simples quanto esta:

```sh
aws sts get-caller-identity --output json > evidence/caller-identity.json
cat evidence/caller-identity.json
```

O resultado identifica a conta e o principal:

```json
{
  "UserId": "AROAXXXXX:apply-run",
  "Account": "123456789012",
  "Arn": "arn:aws:sts::123456789012:assumed-role/InfraApply/apply-run"
}
```

No Google Cloud, registre separadamente a conta ativa e o projeto. No Azure, registre o ID da assinatura e o ID do tenant no contexto da credencial. Não dependa do nome de exibição da conta de nuvem, pois as pessoas podem duplicar esses nomes. Identificadores numéricos ou globalmente exclusivos são menos agradáveis de ler durante a revisão, mas muito mais seguros na execução.

A verificação pré-aplicação deve usar o mesmo caminho de credencial da aplicação. Isso parece óbvio, mas wrappers frequentemente violam essa regra. Um script de planejamento pode usar uma função assumida de curta duração, enquanto um comando posterior herda o perfil padrão de um desenvolvedor. Um agente que chama um runner remoto pode planejar localmente, mas aplicar remotamente com uma identidade de serviço que nunca inspecionou.

Inclua uma asserção de destino verificável por máquina no runner. Este exemplo recusa uma conta AWS inesperada:

```sh
expected_account="123456789012"
actual_account="$(aws sts get-caller-identity --query Account --output text)"

if [ "$actual_account" != "$expected_account" ]; then
  printf 'refusing apply: expected account %s, got %s\n' \
    "$expected_account" "$actual_account" >&2
  exit 1
fi
```

Essa verificação não substitui a revisão humana. Ela captura uma classe inteira de erros antes que qualquer chamada de API altere a infraestrutura. Combine-a com uma configuração do provedor que declare a conta ou assinatura permitida, quando o provedor oferecer esse tipo de proteção. Uma asserção no provedor e outra no runner falham de forma independente, exatamente como você quer.

## O desvio de estado torna as aprovações antigas inseguras

Um plano descreve a alteração desejada em relação a um determinado estado observado. Ele não promete que esse estado ainda existirá uma hora depois.

Outro engenheiro pode fazer uma implantação. Um autoscaler pode adicionar ou remover recursos. Um serviço de nuvem pode alternar uma conexão, substituir um nó ou concluir uma operação assíncrona. O Terraform frequentemente detecta parte disso ao atualizar o estado, mas a resposta segura a uma diferença relevante não é prosseguir porque o plano parecia pequeno antes. Gere um novo artefato e revise o novo diff.

A expiração resolve boa parte do problema. Faça uma aprovação curta o bastante para que uma pessoa ainda se lembre por que a aceitou. A duração certa varia conforme o processo de lançamento, mas deve cobrir uma janela de execução definida, não um dia inteiro por padrão. Quando a janela fechar, force um novo plano, repita a verificação do destino e exija uma nova aprovação.

Você também precisa de uma regra de invalidação. Rejeite um plano quando qualquer uma destas alterações ocorrer depois da revisão:

- A revisão de origem, o conjunto de variáveis, a referência do módulo ou o arquivo de lock do provedor mudar.
- O workspace, backend, conta, assinatura, tenant, projeto ou região diferir das evidências aprovadas.
- O resumo do plano não corresponder ao registro de aprovação.
- Um lock de estado, atualização ou pré-condição relevante informar um conflito que altere a ação proposta.

Não use «não houve alterações no pull request» como substituto dessa regra. Fontes de dados externas, padrões do provedor, estado atual e credenciais ficam fora do diff. O trabalho de infraestrutura tem entradas demais para que uma aprovação baseada apenas na origem carregue toda a decisão.

Algumas equipes tentam resolver o desvio permitindo que o agente gere planos novamente de forma automática até que o plano fique limpo. A recomendação é popular porque reduz o tempo de espera. Ela está errada para contas de consequência elevada. Gerar planos novamente sem revisão pode transformar uma atualização revisada em uma substituição não revisada. Se quiser, permita uma nova geração automática para uma prévia somente de leitura, mas exija nova revisão humana antes de qualquer alteração.

## O rollback deve descrever um estado recuperável

Um caminho de rollback claro explica como os operadores retornarão o serviço a uma condição aceitável, quem pode fazer isso, quais dados estão em risco e quando devem parar. «Execute terraform destroy» e «reverta o commit» raramente atendem a esse padrão.

As alterações de infraestrutura pertencem a classes de recuperação diferentes. Tratá-las da mesma forma cria uma falsa sensação de segurança.

Uma alteração de configuração reversível, como uma regra de security group ou um peso de load balancer, pode permitir uma aplicação inversa direta a partir de uma revisão conhecida e estável. A substituição de um grupo de instâncias pode exigir verificações de capacidade antes da reversão. Uma migração de banco de dados pode se tornar irreversível depois de gravar dados, então o caminho de recuperação pode ser uma migração posterior, uma restauração a partir de um backup verificado ou um recurso que interrompa novas gravações.

Escreva o caminho de rollback em linguagem operacional. Um registro útil responde a estas perguntas:

1. Qual condição observável indica que devemos fazer rollback, como verificações de saúde com falha, aumento da taxa de erros ou falha em um smoke test?
2. Qual revisão, conjunto de parâmetros ou comando exato retorna o serviço à configuração conhecida e estável?
3. Qual pré-requisito deve existir antes, como um ponto de restauração de backup, capacidade sobressalente ou janela de manutenção aprovada?
4. Quem tem autoridade para agir se a sessão do agente terminou ou o aprovador original não estiver disponível?
5. O que não pode ser restaurado automaticamente, incluindo registros, segredos, endereços públicos ou alterações manuais na nuvem?

Um caminho de recuperação precisa ser testado antes do incidente, não receber uma frase otimista durante o incidente. Se a equipe chama uma alteração de reversível, execute a reversão em um ambiente representativo e registre as condições que fizeram tudo funcionar. Os provedores podem manter o nome de um recurso excluído, as cotas podem impedir a recriação e os serviços dependentes podem armazenar em cache um endpoint antigo. Esses detalhes aparecem quando a alteração já está sob pressão.

Para alterações destrutivas, exija uma decisão separada. Excluir um recurso depois de uma revisão do plano não é moralmente equivalente a atualizá-lo. O agente deve mostrar os endereços excluídos, as ações de substituição, as configurações de retenção e as evidências de backup em um formato que não desapareça entre centenas de atualizações inofensivas. Se a alteração incluir um banco de dados, armazenamento de objetos, vínculo de identidade, limite de rede ou zona DNS, exija que o responsável pela recuperação leia o plano.

## O runner de aplicação deve recusar ambiguidades

O runner que executa a alteração precisa impor os próprios fatos da aprovação. Um bot que pode receber uma mensagem de chat dizendo «pode prosseguir» não tem uma forma confiável de distinguir um plano confirmado de uma instrução casual.

Use um registro de aprovação estruturado. Ele pode ficar em um sistema de implantação assinado, em um registro de repositório protegido ou em outro armazenamento controlado. A escolha do armazenamento importa menos que os campos e a verificação. Este JSON ilustrativo mostra o formato:

```json
{
  "change_id": "infra-2025-041",
  "source_revision": "4ad7d2f",
  "plan_sha256": "f1f5f2...a94c",
  "target": {
    "cloud": "aws",
    "account_id": "123456789012",
    "region": "us-east-1",
    "workspace": "production"
  },
  "approved_by": "operator-id",
  "expires_at": "2025-04-18T15:30:00Z",
  "rollback_ref": "runbook: payments-api capacity revert"
}
```

O agente pode montar essa solicitação, mas não deve escrever `approved_by` nem estender `expires_at`. O serviço de aprovação deve adicionar esses fatos depois que uma pessoa visualizar a alteração renderizada. O runner de aplicação lê o registro, recalcula o resumo do plano, verifica a revisão de origem e a identidade de destino e então marca a autorização como consumida antes de enviar a primeira solicitação de gravação.

Consumir uma aprovação é importante. Sem isso, um agente pode tentar novamente uma ação aprovada mais tarde, depois que o ambiente mudou. Uma aplicação com falha também precisa de um status explícito. Não a marque como concluída simplesmente porque o runner emitiu um comando. Registre se o Terraform retornou sucesso, se uma operação da API de nuvem continua pendente e se um operador aceitou o estado resultante.

Mantenha estreita a superfície de escrita do agente. Ele pode precisar de chamadas HTTP para APIs de implantação ou acesso SSH a um runner controlado, mas nunca deve receber em seu contexto um segredo de nuvem reutilizável. O Sallyport mantém as credenciais de API e SSH em seu cofre criptografado enquanto executa a ação solicitada e devolve o resultado ao agente. Essa configuração ajuda a impedir a cópia de credenciais, mas não torna segura uma solicitação vaga de aplicação.

## A aprovação por chamada deve ficar ao redor do limite perigoso

A aprovação por chamada tem seu lugar no trabalho de infraestrutura, mas não substitui a revisão do artefato. Se um agente pedir permissão para cada chamada de API da nuvem, os operadores aprovarão uma longa sequência sem compreender o resultado agregado. Isso é fadiga de aprovação e ensina as pessoas a clicar na única proteção que possuem.

Coloque a intervenção humana onde ela decide algo significativo: aprovar um plano vinculado a um destino e depois permitir a execução delimitada da aplicação. Reserve confirmações individuais para ações com impacto incomum, como rotação de segredos, exclusão de um objeto protegido, acesso de emergência ou comando fora do contrato esperado do runner.

A autorização por sessão do Sallyport pode estabelecer que um processo específico de agente pode usar um canal de ação durante sua execução atual, enquanto chaves por chamada podem exigir uma confirmação separada para credenciais sensíveis. Esse é um limite de credenciais limpo. Seu fluxo de implantação ainda precisa definir qual chamada conta como uma aplicação aprovada e quais credenciais merecem a fricção de uma aprovação por chamada.

Uma pessoa deve ver evidências suficientes para decidir sem ler o tráfego bruto do provedor. Mostre endereços de recursos agrupados por ação, substituições e exclusões separadamente, identidade de destino, revisão de origem, resumo, validade e referência de rollback. Depois, ofereça acesso ao plano completo para quem precisar dele. Esconder uma alteração destrutiva entre cem atualizações é uma falha de apresentação, não uma falha do operador.

## Uma aplicação com falha exige uma decisão diferente de uma aplicação bem-sucedida

O Terraform pode retornar uma falha depois de alterar vários recursos. Os planos de controle da nuvem também podem aceitar uma solicitação e concluí-la mais tarde. Tratar qualquer status de saída diferente de zero como «nada aconteceu» é um dos hábitos mais perigosos em operações automatizadas.

Quando uma aplicação falhar, congele as novas tentativas automáticas. Capture a saída do runner, as informações do lock de estado, a identidade de destino e o subconjunto de recursos concluídos. Depois, inspecione o ambiente real antes de escolher uma resposta. Uma nova tentativa às cegas pode agravar uma falha parcial, enquanto um rollback imediato pode remover um recurso intermediário que o provedor ainda está criando.

Use esta sequência de decisão:

1. Confirme a identidade atual na nuvem e colete o status real de cada recurso citado na operação com falha.
2. Determine se é seguro concluir o estado desejado, revertê-lo ou se é necessário um plano de reparo.
3. Gere um plano novo a partir do estado atual e peça a um operador que o revise como uma alteração nova.
4. Registre a decisão sobre o incidente junto à aprovação original, incluindo quaisquer ações manuais que o Terraform não consiga representar.

É aqui que os registros de auditoria mostram seu valor. Mantenha juntos a revisão de origem, o resumo do plano, a identidade do aprovador, as evidências do destino, a transcrição dos comandos, o estado resultante e a decisão posterior. Uma trilha de eventos com evidência de adulteração é melhor que capturas de tela espalhadas por conversas, porque os responsáveis pela resposta precisam estabelecer a sequência, não reconstruir a intenção de memória.

Não prometa que a automação desfará toda aplicação com falha. Algumas alterações exigem uma pessoa que entenda a dependência do serviço, a durabilidade dos dados e o impacto para os clientes. O agente pode reunir evidências rapidamente. Ele não deve inventar uma operação de recuperação porque o pipeline espera um resultado verde.

## Torne a primeira implantação em produção deliberadamente entediante

A primeira aplicação em produção mediada por um agente deve alterar algo pequeno, reversível e observável. Escolha um ajuste de configuração conhecido, com um procedimento de recuperação já testado, não uma migração, uma reformulação de rede ou uma rotação de segredos que envolva vários consumidores.

Execute o fluxo completo em condições normais: gere o pacote de evidências, verifique a conta exata, revise o plano renderizado, aprove o resumo, aplique o artefato salvo, inspecione o resultado e consuma a autorização. Depois, faça um exercício de falha controlada. Expire uma aprovação, altere a revisão de origem ou aponte o runner para uma conta não aprovada e confirme que ele se recusa a agir.

Esses testes de recusa importam mais que uma implantação bem-sucedida no caminho feliz. Qualquer ferramenta parece disciplinada quando a conta, o plano e o estado coincidem. O controle prova seu valor quando um operador apressado, um artefato obsoleto ou um agente confuso pede que ele faça a coisa errada e ele para.

Não amplie o modelo de permissões porque a primeira implantação parece lenta. Meça onde o tempo de revisão é gasto. Se as pessoas gastam tempo comparando identificadores de contas, melhore a apresentação das evidências. Se os planos contêm alterações não relacionadas demais, corrija a propriedade dos módulos ou os limites do estado. Se as notas de rollback são fracas, exija que as equipes de serviço as escrevam e testem. O acesso amplo e permanente não corrige um processo de lançamento incômodo; apenas esconde a fraqueza até que um agente a alcance.
