# Evidências de autorização: prove que as ações do agente de IA foram concluídas

Um registro de aprovação informa que uma pessoa permitiu que um agente tentasse algo. Ele não informa se a solicitação chegou ao serviço, se o host remoto aceitou o comando ou se a alteração pretendida aconteceu. Tratar a aprovação como prova de conclusão cria trilhas de auditoria que parecem tranquilizadoras até o momento em que alguém responsável por analisar um incidente pergunta: «O que realmente aconteceu?»

Essa diferença se torna urgente com agentes de IA, porque eles podem executar muitas ações reais enquanto trabalham em uma tarefa comum de desenvolvimento. Uma pessoa pode aprovar um processo de agente uma vez e, depois, o processo criar um ticket, alterar uma configuração de implantação, consultar uma API de produção ou executar um comando remoto. Cada ação precisa de evidências com um significado diferente. A decisão humana e o resultado obtido fazem parte da mesma investigação, mas não são intercambiáveis.

## Uma aprovação registra permissão, não conclusão

A evidência de autorização responde se um tomador de decisão reconhecido permitiu uma ação definida em determinado momento. A evidência de execução responde o que o gateway de ações tentou fazer e o que o destino devolveu. Um modelo de auditoria que salva apenas a primeira resposta tem uma grande lacuna.

Considere um agente autorizado a chamar uma API que cria um token de acesso. O gateway envia a solicitação, mas a conexão cai depois que o serviço a processa e antes de o chamador receber uma resposta. A aprovação continua válida. Um registro que diz «aprovado» não informa ao revisor se o token existe. Um registro que afirma «concluído» porque o gateway enviou bytes é ainda pior, pois transforma uma incerteza em um fato falso.

O mesmo erro aparece com SSH. Uma pessoa aprova `deploy.sh`. O cliente SSH autentica, o shell remoto é iniciado e a conexão de rede cai enquanto o script é executado. O script terminou? Alterou parcialmente um sistema? O registro da conexão não pode responder. Você precisa do status de saída remoto, se o cliente o recebeu, e de um registro claro de resultado desconhecido se não recebeu.

Mantenha estas perguntas separadas:

- Uma pessoa ou um controle aprovado autorizou este processo de agente?
- Qual capacidade exata a autorização abrangia?
- O gateway enviou a ação ao destino?
- Que resultado o destino ou o transporte retornou?
- Os revisores poderão verificar depois que ninguém editou o histórico?

Muitas equipes comprimem as cinco perguntas em um único evento chamado `agent_action`. Isso é conveniente para um painel e inútil quando os fatos divergem. Armazene eventos relacionados e mostre-os juntos na interface.

A NIST Special Publication 800-53 Rev. 5 faz uma exigência prática parecida no controle AU-3. O conteúdo do registro de auditoria inclui o que aconteceu, quando aconteceu, onde aconteceu, a origem, o resultado e a identidade associada ao evento. O ponto útil não é a linguagem de checklist. É a insistência de que o resultado precisa estar no registro. Uma decisão de permissão não pode preencher esse campo.

## Os dois registros precisam de campos diferentes

Um modelo de auditoria organizado usa um evento de autorização e um ou mais eventos de execução para uma única ação solicitada. Eles compartilham um identificador de correlação, mas cada um mantém os campos que sustentam sua própria afirmação.

O registro de autorização deve identificar a solicitação antes do início da execução. Capture a identidade do processo chamador, a decisão humana, a referência da credencial, o canal pretendido, o destino e a operação solicitada. Registre o escopo da autorização com precisão suficiente para que um revisor veja se a chamada posterior permaneceu dentro dele.

Uma estrutura útil se parece com esta:

```json
{
  "event_type": "authorization.granted",
  "action_id": "act_01JX7K8N4Q",
  "session_id": "ses_01JX7JYQ2M",
  "time": "2025-03-08T14:21:18Z",
  "agent_process": {
    "pid": 4812,
    "code_signing_authority": "Example Development Team"
  },
  "human_decision": {
    "method": "local_confirmation",
    "actor": "local_user"
  },
  "requested_action": {
    "channel": "http",
    "credential_ref": "billing-api-prod",
    "method": "POST",
    "destination": "api.internal.example",
    "path": "/v1/refunds"
  }
}
```

Por padrão, este registro não deve conter o segredo da API, a chave privada SSH, o cabeçalho de autorização nem o corpo bruto da solicitação. Um repositório de auditoria cheio de credenciais se torna um segundo caminho para uma violação. Se os revisores precisarem distinguir solicitações com conteúdo privado, mantenha um digest criptográfico da parte protegida e um resumo curto e redigido, com regras documentadas.

O registro de execução começa quando o gateway tenta realizar a ação. Ele precisa dizer se a ação chegou a uma fronteira de protocolo e o que retornou. Para HTTP, capture o método, o destino, o status da resposta, o erro de transporte, o tamanho da resposta e uma classificação limitada da resposta. Para SSH, capture a conta, a identidade do host, uma representação do comando, o status de saída, o sinal, se houver, e o resultado da conexão no cliente.

```json
{
  "event_type": "execution.finished",
  "action_id": "act_01JX7K8N4Q",
  "time": "2025-03-08T14:21:20Z",
  "channel": "http",
  "attempt": 1,
  "delivery": "response_received",
  "result": {
    "http_status": 201,
    "response_bytes": 428,
    "response_digest": "sha256:..."
  }
}
```

Não escreva `success: true` como único campo de resultado. O significado de sucesso muda entre protocolos e produtos. HTTP 201 significa que o servidor informa a criação de um recurso. HTTP 202 significa que ele aceitou um trabalho para processamento posterior. O status de saída SSH 0 significa que o comando remoto informou sucesso, mas um script ainda pode ter ignorado uma falha interna. Um resultado tipado oferece fatos aos revisores, em vez de um rótulo verde e vago.

## A fronteira confiável de ações deve criar a correlação

O componente que mantém as credenciais e executa a ação deve gerar o ID de ação. O agente pode solicitar um trabalho, mas não pode ser a fonte do registro sobre o que tinha permissão para fazer ou sobre o que o gateway enviou.

Isso importa quando um processo de agente apresenta um erro, é comprometido ou simplesmente se confunde durante uma conversa longa com ferramentas. Se ele criar seus próprios identificadores, poderá associar um resultado posterior a uma solicitação anterior, omitir chamadas inconvenientes ou informar um status inventado. Mesmo um agente bem-comportado pode perder o contexto depois de uma reinicialização. A fronteira de ações vê a solicitação, a seleção da credencial, a tentativa de saída e o resultado retornado em um só lugar.

Use um identificador sem significado comercial e nunca o reutilize. Um ID aleatório ou único ordenável por tempo funciona. Anexe-o a todos os registros locais. Quando o protocolo permitir, leve-o também para fora como identificador da solicitação. Assim, os operadores do serviço podem associar seus registros ao registro do gateway sem expor uma credencial.

Para uma solicitação HTTP, use um cabeçalho dedicado que o sistema de destino aceite registrar, como `X-Action-ID`. Não confunda esse cabeçalho com uma chave de idempotência. Um ID de ação ajuda na investigação. Uma chave de idempotência informa a um servidor compatível que ele deve reconhecer uma mutação duplicada. Um único valor às vezes pode cumprir as duas funções, mas somente depois que o responsável pelo serviço confirmar sua semântica e seu período de retenção.

```text
Authorization: action_id=act_01JX7K8N4Q
Outbound request: POST /v1/refunds
Request header: X-Action-ID: act_01JX7K8N4Q
Response: 201 Created
Execution record: action_id=act_01JX7K8N4Q, delivery=response_received
```

Não dependa apenas de horários para correlacionar registros. Os relógios podem divergir, as solicitações se sobrepõem e os agentes podem fazer chamadas idênticas no mesmo segundo. Os horários ajudam a reconstruir a ordem. Eles não provam a relação de origem.

Um ID de sessão também importa, mas responde a uma pergunta mais ampla: qual execução do processo de agente fez esta solicitação? Preserve os dois IDs. A sessão informa qual processo recebeu uma permissão contínua. O ID de ação informa qual operação específica obteve determinado resultado.

## Códigos de status HTTP são evidências com limites

Uma resposta HTTP oferece evidências de execução mais fortes do que uma aprovação local, mas ainda precisa ser interpretada. Registre o status final e contexto suficiente para explicá-lo. Não transforme todo status fora da faixa 200 em falha.

Um `200 OK` ou `201 Created` é um relatório explícito do servidor. Um `204 No Content` geralmente significa que a operação foi bem-sucedida sem corpo de resposta. Um `202 Accepted` é diferente: o destino recebeu a solicitação para processamento assíncrono, mas o trabalho final pode falhar depois. Seu registro de execução deve dizer `accepted_for_async_processing` e, quando o serviço oferecer esse padrão, associar à mesma ação uma verificação de status ou um callback posterior.

Redirecionamentos exigem cuidado. Se um gateway seguir redirecionamentos, registre o destino original e o final, incluindo se a regra de injeção de credenciais foi aplicada em cada salto. Encaminhar um cabeçalho de autorização para um host inesperado é um vazamento de credencial, não um redirecionamento comum. Na prática, rejeite redirecionamentos entre hosts, a menos que um operador tenha configurado explicitamente a relação entre os destinos.

Erros do cliente e do servidor também trazem fatos úteis. Um `403` prova que o serviço negou a solicitação. Um `409` pode mostrar que já existe um estado duplicado ou conflitante. Um `429` informa que o destino recusou o trabalho por enquanto. Um `500` informa que o servidor relatou uma falha, não que nenhuma alteração ocorreu. O corpo da resposta pode esclarecer o resultado, mas só o armazene depois de aplicar redação e limites de tamanho. Respostas de erro frequentemente contêm mais detalhes operacionais do que respostas de sucesso.

Falhas de transporte precisam de seus próprios valores de resultado. Registre distinções como `dns_failure`, `tls_validation_failure`, `connect_timeout`, `write_interrupted`, `response_timeout` e `connection_reset`. Esses resultados informam ao revisor onde termina a certeza.

A categoria perigosa é uma solicitação interrompida depois que o gateway começa a enviá-la. O serviço pode ter agido. Marque o estado como `unknown_remote_outcome`; não o classifique como falha apenas porque o cliente não tem uma resposta. Se a chamada alterar um estado, o agente deve pausar e usar um método seguro de reconciliação. Esse método pode consultar o serviço por uma chave de idempotência, ler um recurso usando um identificador de solicitação ou pedir que uma pessoa inspecione o destino.

## SSH precisa de evidências do processo remoto

Os registros de auditoria SSH muitas vezes terminam em «conectado ao host». Isso prova apenas que um cliente estabeleceu uma sessão SSH. Não diz nada sobre o resultado do comando e talvez nem identifique o host exato que respondeu, a menos que você registre a verificação da chave do host.

Para cada ação SSH, registre o nome do host de destino, o endereço resolvido, se disponível, a impressão digital verificada da chave do host, a conta solicitada, a referência do método de autenticação, o comando normalizado e o resultado final no cliente. Se o comando remoto começar, capture seu status de saída e o sinal de encerramento. Trate a saída padrão e a saída de erro como dados operacionais sensíveis, não como material automático de log.

Um comando normalizado preserva o valor da revisão e reduz a exposição. Por exemplo, em vez de guardar um comando que contenha um argumento secreto, mantenha o executável, as opções fixas, as posições dos argumentos sensíveis e um digest dos valores protegidos.

```text
requested_command: /usr/local/bin/rotate-service-token --project payments --token [redacted]
command_digest: sha256:...
remote_exit_status: 0
remote_signal: null
connection_result: clean_close
```

O status de saída 0 é uma evidência do comando remoto, não uma prova de que todos os efeitos comerciais ocorreram. Um script de shell mal escrito pode executar `curl`, ignorar o erro e ainda terminar com status 0. Se você controla o script, faça-o falhar claramente e retornar um valor diferente de zero quando uma operação necessária falhar. Se não o controla, registre o resultado do comando com precisão e evite afirmar mais do que os dados permitem.

Sessões SSH interativas merecem desconfiança. Elas criam uma enorme distância entre «permissão concedida» e «comandos executados». Um comando remoto limitado produz evidências melhores do que conceder a um agente um shell interativo geral. Se uma tarefa precisar de vários comandos, use um script revisado com saídas explícitas ou crie registros de ação separados para cada comando. Isso é menos atraente do que deixar um agente digitar livremente em um terminal, mas é muito mais fácil de investigar.

A verificação do host deve permanecer ativada. Um registro que diz que um agente executou um comando em `build-01` significa pouco se o cliente aceitou um host não verificado durante um ataque de rede ou depois de uma substituição equivocada do host. Preserve a impressão digital verificada da chave do host no evento de execução. Assim, os revisores podem distinguir o rótulo do nome do host da identidade criptográfica.

## Um timeout deve terminar em incerteza, não em uma tempestade de novas tentativas

A falha que mais costuma surpreender as equipes começa com uma chamada de API que altera dados e termina em timeout. O agente recebeu permissão. O gateway abriu uma conexão e enviou a solicitação. O destino concluiu a alteração, mas a resposta desapareceu, ou o destino nunca recebeu os bytes finais. Para quem chama, os dois caminhos parecem iguais.

Imagine que um agente crie um ticket de incidente de produção por meio de uma API. Ele envia:

```text
POST /v1/incidents
Idempotency-Key: inc_72f9c
X-Action-ID: act_01JX7K8N4Q
```

O cliente espera e depois registra `response_timeout`. Uma trilha de auditoria baseada apenas na aprovação diz que a pessoa aprovou um ticket. Um registro de ação simplista diz que a criação do ticket falhou. Nenhuma das duas afirmações é segura.

O registro correto de execução diz que o gateway tentou fazer a solicitação e não recebeu uma resposta. Ele deve preservar o ID de ação e a referência da chave de idempotência. Depois, o agente consulta o serviço sobre o estado associado a `inc_72f9c`, se o serviço oferecer essa consulta. Se o serviço informar que existe um ticket, registre um evento de reconciliação apontando para a ação original. Se informar que não há registro e o contrato de idempotência permitir uma nova tentativa, repita uma vez usando a mesma chave de idempotência, não uma nova chave.

A sequência contém três fatos separados:

1. Uma pessoa aprovou a solicitação original.
2. O gateway não conseguiu confirmar o resultado inicial.
3. Uma leitura posterior ou uma repetição idempotente estabeleceu o estado final.

Não apague o timeout depois da reconciliação. Ele explica por que a ação posterior ocorreu. Também mostra se a equipe enfrenta um problema recorrente de transporte que uma contagem de sucessos bem apresentada esconderia.

O SSH tem uma falha equivalente. Um comando remoto pode continuar depois que o cliente local perde a sessão. Evite novas tentativas automáticas, a menos que o comando seja comprovadamente idempotente. Prefira um ID de operação remoto, um arquivo de status com permissões controladas ou uma API de destino que informe o estado. Se nada disso existir, registre o resultado desconhecido e exija uma revisão humana. Comandos de implantação duplicados já causaram danos suficientes sem que um agente os repita na velocidade de uma máquina.

## A aprovação por sessão e a aprovação por chamada tratam riscos diferentes

A autorização por sessão estabelece que determinado processo de agente pode usar canais de ação aprovados durante sua execução. Ela reduz o desgaste causado por aprovações quando uma pessoa espera uma sequência curta e limitada de tarefas de baixo impacto. Ela não transforma chamadas posteriores em decisões analisadas individualmente.

A aprovação por chamada registra uma decisão humana para cada uso de uma credencial selecionada. Use-a em operações nas quais cada destino, mutação ou comando remoto merece atenção renovada. O registro de execução continua necessário. Uma pessoa pode aprovar uma chamada destrutiva de API e o serviço pode rejeitá-la, processá-la parcialmente ou sofrer um timeout.

A diferença fica clara quando os revisores perguntam: «Quem aprovou esta alteração?» Um registro de sessão pode responder: «Este processo de agente assinado tinha permissão para chamar este canal». Um registro por chamada pode responder: «Uma pessoa aprovou esta solicitação exata neste horário». Nenhum dos dois responde: «Isso aconteceu?» Apenas as evidências de execução resultantes podem tratar dessa pergunta.

Os avisos de aprovação devem mostrar informações suficientes para que uma pessoa tome uma decisão significativa: identidade do processo chamador, referência da credencial, destino, método ou comando e indicação de que a solicitação altera um estado. Um aviso que diz apenas «Permitir acesso do agente?» registra um clique, mas captura quase nenhuma intenção útil.

Não tente resolver isso criando primeiro uma linguagem de políticas gigantesca. As equipes frequentemente recorrem a regras porque querem menos avisos. As regras podem limitar ações, mas não substituem um modelo de auditoria que diferencie aprovação, tentativa, resposta e resultado desconhecido. Primeiro torne os fatos compreensíveis. Depois decida onde a automação é segura.

## Cadeias de hashes protegem o histórico, não a verdade de uma afirmação

Um registro somente para acréscimo e encadeado por hashes torna a adulteração posterior detectável. Cada evento inclui ou contribui para um digest que depende dos registros anteriores. Se alguém alterar uma autorização antiga, remover uma solicitação com falha ou reordenar uma sequência, a verificação falhará, a menos que essa pessoa consiga reescrever a cadeia a partir do ponto alterado e substituir a cabeça confiável da cadeia.

Essa propriedade importa para a atividade de agentes porque os registros mais constrangedores costumam ser justamente os que alguém deseja remover: uma ação negada, uma implantação malsucedida, uma solicitação enviada ao serviço errado ou uma sessão que continuou além do esperado. Um registro que administradores podem editar silenciosamente não resistirá a uma revisão séria.

Mas o encadeamento por hashes não torna verdadeira uma entrada falsa. Se um agente não confiável fornecer «HTTP 201» e o registro encadear fielmente essa mentira, a cadeia provará apenas que a mentira persistiu. O coletor precisa observar o evento na fronteira de ações. O gateway deve criar o resultado da execução depois de receber a resposta ou detectar a falha de transporte.

A NIST SP 800-92, Guide to Computer Security Log Management, alerta que os registros precisam de proteção durante geração, transmissão, armazenamento, análise e descarte. A lição prática é mais ampla do que centralizar arquivos de texto. Preserve a fonte bruta do evento, proteja a sequência, controle quem pode alterar os registros e permita a verificação sem conceder acesso amplo aos segredos usados pelas ações.

O Sallyport projeta execuções de agentes e chamadas individuais em um único registro de auditoria criptografado, encadeado por hashes e sem permissão de escrita. O comando `sp audit verify` verifica a cadeia offline sobre o texto cifrado sem precisar da chave do cofre. Esse projeto separa o revisor que verifica a integridade do histórico do processo que pode usar credenciais de produção.

Um comando de verificação deve produzir um resultado inequívoco e identificar o intervalo verificado. Por exemplo:

```text
$ sp audit verify
verified: 1847 records
chain: valid
first_record: 2025-03-01T08:15:02Z
last_record: 2025-03-08T14:21:20Z
```

Uma cadeia válida não resolve se uma API externa cumpriu sua promessa. Ela estabelece que o relato preservado pelo gateway sobre a aprovação e o resultado recebido não foi alterado sem ser detectado.

## Revise as associações, não as contagens isoladas de eventos

A revisão de auditoria falha quando as equipes contam aprovações, chamadas bem-sucedidas e chamadas negadas em gráficos separados, mas nunca inspecionam as associações entre elas. A unidade útil de revisão é uma linha do tempo da ação: solicitação, decisão de autorização, tentativas de execução, resultado e qualquer reconciliação.

Comece pelos registros que não têm um evento correspondente. Uma autorização sem evento de execução pode refletir uma solicitação cancelada, uma falha do gateway ou um erro de registro. Um evento de execução sem autorização anterior pode revelar um desvio de controle. Um resultado remoto desconhecido sem reconciliação é trabalho operacional inacabado, não uma falha encerrada.

Use um pequeno conjunto de consultas ou relatórios que force estas perguntas:

- Quais ações aprovadas que alteravam dados terminaram com resultado remoto desconhecido?
- Quais chamadas receberam uma resposta fora do escopo da autorização?
- Quais comandos SSH terminaram sem status de saída?
- Quais aprovações por sessão produziram ações depois do fim esperado da tarefa?
- Quais IDs de ação aparecem nos registros locais, mas não nos registros do serviço de destino?

A última consulta exige cautela. A ausência em um registro de destino pode significar que o destino não reteve o ID da solicitação, que a janela de tempo está errada ou que outra equipe é responsável pelos registros. Marque isso como sinal para investigação, não como prova de irregularidade.

O diário de sessões e o diário de atividades do Sallyport tornam essa separação prática: uma visão mostra a execução do agente e seu estado de revogação, enquanto a outra mostra as chamadas individuais. Os revisores devem passar de uma visão para a outra por meio dos identificadores de sessão e de ação, em vez de tratar qualquer diário como a história completa.

Mantenha um vocabulário explícito para o grau de certeza. `authorized`, `attempted`, `response_received`, `remote_exit_received`, `denied`, `failed_before_send` e `unknown_remote_outcome` são mais fáceis de defender do que um único indicador de sucesso. Quando a equipe usa esses termos de modo consistente, os casos difíceis deixam de desaparecer em painéis verdes e agradáveis.

## Crie evidências antes de conceder acesso mais amplo aos agentes

Você não precisa de um plano de controle complexo para começar. Coloque o uso de credenciais atrás de uma fronteira de ações confiável, crie o ID de ação ali, registre a decisão humana separadamente do resultado e preserve os resultados desconhecidos sem reescrevê-los como falhas. Isso fornece aos responsáveis por incidentes uma sequência que pode ser comparada com registros de serviços e hosts.

Depois, teste o registro durante uma falha, não apenas em um caminho bem-sucedido. Aprove uma solicitação e corte a conexão depois do envio. Execute um comando SSH que retorne um status de saída diferente de zero. Force uma falha de DNS. Revogue uma sessão de agente e verifique se as chamadas posteriores recebem registros de negação. Veja se um revisor consegue explicar cada evento sem abrir um arquivo de origem ou perguntar ao agente o que ele quis dizer.

Um agente pode receber permissão para agir sem manter uma credencial. Ele não pode receber permissão para redefinir o que aconteceu. Preserve o registro da decisão, preserve o resultado da execução e deixe a incerteza visível quando a rede se recusar a cooperar.
