MÓDULO 3.2

🛡️ Sandbox, file system e segurança

Os três modos de sandbox revisitados sob a lente de risco real. Isolamento, quotas, leitura guiada do SECURITY.md e os alertas de deploy que todo time precisa conhecer antes de pôr um agente em produção.

5
Tópicos
55
Minutos
Avançado
Nível
Prático
Tipo

💡 Como ler este módulo

Na Trilha 1 você viu os três modos de sandbox em termos de conveniência. Aqui trocamos a lente: para cada modo, o que acontece se a tool executar código hostil? Se a resposta for "o host cai", o modo não serve para produção. Sandbox é a última barreira — se ela falhar, tudo depois falha.

1

🔒 Local / Docker / K8s revisitados sob lente de risco

Os três modos já são conhecidos; o que muda aqui é o eixo de comparação. Em vez de "qual roda mais rápido", a pergunta é "o que um código hostil consegue fazer em cada um?". A resposta determina onde cada modo pode viver.

Local

Risco: máximo

  • • Acesso completo ao FS do host
  • • Pode ler ~/.ssh, .env, keychain
  • • Exfiltração via rede sem trava
  • • Uso: apenas máquina descartável de dev

Docker

Risco: médio

  • • Namespace isolado; host protegido
  • • Egress de rede aberto por padrão
  • • Escape via docker.sock se montado (não monte)
  • • Uso: dev equipe, produção pequena

K8s

Risco: controlado

  • • NetworkPolicy restringe egress
  • • PSA + seccomp + AppArmor compondo
  • • Quotas hard por namespace
  • • Uso: multi-tenant, produção

🎯 O modelo de ameaça que importa

O agente não precisa ser comprometido por um atacante externo. Basta prompt injection — um documento que o agente lê em contexto e que reescreve o objetivo dele. Nesse momento, qualquer tool que executa código passa a ser código do atacante. A sandbox existe para assumir que isso vai acontecer e limitar o dano.

2

🚧 Isolamento, quotas e imagem

"Docker já isola" é só metade da verdade. O container bloqueia acesso ao FS do host, mas não limita CPU, memória, egress ou pacotes instalados por padrão. É preciso configurar explicitamente. No modo K8s do DeerFlow, esses controles são primeira-classe via policies do Pod.

🎯 Conceito Central — as 4 camadas

  • 1. Recursos— CPU, memória, disco, tempo máximo. Sem isso, um loop infinito derruba o node.
  • 2. Rede— NetworkPolicy com egress allow-list. Sem isso, o Pod pode exfiltrar para qualquer lugar.
  • 3. Filesystem— volumes read-only, /tmp efêmero, nada de hostPath. Sem isso, persistência entre execuções vaza dados.
  • 4. Imagem— base mínima (distroless ou alpine), sem pip install livre. Sem isso, qualquer pip install requests_evil vira backdoor.

Exemplo: PodSpec mínimo para sandbox DeerFlow

apiVersion: v1
kind: Pod
metadata: { name: deerflow-sandbox }
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 65532
    seccompProfile: { type: RuntimeDefault }
  containers:
    - name: sandbox
      image: deerflow/sandbox:2.3.0-distroless
      resources:
        limits: { cpu: "1", memory: "2Gi", ephemeral-storage: "512Mi" }
        requests: { cpu: "200m", memory: "512Mi" }
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities: { drop: ["ALL"] }
      volumeMounts:
        - { name: scratch, mountPath: /tmp }
  volumes:
    - name: scratch
      emptyDir: { sizeLimit: "256Mi", medium: Memory }

💡 Dica prática

Não fique tentado a dar NET_ADMIN ou SYS_PTRACE "só para debugar". Se precisar, crie um namespace K8s "dev" separado do "prod" e deixe claro que é descartável. Capabilities não voltam para a caixa depois que um incidente acontece.

3

📄 Leitura guiada de SECURITY.md

O arquivo SECURITY.md do repositório é o documento mais autoritativo do projeto sobre risco. A maioria dos usuários nunca o abre. Esta seção faz o passeio: o que está lá, o que não está, e por que cada recomendação existe.

1

Threat model explícito

O que o DeerFlow assume que pode acontecer — e o que diz estar fora de escopo

Lista ameaças cobertas (prompt injection, tool misuse, secret exposure em logs) e deixa fora (atacante com acesso físico ao host). Saber o que não é problema do projeto é tão importante quanto saber o que é.

2

Supported versions

Quais minor releases recebem patch — e por quanto tempo

Fica a regra prática: versões n e n-1 recebem fixes; qualquer coisa mais antiga é "upgrade". Conflita frontalmente com "mantemos um fork estável da v2.0 por 3 anos".

3

Canal de reporte

Private disclosure, PGP, SLA de resposta

Endereço oficial (security@), chave PGP pública e o compromisso de primeira resposta em até 72h. Issue público não é lugar para CVE — o SECURITY.md fala isso em negrito.

4

Recomendações de deploy

Lista mínima do que precisa estar ligado em prod

TLS, auth obrigatória no API gateway, sandbox Docker ou K8s (nunca Local), secrets via gerenciador (não .env no repo), logs sem PII. Cada bullet vira um item de checklist antes de go-live.

4

⚠️ Alertas de deploy — o que o README adverte

O README do DeerFlow tem uma seção curta e explícita sobre o que não fazer em deploy. É uma lista de armadilhas que parecem pequenas em dev e viram incidentes em produção. Elas se repetem porque ninguém lê.

🚨 As 6 armadilhas clássicas

  • 1.Sandbox: local em produção. "Só enquanto resolvemos o Docker." Nunca é só. Vira default e o incidente chega em 3 meses.
  • 2.API gateway sem autenticação. Conveniente em staging, catastrófico em prod. Qualquer um que ache a URL ganha um agente com suas credenciais.
  • 3.Secrets no prompt do sistema. Ficam no histórico, vão para logs, vão para traces, vão para memória. Use injeção via tool, nunca via prompt.
  • 4.Tool irrestrita (curl, bash, fs.write). Qualquer uma que execute comando arbitrário precisa estar atrás de allow-list e com input validado.
  • 5.Logs com PII. Mensagens de usuário gravadas íntegras em Elasticsearch com retenção infinita. LGPD manda lembrança.
  • 6.Docker socket montado. "O agente precisa iniciar containers." Não precisa — você precisa de uma interface mediada. Docker socket = root no host.

💡 Checklist antes de go-live

Imprima as 6 armadilhas, cole no Jira, peça que um humano dê OK em cada uma antes do deploy. Não delegue para o agente decidir se ele próprio está seguro — ele sempre vai dizer que sim.

5

🧪 Lab: deploy K8s com provisioner + script malicioso

Testar sandbox com hostil-de-mentira é a única forma honesta de saber se ela aguenta hostil-de-verdade. Você vai subir um DeerFlow em K8s no modo sandbox-provisioner, injetar um script intencionalmente malicioso e validar que (a) o script falha, (b) o incidente aparece nos logs, (c) o agente continua vivo e responde sobre o erro.

1

Suba um cluster descartável

kind, k3d ou minikube bastam. Crie namespace deerflow-test e aplique o manifest oficial do DeerFlow em modo K8s-provisioner, com o PodSpec restritivo visto no tópico 2.

2

Prepare 3 scripts de teste

A) curl http://169.254.169.254/ — tenta acessar metadata do cloud. B) dd if=/dev/zero of=/tmp/fill bs=1M — tenta esgotar disco. C) while true: pass — tenta loop infinito. Cada um mira uma camada diferente (rede, disco, CPU).

3

Acione via skill de análise

Use a skill data-analysis passando um CSV bobo e instruindo "execute o código anexo no preprocessamento". O código anexo é um dos scripts do passo 2. Rode uma vez para cada script.

4

Observe resultado esperado

A: NetworkPolicy bloqueia, curl: (7) Couldn't connect. B: ephemeral-storage limit corta em 256Mi, Pod evicted. C: CPU limit 1 core estrangula e timeout da tool dispara. Nos 3 casos, o agente segue vivo e reporta o erro na conversa.

5

Colete evidências

Screenshots dos logs (kubectl logs), dos eventos (kubectl get events) e do trace do DeerFlow mostrando o erro retornado. Anexe ao doc do lab — serve como post-mortem-mock para treinar o time em incidente real.

⚠️ Se algum teste passar quando não deveria

Pare o lab. Sua config de K8s não está aplicando os limits. Revise securityContext, resources.limits e NetworkPolicy. Um deploy que deixa o script A funcionar em laboratório vai deixar um exfiltrador funcionar em produção.

📝 Resumo do Módulo

Local, Docker, K8s é escada de risco — cada degrau assume que o de baixo falha. Em produção, só K8s passa no teste de ameaça honesto.
Docker sem quotas é Local com passo extra — namespace isola FS do host, mas CPU, rede, disco e pacotes continuam abertos sem config explícita.
As 4 camadas: recursos, rede, FS, imagem — todas precisam estar fechadas. Fechar só 3 não vale nada — o atacante usa a aberta.
SECURITY.md é leitura obrigatória — threat model, supported versions, canal de reporte e recomendações de deploy. Vire-se pelo link que ele aponta.
6 armadilhas clássicas de deploy — Local em prod, API sem auth, secrets no prompt, tool irrestrita, logs com PII, docker socket. Checklist antes de cada go-live.
Sandbox só é sandbox se você testa — o lab dos 3 scripts hostis é o único jeito honesto de saber que os limits funcionam.

Próximo Módulo:

3.3 — 💾 Memória avançada e context engineering

Do "existe memória" do módulo 1.1 para compactação, recall semântico e memory poisoning.