Notícias11 min de leitura
O que um desenvolvedor precisa entender sobre agentes de IA com acesso a sistemas reais
Sandbox, credenciais, menor privilégio, rede e logs: o que muda quando um agente de IA deixa o chat e passa a executar shell, APIs e ferramentas.
- agentes-ia
- seguranca
- sandbox
- menor-privilegio
- devops
O agente leu o ticket, chamou a API do banco, rodou um comando no shell e respondeu que "já resolveu". No chat, isso parece produtividade. Na infraestrutura, é um processo com identidade, rede e credenciais. A diferença entre um assistente que sugere SQL e um agente que executa o SQL não é de UX. É de superfície de ataque.
Eu uso agentes com ferramentas no dia a dia. O que me interessa neste texto não é o modelo em si. É o que você precisa controlar quando a saída do modelo deixa de ser texto e vira ação: sandbox, credenciais, menor privilégio, isolamento de rede, orçamento de tokens e tempo, allowlist de ferramentas, e logs que sobrevivem a um incidente.
A cena: shell e API no mesmo loop
Um agente típico com acesso a sistemas reais faz um loop. O modelo recebe o objetivo. Decide uma ferramenta. O runtime executa. O resultado volta para o contexto. O modelo decide de novo. Em dez passos, ele pode ter listado arquivos, lido um .env, chamado um endpoint interno e aberto um PR.
Nada disso exige má intenção do usuário. Basta um ticket com texto estranho, um README de terceiro, ou um comentário em issue que o agente "só ia resumir". O OWASP chama isso de prompt injection indireto: o conteúdo externo entra no contexto e altera o comportamento do modelo. No chat puro, o pior caso costuma ser uma resposta ruim. Com ferramentas, o pior caso é o agente usar as suas próprias permissões contra o seu sistema.
A pergunta útil não é "o modelo é seguro?". É: se o modelo escolher a ferramenta errada, ou a ferramenta certa com o parâmetro errado, o que ainda é possível?
O que muda em relação ao chat
No chat, o contrato é geração de texto. Você filtra saída, marca conteúdo sensível, e o dano fica em grande parte na confiança do usuário no que leu. No agente com ferramentas, o contrato é side effect. Delete, deploy, UPDATE, envio de e-mail, compra de crédito em nuvem. O modelo não precisa "escapar" do sandbox de texto. Ele só precisa de uma chamada de ferramenta autorizada demais.
Três mudanças práticas:
- A identidade deixa de ser a do usuário humano sozinho. O agente age com um service account, um token de API, um kubeconfig, ou o mesmo segredo que a aplicação usa. Se esse segredo for amplo, o agente herda amplitude.
- O contexto mistura fontes com níveis de confiança diferentes. Instrução do sistema, pedido do usuário, saída de ferramenta, página baixada, e-mail, linha de ticket. O modelo trata tudo como tokens. Não há boundary de confiança automática entre "mensagem do admin" e "anexo do cliente".
- O erro deixa de ser só alucinação verbal. O NIST AI 600-1 trata confabulação e riscos de segurança da informação como categorias distintas, mas no agente elas se encontram: o modelo inventa um caminho de arquivo ou um ID, e a ferramenta executa de verdade.
O OWASP Top 10 for LLM Applications 2025 elevou Excessive Agency (LLM06) exatamente por causa dessa mudança. O risco não depende só de o modelo ter sido "hackeado". Basta autonomia demais + ferramenta aberta demais + falha qualquer no raciocínio.
Superfície de ataque, sem teatro
Desenhe o diagrama mental em três camadas.
Entrada. Prompt direto do usuário. Injection indireto via conteúdo que o agente lê (web, repo, ticket, PDF, resposta de API). Metadados de ferramenta (descrições MCP/plugin) que o modelo vê e o humano quase nunca. O cheat sheet da OWASP sobre prompt injection trata saída de ferramenta e conteúdo remoto como não confiáveis, no mesmo espírito em que você trata input de formulário.
Decisão. O modelo escolhe ferramenta e argumentos. Aqui entram alucinação de parâmetro, confusão de escopo ("apague o cache" vira rm -rf), e chains em que uma observação forjada empurra a próxima ação. Autonomia excessiva sem gate humano em ações de alto impacto amplifica qualquer um desses erros.
Execução. Shell aberto, cliente HTTP genérico, SDK da nuvem com role admin, volume montado com o home do desenvolvedor, rede do cluster sem NetworkPolicy. A documentação do gVisor é explícita: container sozinho não é sandbox. Compartilhar o kernel do host significa que um escape de container continua sendo uma classe de risco real. A documentação de sandbox da OpenAI reforça o outro lado: código gerado pelo agente enxerga arquivos, credenciais e rede disponíveis no ambiente. Se o segredo está lá, o agente pode lê-lo.
Casos públicos úteis para calibrar o medo, sem sensacionalismo: pesquisadores mostraram que instruções escondidas em issue/ticket/página podem fazer um assistente com ferramentas privilegiadas extrair dados ou tomar ações que o usuário não pediu. O padrão se repete nos cenários do próprio OWASP LLM01. O vetor não é "IA maligna". É conteúdo não confiável + agente com poder demais.
Controles que importam de verdade
Sandbox: isolar a execução, não "confiar no prompt"
Se o agente gera ou executa código, trate o workload como não confiável. Isolamento em camadas:
- Processo / container com filesystem mínimo, usuário não-root, cgroups de CPU/memória/disco.
- Runtime mais forte quando o código é adverso ou gerado: gVisor (kernel em userspace que intercepta syscalls), ou microVM (Kata/Firecracker) quando você precisa de kernel separado. O gVisor reduz a superfície de System API do host; não substitui política de rede nem controle de segredos.
- Ambiente efêmero por tarefa ou por tenant. A OpenAI recomenda compute isolado e ambientes separados quando dados não devem se misturar. Warm pool ajuda a não pagar o custo de segurança em latência, mas o isolamento continua sendo o ponto.
Sandbox limita o que o código pode fazer no host. Não limita o que a credencial montada autoriza na API de produção. São eixos diferentes.
Credenciais: fora do alcance do modelo
Regra que eu uso: o modelo nunca vê o segredo longo. A ferramenta confiada injeta o segredo no momento da chamada, ou um proxy/broker troca um placeholder por header real só para hosts aprovados.
Consequências práticas:
- Chave da aplicação (orquestração, audit, vault) fora do sandbox. Chave do executor, se existir, com escopo mínimo e rotacionável.
- Sem
AWS_ACCESS_KEY_IDno env do container do agente "porque facilita o boto3". - Preferir credencial de curta duração (STS, workload identity, OAuth com escopo estreito) a chave estática.
- Montar volume com secret ainda expõe o secret ao código do agente. Broker > env var > arquivo no workspace.
O OWASP LLM01 recomenda exatamente isso em mitigação: tokens da aplicação nas funções da aplicação, não entregues ao modelo; privilégio mínimo para a operação pretendida.
Menor privilégio: IAM e allowlist de ferramentas
Least privilege aqui tem duas faces.
Face IAM. Role do agente ≠ role do humano admin ≠ role da app monólito. Se o agente só precisa ler orders e criar issue no tracker, a policy para aí. O NIST SP 800-207 (Zero Trust) formula o princípio de forma útil para agentes: autenticação e autorização por sessão/pedido, com o mínimo de privilégio necessário para aquela ação, sem confiança implícita porque "já está na VPC".
Face ferramentas. O LLM06 é direto: minimize extensões; evite extensões abertas (run_shell, fetch_url genérico) quando dá para oferecer uma função estreita (write_report_file, get_order_by_id). Allowlist por agente, por ambiente e, se possível, por usuário. "Todas as tools do catálogo" é o equivalente a SELECT * com user postgres.
Ações irreversíveis ou caras (drop, deploy prod, refund, envio em massa) pedem human-in-the-loop. Não como teatro de UX: como gate no runtime que rejeita a tool call sem aprovação, mesmo que o modelo "tenha certeza".
Isolamento de rede
Sandbox sem egress control ainda fala com o metadata service da nuvem, com o banco interno, com o webhook do atacante. Controles concretos:
- Allowlist de egress (DNS e IP) para o que a tarefa precisa.
- Bloquear acesso a link-local / IMDS quando o agente não precisa assumir role pela instância.
- Separar rede do sandbox da rede de produção: o agente fala com um gateway seu; o gateway fala com produção com política própria.
- Em Kubernetes, NetworkPolicy não é opcional se o pod executa código do modelo.
O gVisor deixa claro que política de rede continua sendo responsabilidade do orquestrador. O sandbox não configura isso por você.
Orçamento de tokens, tempo e chamadas
Agente sem teto entra em loop, gasta API, martela endpoint, ou tenta a mesma mutação até dar certo do jeito errado. Defina:
- máximo de passos (tool calls) por sessão;
- timeout wall-clock por run;
- rate limit por ferramenta e por identidade;
- circuit breaker: N falhas ou N ações de alto impacto e o run morre;
- teto de custo (tokens + chamadas externas).
Isso não é otimização financeira só. É contenção de blast radius quando o modelo decide "tentar de outro jeito" cinquenta vezes.
Logs e auditoria: o que precisa existir depois do incidente
Se você não consegue responder "quem/o quê autorizou qual tool call com quais argumentos", você não tem agente em produção. Tem um processo opaco com side effects.
O mínimo útil:
- Identidade do agente (não só "o bot"): versão do prompt/system, modelo, ambiente, tenant, usuário solicitante.
- Cada tool call: nome, argumentos (com redaction de segredo), resultado resumido, latência, decisão (permitido / negado / aguardando aprovação).
- Cadeia de contexto: hash ou id do conteúdo externo que entrou no prompt (issue, URL, arquivo), para investigar injection indireto.
- Aprovação humana: quem aprovou, o quê, quando.
- Imutabilidade razoável: log em sistema que o próprio agente não pode apagar com a mesma credencial.
O NIST AI 600-1 enfatiza inventário de sistemas de IA, papéis de supervisão humana e monitoramento pós-deploy. Em agente com ferramentas, inventário significa: lista de tools, destinos de rede, roles IAM e owners. Sem isso, o checklist de segurança vira slide.
Log demais também vaza. Redacte token, cookie, corpo de resposta com PII. Guarde argumento bruto só onde a política de retenção e acesso forem explícitos.
Checklist de produção
Antes de apontar o agente para algo que dói se der errado:
- O agente tem identidade própria no IAM; não reutiliza a role admin da equipe.
- Cada ferramenta é necessária; shell/URL genéricos estão justificados ou foram substituídos por funções estreitas.
- Credenciais longas ficam fora do sandbox; broker ou handler da ferramenta injeta o segredo.
- Egress é allowlist; IMDS e redes internas sensíveis estão bloqueados por padrão.
- Sandbox isola filesystem e, se executa código gerado, usa runtime reforçado (gVisor/microVM) além de container.
- Há teto de passos, tempo, rate limit e circuit breaker.
- Ações de alto impacto exigem aprovação humana no runtime, não só "por favor não faça isso" no system prompt.
- Tool output e conteúdo externo são tratados como não confiáveis na reentrada do contexto.
- Audit log cobre tool calls, negações e aprovações; o agente não pode apagar o próprio rastro.
- Existe kill switch: revogar credencial, derrubar o runner, desligar a allowlist sem redeploy heroico.
- Ambiente de staging com as mesmas guardas, e teste adversário (injection indireto em ticket/README) faz parte do release.
System prompt ajuda a orientar. Não é controle. Controle é o que o runtime recusa mesmo quando o modelo insiste.
O ponto em que vale parar
Agente com acesso a sistemas reais é útil quando o efeito colateral está contido e observável. É má ideia quando a primeira versão já tem kubectl, billing da nuvem e o mesmo token do CI. Comece estreito: uma ferramenta, um destino, um ambiente, logs ligadas. Amplie privilégio só com evidência de que as guardas aguentam o caso feio, não só o demo feliz.
O chat responde. O agente age. A engenharia boa trata a segunda frase com o mesmo rigor que você já trata um worker com credencial de produção.
Se o seu agente pudesse executar uma única ferramenta amanhã, qual você escolheria — e qual privilégio ela não precisaria ter?
Referências
- OWASP Top 10 for LLM Applications 2025 (PDF) — LLM06:2025 Excessive Agency (minimizar extensões, evitar tools abertas, menor privilégio, human-in-the-loop, rate limiting). Versão web equivalente: LLM08 Excessive Agency (2023/24).
- OWASP LLM01:2025 Prompt Injection — injection direto e indireto; impacto sobe com a agência do sistema.
- OWASP Cheat Sheet: LLM Prompt Injection Prevention — validação de tool calls, least privilege, dual-LLM / segregação de conteúdo não confiável.
- gVisor Security Model — containers não são sandbox; redução da superfície de System API; rede e cgroups continuam no host/orquestrador.
- OpenAI: Sandbox security — isolamento de workload, restrição de rede, separação de credenciais e broker para segredos de terceiros.
- NIST AI 600-1: Generative AI Profile — perfil do AI RMF para GenAI: inventário, supervisão humana, monitoramento e riscos de segurança da informação.
- NIST SP 800-207: Zero Trust Architecture — menor privilégio por sessão/pedido e redução de zonas de confiança implícita (aplicável a identidades de agente).
- GKE / Agent Sandbox com gVisor — isolamento de kernel para código de agente + NetworkPolicy para egress.