# Logs de auditoria de agentes: registros de sessão e de chamadas

Os logs de auditoria de agentes falham quando tentam responder a duas perguntas diferentes em um único registro. Durante um incidente, você precisa descobrir tanto quem tinha autoridade para agir quanto exatamente qual ação chegou ao mundo externo. Um registro da execução não substitui um registro da chamada, e uma lista de solicitações não explica por que aquele processo tinha permissão.

As equipes costumam manter apenas uma dessas visões porque ela parece suficiente durante uma demonstração. Então o agente abre um chamado, atualiza uma configuração de produção ou executa um comando SSH, e a investigação vira uma tentativa de adivinhar horários. Isso pode ser evitado. Mantenha um diário de sessão para registrar autoridade e ciclo de vida. Mantenha um diário de atividade para cada ação externa tentada. Associe os dois com um identificador que nem pessoas nem agentes possam inventar livremente.

## Um registro de execução responde quem tinha autoridade

Um registro de sessão deve mostrar se um processo específico de agente tinha permissão para agir, durante qual período e com base em qual decisão humana. É o registro usado quando alguém pergunta: «Qual instância do agente fez isso e por que permitimos que ela agisse?»

Um registro de sessão útil começa quando um processo pede autoridade pela primeira vez, não quando um usuário abre um editor nem quando um diretório de projeto aparece. Nomes de agentes são evidências fracas. Dois processos podem se chamar da mesma forma, e um binário malicioso pode usar um nome conhecido. Registre a identidade do processo disponível para o host, a autoridade de assinatura do código quando o sistema operacional fornecer essa informação, o processo pai quando for útil, um ID de sessão gerado, os horários de início e término e o resultado da autorização.

O registro de sessão também precisa dos eventos do ciclo de vida. A aprovação é um evento. A revogação é um evento. A saída do processo é um evento. Bloquear o cofre de credenciais, quando isso interrompe a atividade, também é um evento que vale a pena associar. Sem esses limites, um investigador não consegue saber se uma chamada ocorreu dentro de um período aprovado ou depois de um suposto desligamento.

Não transforme um registro de sessão em um diário de cada pensamento do modelo, linha de terminal e edição de arquivo. Isso cria uma pilha de material sensível e ainda deixa de registrar o limite que importa: um processo de agente recebeu autoridade para pedir que um gateway execute ações externas. Registre de forma clara as evidências que estabelecem esse limite.

Considere este registro de sessão simplificado:

```json
{
  "type": "session.authorized",
  "session_id": "ses_7f4c2",
  "observed_at": "2025-04-18T14:03:11Z",
  "process": {
    "pid": 8124,
    "signing_authority": "Example Development Team",
    "parent_pid": 8090
  },
  "decision": "approved",
  "approved_by": "local_operator"
}
```

O registro não precisa do nome de um funcionário para ser útil. Em uma estação de trabalho compartilhada, `local_operator` pode ser o nível honesto de atribuição. Fingir que você sabe mais produz uma ficção apresentada como certeza. Se o seu ambiente puder associar a aprovação a uma pessoa autenticada, registre essa associação e como ela foi estabelecida.

Um registro de sessão nunca deve afirmar que uma execução inteira foi segura. A aprovação concede autoridade, mas não aprova previamente todos os efeitos que um processo pode criar. Essa distinção parece minuciosa até que um agente de programação mantenha uma sessão aberta por horas e faça centenas de chamadas sob uma única aprovação.

## Um registro de chamada responde o que chegou ao mundo externo

Um registro de chamada deve descrever uma operação tentada e seu resultado. É a evidência necessária quando alguém pergunta: «O agente enviou esta solicitação, para qual destino e com que resultado?»

Registre as tentativas, não apenas os sucessos. Uma solicitação negada pode mostrar que um agente estava procurando uma credencial. Uma solicitação malsucedida pode indicar um host digitado incorretamente, um segredo expirado ou um comando inseguro rejeitado pelo lado remoto. Uma solicitação cancelada pode explicar por que uma sessão parece ter parado no meio de uma implantação. Logs que registram apenas sucessos contam uma história conveniente, mas incompleta.

Para uma ação HTTP, retenha a identidade do destino, o método HTTP, o caminho ou uma representação controlada dele, a referência da credencial em vez do valor da credencial, o horário da solicitação, o horário de conclusão, o resultado do status, o ID da sessão e um ID da chamada. Para SSH, retenha a identidade pretendida do host, o comando ou uma representação segura dele, o resultado da conexão, o status de saída remoto quando disponível, o ID da sessão e o ID da chamada.

Você precisa decidir com cuidado quais dados da solicitação serão retidos. Registrar todos os cabeçalhos e corpos por hábito é esperar que um incidente aconteça. Cabeçalhos de autorização, cookies, URLs assinadas, tokens de acesso, dados privados de clientes e senhas costumam ficar escondidos ali. Um bom registro preserva o significado da operação e elimina o material secreto. Por exemplo, `POST /v1/users/123/disable` pode ser suficiente para reconstruir uma alteração administrativa. Copiar todo o corpo JSON pode expor muito mais do que a investigação precisa.

Use a identidade do destino, não apenas uma string de URL bruta. `https://api.example.test` e `https://api.example.test:443` podem representar o mesmo destino, enquanto um host parecido pode diferir por um único caractere. No SSH, registre a identidade do host usada para verificação quando o sistema puder obtê-la. Um nome de host, sozinho, não confirma que a conexão chegou à máquina esperada.

Este conjunto mostra a separação:

```json
{
  "type": "call.completed",
  "call_id": "call_b91d",
  "session_id": "ses_7f4c2",
  "observed_at": "2025-04-18T14:09:27Z",
  "channel": "http",
  "operation": "POST",
  "target": "api.example.test/v1/deployments/42/cancel",
  "credential_ref": "deployment-service",
  "authorization": "session_approved",
  "outcome": "completed",
  "response_status": 202
}
```

O ID da sessão mostra de quem era a autoridade usada pela chamada. O destino e o resultado mostram o que aconteceu. Se você juntar tudo em um único evento vago, como `agent performed task`, não terá registrado bem nenhuma das duas respostas.

## Aprovação e execução são fatos diferentes

As equipes costumam confundir um evento de aprovação com uma evidência de que uma solicitação foi executada. São fatos diferentes, e uma trilha de auditoria precisa preservar ambos.

Um operador pode aprovar um novo processo de agente e depois se afastar. O processo pode não fazer nenhuma chamada porque a tarefa termina localmente. Pode fazer uma solicitação de API malsucedida. Pode fazer cinquenta solicitações bem-sucedidas. O registro de aprovação permanece igual em todos os casos. Apenas os registros de chamadas individuais mostram o efeito.

A confusão inversa também acontece. Alguém vê uma solicitação de saída em um log de rede e presume que um agente aprovado a enviou. Um log de rede pode comprovar uma conexão ou um fragmento da solicitação, dependendo de onde foi capturado. Em geral, ele não mostra a decisão de aprovação, a identidade real do processo nem se um gateway inseriu uma credencial em nome do agente. Não o obrigue a responder perguntas para as quais nunca foi projetado.

A NIST Special Publication 800-92, Guide to Computer Security Log Management, diferencia a origem do evento, a infraestrutura de logging e o processo de análise. A lição prática para sistemas de agentes é clara: colete o evento na camada que conhece o fato. A camada de autorização sabe se uma sessão recebeu autoridade. O gateway de ações sabe qual operação tentou executar com uma credencial protegida. Um firewall sabe qual tráfego observou. Cada registro tem um alcance probatório diferente.

Um estado de autorização preciso em cada chamada ajuda. `session_approved` significa que a sessão tinha uma aprovação permanente. `per_call_approved` significa que um operador aprovou aquele uso. `denied_locked` significa que o cofre de credenciais rejeitou a tentativa enquanto estava bloqueado. `denied_user` significa que um operador a rejeitou. Esses rótulos não são decorativos. Eles informam ao investigador se a operação chegou ao executor da ação e se uma intervenção humana a interrompeu.

Não rotule toda chamada bem-sucedida como «aprovada». Essa palavra esconde a diferença entre a permissão concedida no início da sessão e a permissão concedida no momento do uso. Quando um revisor de incidente pergunta se alguém aprovou a exclusão, o registro deve responder de imediato.

A aprovação por chamada tem seu lugar, mas trate-a como um controle específico. Use-a para credenciais em que cada uso tenha consequências elevadas ou quando o destino alterar um estado que o operador deva visualizar. Se você exigir um clique humano para leituras rotineiras e chamadas inofensivas de build, as pessoas aprenderão a aprovar uma sequência de avisos sem prestar atenção. A aprovação continuará existindo no papel, mas deixará de significar consentimento consciente.

## Uma linha do tempo de falha revela lacunas escondidas pelos resumos

Uma única linha do tempo de incidente deixa evidente o valor das duas visões. Imagine que um agente autônomo de programação receba a tarefa de limpar ambientes de preview antigos. O operador aprova o processo para a sessão. O agente encontra uma credencial antiga da API de implantação e pede ao gateway que faça chamadas com ela.

Às 14:03, o diário de sessão registra um processo aprovado e atribui `ses_7f4c2`. Às 14:07, o diário de atividade registra uma solicitação `GET` que lista as implantações. Às 14:09, registra a chamada de cancelamento mostrada acima. Às 14:10, uma segunda tentativa de cancelamento recebe uma resposta 403. Às 14:12, o operador revoga a sessão ao perceber que o agente selecionou o grupo de ambientes errado.

Agora imagine que você tenha mantido apenas registros de sessão. Poderia dizer que um processo foi aprovado e depois revogado. Não poderia determinar se ele cancelou um ambiente, vários ou nenhum. Também não conseguiria distinguir uma segunda tentativa bloqueada de uma tentativa bem-sucedida. Teria de consultar o serviço de implantação, e a retenção ou o nível de detalhe do log dele talvez não atendesse às suas necessidades.

Agora imagine que você tenha mantido apenas registros de chamadas. Poderia ver duas solicitações de cancelamento. Não poderia determinar qual processo local as iniciou, se um operador aprovou esse processo, se a aprovação ainda era válida naquele momento ou se o revisor agiu prontamente depois da revogação.

A linha do tempo deve preservar a ordem sem fingir que o horário do relógio é perfeito. As máquinas apresentam diferenças de relógio. Os serviços remotos informam seus próprios horários. Registre o horário do gateway quando observar a solicitação e, quando for relevante, retenha separadamente o horário do resultado remoto. Use uma sequência de ordenação dentro do log de auditoria, se houver uma. Não declare causalidade apenas porque dois eventos compartilham o mesmo segundo em um relógio.

A questão incômoda é saber se uma sessão revogada pode ter chamadas concluídas depois disso. Pode, dependendo de quando a revogação chega ao executor e de a solicitação já ter saído ou não da máquina. Seus registros devem tornar isso visível. Registre o horário da revogação e depois registre qualquer conclusão de chamada posterior, com os horários de início e conclusão da chamada. Um sistema que simplesmente exclui uma sessão torna essa análise impossível.

## Os IDs de correlação precisam ter um responsável claro

Um ID de sessão só funciona quando o gateway o atribui e controla. Não permita que o agente forneça um identificador de sessão e trate esse valor como evidência de segurança.

Agentes podem transportar texto arbitrário entre chamadas de ferramentas. Podem reutilizar um ID antigo depois de uma reinicialização, digitar um ID incorretamente ou reivindicar deliberadamente o ID de outra sessão se uma interface permitir isso. O gateway deve derivar a associação a partir da conexão local autenticada ou da relação entre processos e anexar o ID da sessão a cada chamada por conta própria.

Os IDs de chamada precisam do mesmo tratamento. Gere-os no limite da ação, antes que a solicitação saia. Se uma solicitação HTTP for repetida, registre se a repetição é uma nova tentativa associada à chamada original ou parte da mesma chamada com várias tentativas de transporte. Qualquer um dos modelos pode funcionar. Misturá-los destrói a precisão da contagem durante uma interrupção.

Use um modelo de correlação pequeno e consistente:

- Um ID de sessão agrupa os eventos de autoridade e ciclo de vida de um processo de agente.
- Um ID de chamada identifica uma operação externa solicitada.
- Um ID de tentativa identifica uma tentativa de transporte quando as repetições são relevantes.
- Uma referência de credencial identifica o segredo configurado sem expor seu valor.
- Uma referência de destino identifica o host, serviço ou destino do comando.

Não torne todos os identificadores globalmente compreensíveis para uma pessoa. A função deles é associar registros com confiabilidade. Rótulos legíveis podem aparecer ao lado deles, mas rótulos mudam, colidem e convidam a edições casuais.

Para agentes simultâneos, a correlação evita uma falha comum. Um engenheiro vê uma solicitação destrutiva às 16:21, encontra uma transcrição de terminal de um agente no mesmo horário e presume que os dois eventos correspondem. Enquanto isso, outro processo de agente estava sendo executado na mesma conta. O ID da sessão no registro da ação elimina a suposição. Se não houver uma associação estável, declare essa limitação no relatório do incidente em vez de preencher a lacuna com confiança.

## O log de auditoria deve mostrar rejeições e usos

Ações negadas muitas vezes são mais importantes que ações concluídas porque revelam o que um agente tentou fazer antes de ser interrompido por um controle. Registre-as com contexto suficiente para explicar a decisão, mas evite transformar o log de rejeição em uma nova fonte de segredos.

Um cofre de credenciais bloqueado deve negar toda ação que precise dele. O registro de chamada resultante deve informar que a ação foi negada antes da execução externa, identificar a sessão e o destino solicitados e indicar a classe do motivo. Ele não deve conter um token falso, uma chave privada parcial nem um cabeçalho de autorização copiado.

A rejeição por chamada merece o mesmo cuidado. Se um operador rejeitar um comando SSH, registre a representação do comando, o destino, o horário da decisão e o resultado da decisão. A ausência de um status de saída remoto passa então a ter significado: o executor nunca iniciou o comando. Isso é diferente de um comando que foi iniciado e retornou um status diferente de zero.

O Sallyport usa três controles fixos: um bloqueio absoluto do cofre, autorização por sessão como padrão e aprovação opcional por chamada para uma credencial individual. Esse modelo limitado torna a interpretação da auditoria mais clara, porque cada registro pode identificar qual decisão interrompeu ou permitiu a ação.

Evite a resposta da moda de criar uma linguagem de políticas gigantesca para cada ação do agente. Ela é popular porque promete automação completa. Na prática, um mecanismo de políticas acrescenta um segundo programa que as equipes precisam revisar, testar, atualizar e explicar durante um incidente. Se você precisa de políticas para governança de rede ou serviços, use-as na camada apropriada. Não finja que um conjunto de regras ilegível elimina a necessidade de evidências claras de sessão e de chamada.

Um registro deve distinguir estes resultados:

- O agente nunca teve uma sessão autorizada.
- A sessão tinha autoridade, mas o cofre estava bloqueado.
- O gateway solicitou uma decisão por chamada e o operador a rejeitou.
- O gateway executou a ação e o destino remoto a rejeitou ou apresentou uma falha.
- O gateway executou a ação e recebeu um resultado bem-sucedido.

Esses casos exigem providências diferentes. Uma solicitação de sessão negada pode apontar para um processo não confiável. Um 403 remoto pode indicar um problema no escopo da credencial. Uma chamada bem-sucedida, mas indesejada, pode exigir a revisão da instrução da tarefa, da decisão de aprovação da sessão e do uso permitido da credencial de destino.

## A evidência contra adulteração protege o registro depois do incidente

É fácil editar, truncar ou substituir logs comuns de aplicativos depois que alguém obtém controle do host. Isso não os torna inúteis, mas limita o que podem provar. Um log de auditoria encadeado por hashes torna alterações posteriores evidentes quando um verificador compara a cadeia com os registros que recebeu.

A distinção importa. Uma cadeia de hashes pode mostrar que uma entrada foi alterada ou desapareceu do meio de uma cadeia preservada. Ela não prova que o sistema registrou todos os eventos que deveriam existir. Não pode recuperar um host que já estava comprometido antes de criar o evento. Também não informa se um operador entendeu um cartão de aprovação. Qualquer afirmação além disso é teatro de segurança.

A RFC 5848, Signed Syslog Messages, trata de um problema relacionado: as mensagens de log podem perder integridade e garantia de origem ao atravessar sistemas. A lição continua válida quando você usa um diário local criptografado em vez de syslog. Proteja os logs perto do ponto onde o evento ocorre, retenha evidências da ordem e verifique os registros em vez de simplesmente confiar em uma interface bonita.

O Sallyport projeta seus diários Sessions e Activity a partir de um único log de auditoria criptografado, encadeado por hashes e sem possibilidade de escrita retroativa. O comando `sp audit verify` verifica a cadeia offline sobre o texto cifrado sem precisar da chave do cofre. Isso é útil quando o revisor deve validar a integridade dos registros sem receber os segredos usados nas ações.

Execute a verificação antes de filtrar, exportar ou anotar registros para um incidente. Preserve primeiro as evidências criptografadas originais. Depois, faça uma cópia de trabalho para a análise. Se a verificação falhar, registre a falha e o artefato exato examinado. Não continue silenciosamente com uma exportação limpa, porque a questão da integridade passou a fazer parte do incidente.

A evidência contra adulteração também muda a disciplina operacional. Quando a equipe sabe que uma edição posterior ficará visível, as pessoas deixam de tratar o diário de auditoria como um lugar conveniente para reescrever a história depois de uma implantação malsucedida. Isso, por si só, não evita erros. Mas preserva as evidências necessárias para aprender com eles.

## A retenção precisa de limites, não de coleta indiscriminada

Mantenha os registros de sessão e de chamadas pelo tempo necessário para investigar descobertas tardias, uso indevido de credenciais e revisões de acesso. Não retenha todos os payloads para sempre apenas porque o armazenamento é barato. Os logs mais perigosos muitas vezes são aqueles que ninguém classificou.

Comece pelas perguntas que sua equipe precisa responder durante um incidente. Quanto tempo depois de uma execução do agente o responsável por um serviço pode perceber uma alteração indesejada? Por quanto tempo você precisa rastrear o uso de uma credencial depois da saída de um funcionário? Quais regulamentos ou contratos impõem requisitos de retenção? Essas respostas definem o período. Elas não justificam coletar prompts brutos, respostas completas ou segredos desnecessários.

Separe a visibilidade operacional da preservação forense. Os operadores podem precisar de uma visão atual e concisa das sessões ativas e das chamadas recentes. Os investigadores podem precisar da sequência imutável completa, incluindo negações e detalhes de horário. Dar a todos os desenvolvedores acesso irrestrito à segunda visão transforma a trilha de auditoria em outro conjunto de dados sensível.

Use limites de função na revisão, mas não use o controle de acesso como motivo para esconder informações das pessoas responsáveis pelos incidentes. O responsável por um serviço pode precisar saber que uma chamada alterou esse serviço. Não precisa de um token bearer nem de um payload de cliente sem relação para descobrir isso.

Quando um registro apontar para conteúdo sensível mantido em outro lugar, armazene uma referência controlada e um procedimento de recuperação. Por exemplo, retenha um ID de solicitação que o serviço de destino possa usar para localizar um payload protegido sob suas próprias regras de acesso. Isso mantém o diário de ações útil sem duplicar dados comerciais sensíveis em todos os sistemas de auditoria.

A exclusão precisa de seu próprio registro. Se a retenção expirar um lote de entradas, registre o evento de retenção, o escopo e a autoridade que causou a remoção antes de excluir os dados. Sem isso, um verificador posterior não consegue distinguir uma expiração autorizada de uma ausência sem explicação. Mantenha a política de retenção compreensível o bastante para que um revisor de incidente possa aplicá-la sem consultar quem escreveu o sistema original.

## Monte a visão do incidente partindo da chamada

Durante uma investigação ativa, comece pela chamada suspeita e avance para fora dela. Em geral, essa é a evidência mais concreta: um destino, uma operação, um horário e um resultado. Use o ID da sessão para recuperar o registro de autoridade. Depois, examine as chamadas próximas naquela sessão e o evento de revogação ou saída da sessão.

Use esta sequência:

1. Preserve e verifique os registros de auditoria originais antes de editá-los ou exportá-los.
2. Localize o registro da chamada por destino, ID da chamada, operação ou janela de horário do incidente.
3. Recupere o registro da sessão associada e confirme a identidade do processo, o horário da aprovação e o estado do ciclo de vida.
4. Revise todas as chamadas daquela sessão próximas ao evento, incluindo negações e repetições.
5. Compare a linha do tempo da ação com os próprios registros do serviço de destino e documente as lacunas em vez de adivinhar.

Esse método identifica tanto o erro evidente quanto o mais silencioso. O erro evidente é uma chamada que nunca deveria ter acontecido. O erro silencioso é uma sessão que continuou autorizada depois do fim da tarefa pretendida ou uma repetição que realizou novamente uma ação após um timeout do serviço.

Não altere primeiro todas as credenciais só porque isso parece uma decisão firme. Se o cofre manteve as credenciais longe do agente e o registro mostra uma chamada emitida pelo gateway para um único destino conhecido, uma alteração ampla pode causar uma interrupção desnecessária. Revogue imediatamente as sessões ativas quando houver possibilidade de uso indevido contínuo. Depois, use os registros de chamadas para decidir qual credencial, destino ou escopo de acesso precisa de ação.

Duas visões realmente geram mais registros. Elas também eliminam a frase mais cara de um relatório de incidente: «Não é possível determinar se o agente aprovado realmente fez essa alteração». Torne a autoridade visível no limite da sessão e os efeitos visíveis no limite da chamada. Qualquer coisa menor deixa sua equipe reconstruindo um evento de segurança a partir de fragmentos.
