Como avaliar o isolamento de agentes de IA no Kubernetes
Um agente que analisa um repositório, executa testes e publica um diagnóstico precisa de ferramentas. A decisão importante não é apenas onde executar essas ferramentas, mas quais consequências serão possíveis se o código executado deixar de ser confiável.
Para esta avaliação, adote uma premissa conservadora: o processo do agente pode ser comprometido e tentar usar todas as permissões disponíveis. O objetivo não é testar se o modelo segue instruções, e sim verificar se a infraestrutura impede ações fora do contrato autorizado.
Este artigo propõe um protocolo de avaliação: modelo de ameaças, testes positivos e negativos, coleta independente de evidências e critérios de aprovação. A implementação da conectividade fica no artigo sobre rede para sandboxes de agentes de IA; o ciclo de criação e descarte é tratado em sandboxes efêmeros no Kubernetes.
1. O que significa isolamento verificável
Isolamento é a separação entre domínios de confiança. No Kubernetes, um namespace oferece escopo administrativo, mas não constitui sozinho uma fronteira completa para executar código hostil. Recursos do nó e componentes do cluster continuam fazendo parte do modelo de compartilhamento. (kubernetes.io)
Para tornar a avaliação objetiva, defina seis perguntas:
- Execução: qual fronteira separa o processo do agente do host?
- Identidade: quais APIs e recursos suas credenciais autorizam?
- Rede: quais destinos e operações ele consegue alcançar?
- Dados: quais informações consegue ler, alterar ou deixar para outra execução?
- Recursos: quanto consegue consumir antes de ser contido?
- Ciclo de vida: o que permanece acessível depois do encerramento?
Não aceite uma resposta única como “usa sandbox”. Cada dimensão precisa de uma hipótese verificável, um teste e uma evidência.
Escopo e limitações
Declare se a avaliação inclui apenas o comprometimento do processo ou também administradores maliciosos, comprometimento do nó e ataques entre clientes mutuamente desconfiados. Não apresente um teste de permissões como prova contra vulnerabilidades desconhecidas do kernel.
Neste protocolo, administradores da plataforma e o coletor externo são confiáveis. O agente, seus subprocessos, dependências e arquivos recebidos não são.
2. Arquitetura de referência para a avaliação
Use o seguinte desenho como proposta de arquitetura, não como requisito de um produto específico:
Solicitação → API de orquestração → autorização → fila → executor isolado → broker de ferramentas → serviço autorizado
Em paralelo:
API do Kubernetes + runtime + rede + broker → coletor externo → relatório de evidências
Separe três responsabilidades:
- Orquestrador: aceita solicitações e cria execuções com um template aprovado.
- Executor: processa conteúdo não confiável, sem administrar o cluster.
- Broker de ferramentas: valida identidade, tenant, ação e recurso antes de acessar sistemas corporativos.
Não coloque credenciais administrativas no executor para facilitar a criação do próprio ambiente. O Kubernetes alerta que permissões para criar workloads podem permitir acesso indireto a Secrets e às permissões de outras ServiceAccounts do namespace. (kubernetes.io)
O relatório principal deve ser produzido fora do domínio avaliado. Saídas do agente podem complementar a análise, mas não devem ser a única prova de que ele permaneceu isolado.
3. Compare fronteiras, não nomes de produtos
| Alternativa | Fronteira relevante | Principal trade-off a avaliar |
|---|---|---|
| Contêiner convencional endurecido | Namespaces Linux, controles do kernel e configuração do runtime | Compatibilidade versus compartilhamento do kernel |
| gVisor | Kernel de aplicação que intercepta chamadas do workload | Compatibilidade de chamadas de sistema e comportamento de I/O |
| Kata Containers | Virtualização com kernel convidado | Capacidade, inicialização e operação da camada virtualizada |
| Nós dedicados | Separação de co-residência | Capacidade ociosa; não substitui isolamento de identidade |
| Cluster separado | Separação também do plano de controle Kubernetes | Custo operacional e governança de múltiplos clusters |
Essas alternativas têm fronteiras diferentes; não representam níveis universalmente intercambiáveis de segurança. gVisor e Kata documentam arquiteturas distintas, enquanto a documentação de multitenancy descreve os compromissos de isolamento no Kubernetes. (gvisor.dev)
RuntimeClass seleciona uma configuração de runtime previamente instalada. Criar o objeto ou preencher runtimeClassName não instala o runtime nos nós. Verifique a classe solicitada e a execução efetiva por evidências do runtime ou do serviço gerenciado. (kubernetes.io)
Se a classe exigida estiver indisponível, o critério proposto é falhar de forma fechada: não executar a tarefa. Não aceite um fallback implementado pelo orquestrador para uma classe menos isolada.
4. Prepare uma campanha reproduzível
Execute os testes em ambiente autorizado, com dados sintéticos e limites definidos. Testes de saturação pertencem a um ambiente segregado; não execute exploração de kernel ou cargas destrutivas em nós compartilhados de produção.
Registre:
- versões de Kubernetes, sistema operacional, kernel, runtime e plugin de rede;
- digest da imagem, arquitetura de CPU e template do executor;
- RuntimeClass, políticas de admissão e configuração de identidade;
- tenant, identificador da execução e janela de coleta;
- destinos permitidos, destinos proibidos e critérios esperados;
- responsável, prazo e justificativa para qualquer exceção.
Use quatro resultados: aprovado, reprovado, inconclusivo e não aplicável com justificativa. Uma falha da ferramenta de teste é inconclusiva, não uma aprovação.
Cada teste negativo deve ter um controle positivo. Se uma chamada proibida falha, mas nenhuma chamada permitida funciona, você ainda não demonstrou que a política correta causou a falha.
5. Matriz mínima de testes
A tabela abaixo é uma proposta de contrato de avaliação. Ajuste o resultado esperado ao perfil autorizado do agente.
| Dimensão | Tentativa controlada | Resultado esperado | Evidência independente |
|---|---|---|---|
| Admissão | Alterar um template válido para solicitar privilégio | Rejeição pelo controle esperado | Resposta da API e registro de auditoria |
| Runtime | Solicitar a classe aprovada | Execução nessa classe, sem fallback | Configuração do nó e registros do runtime |
| Identidade | Consultar um Secret sintético de outro tenant | Negação de autorização | Auditoria da API |
| Rede | Acessar um serviço-canário proibido | Bloqueio na camada definida | Telemetria de rede e logs do destino |
| Ferramentas | Solicitar objeto de outro tenant pelo broker | Negação na aplicação | Log de autorização do broker |
| Persistência | Procurar marcador de uma execução anterior | Marcador inacessível | Inspeção controlada da nova execução |
| Recursos | Atingir o orçamento de admissão | Novas solicitações rejeitadas | Status da quota e eventos |
| Encerramento | Reutilizar uma credencial da tarefa encerrada | Rejeição conforme política de revogação ou expiração | Log do serviço de identidade |
Não faça média entre esses resultados. Uma leitura entre tenants não pode ser compensada por boa latência ou baixo custo.
6. Admissão e identidade: teste quem pode fazer o quê
Pod Security Admission pode aplicar o perfil Restricted por namespace. Os modos warn e audit não equivalem a enforce. Além disso, o perfil não substitui controles de rede, autorização de negócio ou uma política que obrigue determinada RuntimeClass. (kubernetes.io)
Para testar admissão, mantenha um Pod-base válido no repositório de testes. Gere uma cópia por mutação: privileged: true, hostPID: true, volume hostPath ou retirada da classe exigida. Faça uma alteração por vez e confirme que a mensagem de rejeição corresponde ao controle avaliado, não a um erro de sintaxe ou a outra restrição.
Para controle de acesso baseado em papéis, ou RBAC, comece pela identidade do executor. O exemplo assume namespace agent-eval e ServiceAccount agent-worker, ambos previamente criados:
NS=agent-eval
SA=agent-worker
kubectl auth can-i get secrets -n "$NS" \
--as="system:serviceaccount:${NS}:${SA}" \
--as-group=system:serviceaccounts \
--as-group="system:serviceaccounts:${NS}" \
--as-group=system:authenticated
kubectl auth can-i create pods -n "$NS" \
--as="system:serviceaccount:${NS}:${SA}" \
--as-group=system:serviceaccounts \
--as-group="system:serviceaccounts:${NS}" \
--as-group=system:authenticatedO operador precisa de autorização para impersonar usuário e grupos. Para o perfil proposto, espere no nas duas consultas. Isso consulta autorização Kubernetes; não prova bloqueio de rede, indisponibilidade de credenciais ou negação em APIs cloud. Complete com testes sobre recursos sintéticos usando a identidade efetiva. (kubernetes.io)
Quando o executor não precisa da API Kubernetes, desabilite a montagem automática do token. Ainda assim, inspecione volumes projetados, variáveis e mecanismos de identidade externos: automountServiceAccountToken: false não é uma política geral de remoção de credenciais. (kubernetes.io)
No Amazon EKS, avalie separadamente as permissões do AWS Identity and Access Management, ou IAM. EKS Pod Identity associa uma role a uma ServiceAccount, mas não transforma contêineres em fronteiras de segurança. Verifique também se o acesso ao serviço de metadados da instância permite alcançar credenciais do nó. (docs.aws.amazon.com)
7. Verificação prática dentro do executor
Em um executor de avaliação com shell POSIX, id, test e mktemp, execute a verificação abaixo. Substitua o nome do Pod e do contêiner. O contrato deste exemplo exige usuário não root, ausência do token padrão e diretório /tmp gravável:
NS=agent-eval
POD=replace-with-evaluation-pod
CONTAINER=worker
kubectl exec -i -n "$NS" "$POD" -c "$CONTAINER" -- sh -s <<'SH'
set -eu
if [ "$(id -u)" -eq 0 ]; then
echo 'FAIL: root user'
exit 1
fi
if [ -e /var/run/secrets/kubernetes.io/serviceaccount/token ]; then
echo 'FAIL: default Kubernetes token is mounted'
exit 1
fi
probe=$(mktemp /tmp/isolation-probe.XXXXXX)
rm -f "$probe"
echo 'PASS: non-root, default token absent, temporary directory writable'
SHEsse script verifica somente três condições locais. Não demonstra ausência de todos os tokens, filesystem raiz somente leitura, isolamento do kernel ou impossibilidade de escape. A opção runAsNonRoot e os controles do perfil Restricted devem ser confrontados com o Pod admitido, não apenas com o template original. (kubernetes.io)
Se a imagem não possui shell, use um binário de teste previamente revisado. Não altere a imagem de produção nem introduza um contêiner privilegiado para fazer a avaliação “passar”.
8. YAML completo: orçamento do namespace de avaliação
O manifesto abaixo complementa a campanha com um orçamento de admissão. Ele não cria uma sandbox nem implementa isolamento de rede. Aplique somente em um namespace de avaliação existente e dedicado:
apiVersion: v1
kind: ResourceQuota
metadata:
name: isolation-evaluation-budget
namespace: agent-eval
spec:
hard:
pods: "8"
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
requests.ephemeral-storage: 8Gi
limits.ephemeral-storage: 16Gi
count/jobs.batch: "16"
persistentvolumeclaims: "0"
count/services: "0"requests.* e limits.* restringem os totais declarados sujeitos à quota. pods limita Pods não terminados; count/jobs.batch limita objetos Job, inclusive os que permanecem após terminar. Os zeros impedem novas PVCs, ou PersistentVolumeClaims, e Services nesse namespace. Eles não impedem acesso a armazenamento externo pela rede. (kubernetes.io)
Os valores são didáticos, não dimensionamento recomendado. Adapte-os à concorrência, aos sidecars e ao overhead do runtime. Valide também o descarte de Jobs antigos para que o limite de objetos não interrompa novas avaliações.
kubectl apply -f evaluation-quota.yaml
kubectl describe resourcequota isolation-evaluation-budget -n agent-eval
kubectl get events -n agent-eval --sort-by=.metadata.creationTimestampQuota não limita diretamente todo consumo do processo. Requests influenciam agendamento; limites de CPU e memória têm mecanismos distintos de aplicação. Avalie consumo real, throttling e encerramentos por falta de memória separadamente. (kubernetes.io)
Para testar a quota, submeta workloads inofensivos com recursos declarados até atingir o orçamento. Não use uma carga destrutiva para comprovar uma regra de admissão.
9. Rede e dados: diferencie bloqueio de indisponibilidade
NetworkPolicy depende de implementação compatível no plugin de rede. As permissões de políticas aplicáveis se combinam; uma política adicional pode ampliar conectividade. A API padrão não oferece autorização HTTP nem validação de identidade de negócio. (kubernetes.io)
Sem repetir os manifestos do artigo de rede, proponha estes testes:
- chamada permitida ao broker com certificado TLS válido;
- chamada a destino proibido por nome e por IP;
- acesso direto ao destino, contornando o proxy;
- cobertura de IPv4 e IPv6, quando ambos estiverem habilitados;
- uso do broker permitido para solicitar recurso de outro tenant;
- comportamento durante indisponibilidade do componente de autorização.
Não classifique um timeout isolado como prova de isolamento. Correlacione origem, destino, instante e mecanismo esperado. Diferencie bloqueio de rede, falha de resolução, recusa de conexão, erro TLS e negação de autorização.
Para persistência, grave um marcador sintético único na execução A e procure-o na execução B. Inclua workspace, cache, artefatos, checkpoints e armazenamento externo. Excluir o Pod não comprova exclusão de um volume persistente: a recuperação de volumes depende de sua política e do provisionamento utilizado. (kubernetes.io)
Defina também testes para rotação de credenciais, escopo de chaves e autorização sobre backups. Criptografar armazenamento não substitui separar permissões de leitura entre tenants.
10. Exemplo corporativo: análise de pull requests
Problema: uma plataforma recebe pull requests externos e executa testes para produzir um diagnóstico. O código recebido não deve herdar credenciais da automação corporativa.
Solução proposta: separar o executor do broker que publica comentários, com uma identidade limitada ao repositório e à operação autorizados.
Implementação da avaliação: usar dois tenants sintéticos, um repositório permitido e outro proibido. Executar a matriz com a mesma imagem e configuração de runtime previstas para produção. Confirmar publicação permitida, negação no segundo repositório, ausência de credenciais administrativas e descarte dos artefatos temporários.
Resultado esperado: liberar o perfil somente quando os limites estiverem demonstrados por evidências. Não se trata de um benchmark ou caso real com ganhos medidos.
Uma falha no teste entre tenants deve bloquear a publicação do perfil, mesmo que os testes funcionais da análise de código estejam corretos.
11. Produção: disponibilidade sem enfraquecer a fronteira
Como desenho operacional, distribua API, broker e consumidores da fila por múltiplas zonas, com réplicas, health checks e capacidade mínima. Uma execução isolada não precisa de múltiplas réplicas simultâneas: disponibilidade da plataforma e repetição da mesma tarefa são decisões diferentes.
Use readiness para controlar recebimento de tráfego, startup para inicialização demorada e liveness apenas quando o reinício for uma recuperação apropriada. Para tarefas finitas, considere deadlines e política de retry de Jobs; não replique automaticamente uma operação externa não idempotente. (kubernetes.io)
Minha recomendação de recuperação é persistir somente checkpoints autorizados, adotar chaves de idempotência no broker e testar interrupção de nó, duplicação de entrega e retomada. Inclua restauração do estado da fila e dos metadados da plataforma no plano de backup.
Para upgrades, execute a mesma suíte antes e depois de alterar kernel, runtime, imagem ou plugin de rede. Faça canário com tráfego sintético antes da expansão. O rollback deve retornar a um perfil ainda aprovado; nunca remover a sandbox ou liberar egress indiscriminadamente para recuperar disponibilidade.
12. Observabilidade e evidências
Métricas, logs e traces atendem a perguntas diferentes. A auditoria Kubernetes registra operações da API conforme a política configurada; não substitui a observação do que ocorre dentro dos processos. (kubernetes.io)
Como instrumentação proposta, acompanhe:
- latência de provisionamento e idade da fila;
- throughput, erro e latência das chamadas ao broker;
- CPU, memória, armazenamento efêmero e reinicializações;
- rejeições de admissão e tentativas de autorização negadas;
- runtime efetivo divergente do aprovado;
- tempo entre encerramento da tarefa e invalidação de acessos;
- custo por tarefa concluída, incluindo retries.
Prometheus e Grafana podem compor a camada de métricas; escolha logs e tracing conforme o padrão da organização. Preserve identificadores detalhados em logs e traces, evitando uma série de métricas por execução.
Não registre tokens, conteúdo de Secrets ou documentos sensíveis para produzir evidência. Armazene relatórios fora do namespace do executor, com controle de acesso, retenção e integridade verificáveis.
13. Troubleshooting orientado por hipótese
Use os comandos abaixo como coleta inicial, com os nomes reais do ambiente:
kubectl get pods -n agent-eval -o wide
kubectl describe pod "$POD" -n agent-eval
kubectl logs "$POD" -n agent-eval -c worker
kubectl logs "$POD" -n agent-eval -c worker --previous
kubectl get runtimeclass
kubectl get resourcequota -n agent-eval
kubectl get events -n agent-eval --sort-by=.metadata.creationTimestamp--previous só ajuda quando existe uma instância anterior do contêiner com logs disponíveis.
| Sintoma | Possível causa | Investigação | Correção proposta |
|---|---|---|---|
| Pod não inicia | Handler de runtime ausente ou nós incompatíveis | Eventos, RuntimeClass e configuração do runtime | Corrigir o pool; não remover a classe exigida |
| Criação rejeitada | Quota esgotada ou recurso não declarado | Mensagem da API e uso da quota | Ajustar orçamento ou descarte após revisão |
| Destino proibido responde | Política permissiva adicional ou cobertura inadequada | Políticas selecionadas e telemetria do caminho | Corrigir a política e repetir controles positivos |
| API cloud acessível inesperadamente | Identidade injetada ou acesso a credenciais do nó | Associações IAM e origem efetiva da credencial | Restringir identidade e acesso ao metadata service |
| Marcador reaparece | Cache, volume ou artefato reutilizado | Rastrear identificador até o armazenamento | Corrigir separação e descarte |
As hipóteses de runtime, quota, rede e identidade devem ser confrontadas com os mecanismos documentados, não resolvidas pela ampliação indiscriminada de permissões. (kubernetes.io)
14. Desenvolvimento, custos e critérios de adoção
Em desenvolvimento, aceite menor redundância e uma suíte reduzida com dados sintéticos. Preserve, porém, o contrato de identidade e admissão: um ambiente com cluster-admin não valida o perfil restrito de produção.
Em produção, minha proposta é exigir o relatório completo, alertas, capacidade de recuperação, rollback ensaiado e reavaliação após mudanças relevantes.
Para FinOps, compare o custo total por tarefa concluída: computação, inicialização, capacidade ociosa, rede, armazenamento e observabilidade. Meça o overhead de cada runtime com suas próprias cargas; não presuma equivalência de desempenho. Inclua overhead declarado da RuntimeClass no planejamento de capacidade. (kubernetes.io)
Considere Spot apenas para tarefas interrompíveis e recuperáveis. Mantenha capacidade estável para componentes críticos quando o objetivo de disponibilidade exigir. Dimensione concorrência pela idade da fila e pelo orçamento de cada tenant, não apenas pela CPU média.
Use esta avaliação completa quando houver execução de código externo, acesso a dados sensíveis, múltiplos tenants ou exigência de evidências de compliance. Para um agente sem execução de código e com uma única ferramenta estritamente autorizada, uma avaliação menor pode ser suficiente; não elimine a revisão de identidade e dados.
Se a equipe não consegue operar runtimes adicionais com segurança, considere um serviço gerenciado de execução isolada ou ambientes separados. Avalie custo, observabilidade, portabilidade e dependência do fornecedor antes da escolha.
15. Resumo prático e conclusão
Antes de aprovar um perfil de execução, confirme:
- modelo de ameaças e exclusões documentados;
- runtime solicitado e efetivo coerentes;
- testes positivos e negativos para identidade, rede e dados;
- recursos e concorrência com orçamento explícito;
- credenciais e persistência avaliadas após o encerramento;
- evidências externas ao executor;
- falhas críticas bloqueando a promoção;
- upgrade, rollback e recuperação ensaiados.
Evite confundir namespace com sandbox, warn com bloqueio, timeout com prova ou YAML correto com comportamento confirmado.
Em DevOps e Platform Engineering, o resultado deve ser um perfil versionado e reproduzível. Em SRE, ele precisa continuar válido durante falhas, saturação e manutenção. Avaliar isolamento é transformar uma promessa de arquitetura em um conjunto explícito de propriedades que a equipe consegue testar, observar e sustentar.
Artigos relacionados
Quer aplicar isso no seu ambiente?
Agende uma conversa de 30 minutos sem compromisso. Eu olho o seu cenário e digo por onde começar.
Agendar uma conversaReceba os novos artigos por e-mail
Um e-mail quando sair artigo novo sobre infraestrutura, backend e IA. Sem spam, cancele quando quiser.