# Rotacione credenciais por trás de um gateway de ações com evidências

Substituir um token de API ou uma identidade SSH prestes a expirar deveria ser algo rotineiro. O problema começa quando cada agente, perfil do shell, segredo do repositório e ferramenta local mantém sua própria cópia. Nesse cenário, você não rotaciona uma credencial. Você procura um número desconhecido de cópias, torce para ter encontrado todas e interrompe o trabalho em lugares que ninguém pensou em testar.

Um gateway de ações muda esse trabalho. O gateway mantém a credencial, executa a chamada externa e devolve o resultado ao agente. A rotação passa a ter um único local que contém o segredo, uma troca controlada e evidências que distinguem a sessão do agente da identidade usada por ela. Essa separação é mais importante durante um incidente, quando as pessoas costumam confundir «este processo enviou a chamada» com «este processo possuía o token».

Já vi equipes considerarem uma rotação concluída porque um novo valor apareceu em um gerenciador de segredos. Depois, uma chave de implantação antiga continuava no arquivo `authorized_keys` de uma conta, ou uma variável de ambiente esquecida mantinha ativo um token de API expirado. A rotação só termina quando a substituta comprova o caminho de ação esperado e a identidade retirada já não consegue se autenticar.

## Rotação é mudança de identidade, não substituição de texto

Rotacionar uma credencial significa substituir uma identidade de autenticação por outra e comprovar que o acesso foi transferido como planejado. Colar um novo token em um campo é apenas uma das operações dessa mudança.

Mantenha quatro elementos distintos nas anotações e nas ferramentas:

- A identidade externa: um token de API, segredo de cliente, par de chaves SSH ou credencial de conta de serviço aceito por um provedor.
- O registro da credencial: a entrada criptografada que armazena a identidade e os detalhes de uso.
- O destino da autorização: a conta de API, o repositório, a conta de máquina, o host ou o endpoint de rede que aceita a credencial.
- A sessão do agente: o processo específico que solicitou uma ação.

As pessoas frequentemente misturam o primeiro e o quarto itens. Esse erro produz relatórios de incidentes ruins. Uma sessão de agente pode ter chamado um endpoint por meio de um gateway sem precisar ler o token bearer. Por outro lado, um token vazado pode ser usado por um processo que nunca aparece no diário do agente. São investigações diferentes, com medidas de contenção diferentes.

A mesma distinção vale para a expiração. Um provedor pode expirar um token em um horário determinado, enquanto o registro do gateway continua perfeitamente saudável como dado armazenado. O registro não expira por mágica. Você precisa substituir a identidade externa antes que o provedor a rejeite, validar a nova identidade e retirar a antiga.

A publicação especial 800-57, Parte 1, do NIST trata os períodos criptográficos como algo além de lembretes no calendário. A discussão relaciona o período à exposição, ao uso e ao risco de comprometimento. Esse é também o raciocínio certo para credenciais de API e SSH. Um token com amplo acesso de gravação, usado com frequência ou sem responsável claro merece uma vida planejada mais curta que uma identidade restrita para uma única tarefa de leitura. Não transforme isso em um ritual que troca textos toda sexta-feira enquanto mantém um escopo excessivo.

Uma declaração clara de rotação deve ser parecida com esta: «A sessão do agente de build usou o registro de credencial deploy-api-prod nesta chamada. O registro mudou do token do provedor terminado em 4K2 para o token terminado em P9M. O token antigo foi revogado depois que o novo registro concluiu a ação esperada». O token em si não deve aparecer.

## Coloque o segredo em um único lugar antes que a expiração force a decisão

Não é possível controlar a rotação enquanto as credenciais continuarem em prompts de agentes, arquivos de repositórios, variáveis do shell e configurações copiadas. Primeiro vem a consolidação, mesmo quando a data de expiração está próxima.

Comece com um inventário que acompanhe o uso, não apenas o armazenamento. Pergunte a cada equipe quais chamadas externas e destinos SSH um agente pode acessar. Para cada resposta, registre a conta do provedor ou da máquina, o tipo de credencial, o responsável, a ação pretendida, o escopo, o comportamento de expiração e se a credencial aparece em outro lugar. É nesse último campo que começa o trabalho desagradável.

Uma varredura do repositório encontra erros óbvios, mas não prova a ausência de cópias. Procure nomes de variáveis de ambiente, chaves de configuração, modelos de implantação, caminhos copiados de chaves privadas e documentação que instrua as pessoas a colar um token na configuração de um agente. Examine também as definições das ferramentas do agente. Se uma ferramenta aceita `token`, `api_key`, `authorization` ou o conteúdo bruto de uma chave privada como argumento, o agente ainda pode carregar segredos, mesmo que outro sistema mantenha uma cópia.

Para HTTP, o formato pretendido é simples: o agente fornece uma ação e os dados comuns da requisição, enquanto o gateway seleciona a credencial armazenada e injeta o material de autorização apenas ao enviar a chamada. Uma chamada de ferramenta pode conter conceitualmente isto:

```json
{
  "credential": "deploy-api-prod",
  "method": "POST",
  "url": "https://api.example.internal/releases",
  "headers": {"Content-Type": "application/json"},
  "body": {"revision": "a81c2f"}
}
```

Ela não pode conter um token bearer, nem mesmo sob um nome amigável. Devolver um cabeçalho de autorização no resultado da ferramenta é o mesmo erro no sentido inverso. Faça a remoção na fronteira da ação, não depois, em uma transcrição de chat.

Para SSH, o agente deve solicitar uma conexão por meio de um registro de credencial e de um destino nomeados. Ele não deve receber um bloco de chave privada, um arquivo temporário de chave privada nem instruções para procurar em `~/.ssh`. Uma chave privada no diretório de trabalho do agente sobrevive em caches, histórico do editor, arquivos compactados e, às vezes, em um commit. Já limpei arquivos suficientes desse tipo para considerar «temporário» uma palavra sem significado de segurança.

O Sallyport mantém chaves de API e SSH em um cofre criptografado dentro do app para macOS e executa ações HTTP e SSH sem expor o segredo ao agente. Isso oferece um único registro para alterar, mas não elimina a necessidade de encontrar e remover cópias antigas criadas antes da migração.

## Dê a cada credencial um responsável e uma finalidade

Uma credencial pode ter mais de um usuário legítimo, mas ainda precisa de um responsável único e de uma finalidade declarada. A responsabilidade compartilhada costuma ser um nome educado para «ninguém verifica a expiração, o escopo ou a retirada».

Nomeie os registros para que um operador identifique o limite de autorização sem ver o material secreto. `billing-write-prod` informa mais que `token-final-2`. `github-deploy-repo-a` informa mais que `automation-key`. Inclua o ambiente quando ele afetar o destino e evite colocar o nome de uma pessoa quando a credencial pertence a uma função de serviço. Pessoas saem; a finalidade do serviço deve continuar compreensível.

Não coloque destinos sem relação atrás de um único token compartilhado apenas para reduzir o número de registros. Esse atalho é popular porque uma única renovação parece fácil. Ele causa três problemas:

1. Você não consegue saber qual destino exigiu a rotação.
2. Um aumento de escopo para um uso amplia o acesso de todos os outros.
3. Revogar a identidade durante um incidente interrompe trabalhos sem relação.

Um registro pode atender a um conjunto estreitamente relacionado de ações contra uma conta de provedor quando o escopo e o responsável forem realmente os mesmos. Trate isso como uma decisão explícita, não como padrão. Se o publicador do build e o processo de exportação do suporte precisam de permissões diferentes, precisam de identidades diferentes, mesmo que chamem a mesma API.

O SSH exige a mesma disciplina. Uma chave SSH ligada a uma conta de implantação em um grupo de hosts não deve também servir para acessar bancos de dados de produção só porque ambos usam SSH. Sempre que possível, coloque as restrições no servidor: uma conta dedicada, um comando limitado, uma restrição de origem quando a rede permitir e um comentário claro na chave autorizada. O comentário não impõe o acesso, mas torna a chave antiga visível quando alguém revisa `authorized_keys` sob pressão.

O manual de `authorized_keys` do OpenSSH documenta opções como `command=`, `restrict` e `from=`. Essas opções só ajudam se você testar o caminho exato exigido pela automação. Já vi uma entrada `restrict` bem-intencionada interromper o encaminhamento de portas de que um processo de implantação dependia silenciosamente. É melhor descobrir esse problema durante uma rotação planejada que à meia-noite. Não adicione todas as restrições disponíveis sem critério; adicione as que correspondem à ação definida.

## Use uma janela de sobreposição com término programado

Mantenha as credenciais antiga e nova ativas juntas apenas pelo tempo necessário para validar a substituta e se recuperar de uma troca malsucedida. A sobreposição é um mecanismo de segurança, não um modo permanente de operação.

Alguns provedores permitem vários tokens de API ou várias credenciais de cliente ativas. Crie primeiro a substituta, registre um identificador seguro para manter e carregue-a no registro do gateway. Depois, faça uma ação inofensiva pelo mesmo caminho que o agente usará no trabalho normal. Um endpoint de leitura, a criação de um rascunho em um projeto de teste ou uma chamada que retorne a identidade do chamador pode funcionar, desde que a ação verifique o escopo exigido e a conta de destino.

Não dependa de um endpoint genérico de «token válido» se o agente normalmente publica versões ou altera tickets. Um token pode ser válido, mas não ter o escopo de gravação, apontar para uma conta de sandbox ou falhar porque o gateway injeta o tipo errado de cabeçalho. Teste o método, a família de URLs, a conta e o formato do payload reais com um objeto inofensivo.

Defina o horário de revogação da credencial antiga antes do teste. Se você não consegue indicar esse horário, não tem uma janela de sobreposição. Criou outra credencial permanente.

Uma sequência prática é:

1. Crie a nova credencial do provedor com o escopo necessário e uma política de expiração conhecida.
2. Atualize o único registro do gateway, mantendo a credencial anterior apenas durante a sobreposição declarada.
3. Execute uma ação restrita por uma sessão de agente autorizada ou por uma sessão de teste controlada por um operador.
4. Verifique o resultado no provedor e examine o diário de ações para confirmar a sessão e o destino esperados.
5. Revogue ou remova a credencial antiga e repita a ação restrita mais uma vez.

O teste final, depois da revogação, não é mera formalidade. Ele detecta o caso constrangedor em que o teste usou silenciosamente o token antigo porque uma variável de ambiente, uma configuração de proxy ou outro registro de credencial teve prioridade. Isso acontece com mais frequência do que as pessoas admitem.

Quando o provedor permite apenas uma credencial de API ativa, não existe uma sobreposição verdadeira. Agende uma janela de mudança, registre uma ação de referência antes da troca, substitua o segredo no gateway, execute o teste restrito imediatamente e mantenha um responsável pela conta disponível para emitir uma substituta caso o provedor a rejeite. Não «resolva» a falta de sobreposição colocando o novo token na configuração do agente antecipadamente.

## Valide o caminho que o agente realmente usa

Um teste de rotação precisa exercitar o gateway, a seleção da credencial, a construção da requisição, a autorização remota e o tratamento do resultado. Testar cada componente isoladamente deixa lacunas justamente onde os erros de credencial se escondem.

Para HTTP, faça uma requisição específica o bastante para que você consiga reconhecê-la nos registros do provedor. Use um token de idempotência quando a API oferecer esse recurso ou crie um objeto descartável claramente identificado. Confirme que o provedor informa a conta ou o principal pretendido. Depois, confira se o diário de ações contém uma chamada correspondente, com destino, resultado e referência à sessão, sem imprimir credenciais.

Um teste genérico no shell ajuda a isolar o comportamento do provedor, mas prova menos do que muita gente imagina:

```sh
curl -sS -D /tmp/headers.txt \\
  -H "Authorization: Bearer $NEW_TOKEN" \\
  https://api.example.internal/v1/whoami
```

O resultado esperado costuma ter status `200` em `/tmp/headers.txt` e um corpo que identifica a conta de serviço. Isso mostra que o provedor aceita o token. Não prova que o gateway injeta o mesmo cabeçalho, escolhe o registro correto ou impede que o agente veja `$NEW_TOKEN`. Use esse teste apenas sob controle de um operador e remova a variável do shell ao terminar. Nunca cole um token real em um ticket ou em uma gravação de terminal salva.

Para SSH, teste o mesmo hostname, usuário e formato de comando exigidos pela automação. A verificação de chave pública abaixo ajuda a diagnosticar a autorização no servidor sem revelar material privado na saída:

```sh
ssh -o BatchMode=yes -o IdentitiesOnly=yes \\
  deploy@host.example.internal 'id \u0026\u0026 test -w /srv/releases \u0026\u0026 echo write-ok'
```

`BatchMode=yes` faz a autenticação falhar em vez de esperar uma senha interativa. `IdentitiesOnly=yes` impede que o cliente SSH tente todas as chaves sem relação carregadas em um agente. Não trate um login bem-sucedido em `ssh deploy@host` como prova de que uma ação de implantação funciona. A conta remota pode aceitar um shell e rejeitar o comando, o diretório ou a restrição de comando forçado usada pelo processo.

O manual de `ssh` do OpenSSH explica que `IdentitiesOnly` limita as identidades oferecidas pelo cliente. Essa opção captura um resultado positivo enganoso comum em máquinas de desenvolvedores: o agente local consegue autenticar com uma chave pessoal, enquanto a nova chave de automação falharia em produção. Em um desenho com gateway, faça a verificação equivalente pelo caminho SSH do gateway, onde a chave selecionada é inequívoca.

Teste também as falhas. Tente deliberadamente uma requisição com método não autorizado ou um comando SSH fora das permissões previstas para a conta. Você quer uma negação clara no sistema remoto e uma entrada correta no diário. Se uma credencial supostamente restrita funcionar em uma ação sem relação, interrompa a rotação e reduza o escopo antes de retirar a identidade antiga.

## A rotação de SSH falha no servidor quando as chaves públicas antigas permanecem

Substituir uma chave privada SSH no cofre não revoga a chave antiga. O servidor continua aceitando a identidade antiga até que sua chave pública seja removida de todas as fontes de autorização que confiam nela.

O inventário de SSH é mais difícil porque as chaves públicas podem aparecer em vários lugares: `~/.ssh/authorized_keys`, um serviço de gerenciamento de identidades, uma configuração de metadados de uma instância na nuvem, um modelo de gerenciamento de configuração ou a interface de chaves de implantação de um provedor. Encontre a fonte de autoridade antes de alterar qualquer coisa. Se o gerenciamento de configuração reescreve `authorized_keys`, uma exclusão manual emergencial pode voltar na execução seguinte.

Gere uma identidade substituta com as ferramentas aprovadas e armazene sua parte privada apenas no limite do gateway. Instale a nova parte pública ao lado da antiga. Dê a cada entrada um comentário que identifique a finalidade e a data da rotação e teste-a pelo caminho pretendido. Quando funcionar, remova a entrada pública antiga da fonte de verdade e confirme que o servidor a rejeita.

Você pode verificar a impressão digital de uma chave pública sem expor uma chave privada:

```sh
ssh-keygen -lf deploy-release-ed25519.pub
# 256 SHA256:exampleFingerprint deploy-release-2025 (ED25519)
```

O formato da saída importa mais que a impressão digital de exemplo: tamanho em bits, impressão digital, comentário e tipo de chave. Coloque a impressão digital real no registro da mudança. Não coloque as opções de autorização que acompanham a chave pública em uma captura de tela vaga. Copie a regra exata do servidor para a configuração revisada, para que outro operador possa ver se ela contém um comando forçado ou uma restrição de origem.

Depois, faça um teste negativo com a chave antiga antes de destruir sua última cópia controlada. O servidor deve rejeitá-la depois da remoção. Se não puder realizar o teste porque já não possui a chave privada antiga, examine a fonte autorizada de chaves e os registros de auditoria do provedor. Registre essa limitação. Fingir que a revogação foi testada é pior que documentar uma verificação incompleta.

Evite rotacionar uma chave SSH sobrescrevendo um arquivo no mesmo caminho e reiniciando um cliente desconhecido. Processos de longa duração podem manter conexões abertas, agentes SSH podem oferecer uma identidade antiga e um auxiliar pode armazenar um descritor de arquivo. Um auxiliar de ações sem estado reduz essa ambiguidade porque cada conexão começa com uma seleção conhecida. A propriedade importante é o comportamento observável, não uma linguagem de implementação específica.

## Mantenha autorização e rotação separadas

A aprovação para que um agente execute uma ação é diferente da aprovação para usar uma determinada credencial em todas as chamadas. Tratar as duas como o mesmo controle cria fadiga de aprovação ou deixa identidades sensíveis permissivas demais.

Um controle de sessão responde: «Este processo de agente recém-iniciado pode executar ações durante esta execução?». Ele ajuda a interceptar um processo novo antes que obtenha acesso externo. Um controle por chamada responde: «Esta credencial específica pode ser usada agora?». Ele faz sentido para um pagamento, uma versão em produção ou uma credencial cujo escopo torna cada uso digno de uma verificação humana.

Não peça a uma pessoa que aprove cada leitura inofensiva de status só porque o processo de rotação deixou todos apreensivos. As pessoas aprovam prompts repetidos e idênticos sem lê-los. Use aprovação frequente para identidades cuja ação individual exige julgamento e uma aprovação de sessão claramente limitada para o restante. A rotação não deve treinar operadores a clicar em avisos sem conferir.

A escala de decisão do Sallyport mantém a barreira do cofre absoluta e, por padrão, autoriza um novo processo de agente para sua sessão, com a opção de exigir aprovação para cada uso de uma credencial selecionada. Durante a rotação, isso permite que um operador autorize a sessão de teste e exija confirmação explícita para a nova credencial de produção até que a troca esteja concluída.

A barreira do cofre tem uma função separada. Um cofre bloqueado deve negar ações independentemente do que uma sessão de agente tinha permissão para fazer antes. Isso oferece ao operador uma interrupção imediata durante um possível vazamento ou diante de uma mudança que começa a se comportar de modo inesperado. O bloqueio não revoga a credencial do provedor. Depois de bloquear o acesso, ainda revogue ou desative a identidade externa se alguém puder tê-la copiado para fora do gateway.

Mantenha um registro breve de quem aprovou um teste excepcional em produção e por quê. Não transforme as notas de aprovação em um diário. Uma identidade de sessão, horário, registro de credencial, destino e referência da mudança bastam para conectar a aprovação ao evento de rotação.

## As evidências de auditoria precisam responder a duas perguntas diferentes

Um bom registro de rotação consegue responder tanto «o que o agente fez?» quanto «podemos confiar no registro?». Um log comum de aplicação muitas vezes não responde bem a nenhuma das duas depois que alguém edita arquivos, apaga uma linha ou mistura chamadas rotineiras com um incidente.

A primeira pergunta exige campos operacionais: identidade da sessão, autoridade de assinatura do código ou identidade do processo quando disponível, horário, tipo de ação, destino, nome do registro de credencial, resultado e uma referência à requisição no provedor, se existir. O diário não deve manter tokens bearer, senhas, chaves privadas ou cabeçalhos completos que contenham segredos. Logs com credenciais transformam cada leitor dos logs em outro detentor de credenciais.

A segunda pergunta trata da integridade. A expressão «somente anexar» não basta se um administrador pode reescrever o log de ontem. Uma cadeia de hashes faz cada entrada depender da anterior, permitindo que um verificador detecte remoções ou alterações ao conferir a cadeia. Isso não prova que uma ação nunca aconteceu nem transforma entradas falsas em verdade. Mas torna muito mais difícil apresentar alterações silenciosas como o registro original.

É aqui que diários separados de sessões e atividades fazem diferença. O diário de sessões responde qual processo de agente recebeu autoridade e se alguém revogou aquela execução. O diário de atividades responde quais ações HTTP ou SSH individuais ocorreram durante ela. Se um token de API for rotacionado às 14h, você pode examinar as chamadas que usaram o registro antes e depois da troca sem tratar cada aprovação de sessão como prova de cada requisição.

O Sallyport projeta as duas visões a partir de um log de auditoria criptografado, somente para escrita, e pode verificar sua cadeia offline com `sp audit verify`, sem exigir a chave do cofre. Execute a verificação antes e depois de uma rotação sensível e preserve o resultado com o registro da mudança. Uma verificação bem-sucedida informa que a cadeia registrada é internamente consistente; ela não substitui a revisão dos destinos e resultados reais.

Para uma rotação de alto risco, reúna estas evidências em uma única entrada compacta:

- Por que a credencial mudou e quem é responsável pelo destino da autorização.
- Identificadores seguros das credenciais antigas e novas do provedor, além do fim planejado da sobreposição.
- A ação restrita de validação e seu resultado no provedor.
- As referências à sessão do agente e às atividades envolvidas na validação.
- A prova da revogação da identidade antiga ou a limitação documentada da verificação.

Esse registro permite que um investigador posterior diferencie uma mudança planejada normal de uma credencial nova e inexplicada. Ele também revela uma verificação de revogação ausente antes que meses passem.

## Trate uma suspeita de vazamento como contenção antes da substituição

Quando suspeitar que um agente viu ou exportou um segredo, interrompa o acesso primeiro. Criar um token substituto sem desativar o exposto deixa o caminho antigo disponível para quem o copiou.

Bloqueie o gateway de ações se precisar de contenção local imediata, revogue as sessões ativas dos agentes que já não devem operar e desative ou revogue a credencial do provedor. Preserve as evidências relevantes de sessões e atividades antes que tarefas de limpeza apaguem o contexto. Depois, emita uma nova identidade com escopo limitado ao trabalho que precisa continuar.

Não espere uma prova perfeita de que o valor vazou. Um token em uma transcrição do agente, no histórico do shell, em um commit do repositório, em um log de build ou em um chat copiado já basta para tratá-lo como exposto. No caso de uma chave privada SSH, remova a chave pública correspondente de todas as fontes confiáveis e procure cópias do material privado nos locais onde a automação grava artefatos. Rotacionar uma chave privada enquanto sua chave pública antiga continua autorizada não é contenção.

Depois que o serviço voltar, descubra como o segredo atravessou o limite. As causas mais comuns são banais: um parâmetro de ferramenta aceitava credenciais brutas, um log de depuração imprimia cabeçalhos de requisição, um desenvolvedor copiou um arquivo de ambiente local para o espaço de trabalho do agente ou um cliente alternativo ignorou o gateway. Corrija esse caminho antes de encerrar o incidente. Caso contrário, a substituta apenas começa sua própria contagem regressiva para o próximo vazamento.

## Transforme a expiração em um teste operacional programado

Um lembrete no calendário deve iniciar um teste repetível, uma verificação de responsabilidade e uma decisão de revogação. Não deve produzir um pedido apressado para que alguém cole um novo token no último arquivo de configuração que funcionou.

Revise cada registro de credencial antes da data de expiração do provedor. Confirme que o responsável indicado ainda responde pela conta externa, que a finalidade documentada continua existindo, que os escopos ainda correspondem à ação e que as sessões selecionadas dos agentes ainda precisam de acesso. Se qualquer resposta for negativa, retire a identidade em vez de rotacioná-la.

Para identidades que continuam necessárias, ensaie cedo a ação restrita de validação, para descobrir mudanças na conta do provedor, novas restrições SSH ou permissões de API alteradas. Mantenha o registro desse ensaio separado da rotação real, para que ninguém confunda um teste antigo bem-sucedido com uma prova de que a substituta de hoje funciona.

O teste desconfortável é o que encontra mais defeitos: depois de revogar a credencial antiga, repita exatamente a ação de que o agente depende e verifique se o diário a atribui à sessão e ao registro pretendidos. Se esse teste falhar, você terá uma falha contida, com responsável, evidências e um caminho de reversão conhecido. É uma situação muito melhor que descobrir uma credencial expirada no meio de uma implantação autônoma.
