Segurança do Loop Autônomo|INEMA.CLUB-PRO

Aula 7 · 20 min

Irreversível pede humano; rodar fora do terminal sem aumentar o raio de dano

Enviar, publicar, apagar e gastar não têm volta. No loop, essas ações viram pedidos que esperam numa porta que só você abre, vendo destino e conteúdo. E quando o loop sai do terminal para o systemd, ele leva junto o teto, o sandbox e a porta, não a sua sessão inteira.

Começar a aula
Duas chaves metálicas em duas fechaduras separadas num painel de cofre industrial.

Nesta aula você vai

  1. 1porta.py: pedir, aprovar com hash, executar uma vez
  2. 2Uma política real de ação irreversível, anonimizada
  3. 3systemd com teto de tempo e memória e o sandbox do Codex dentro
  4. 4Routines na nuvem: o mesmo cuidado, sem confirmação de detalhes

Objetivo: pôr envio, push e apagar atrás de uma porta que só o humano abre e rodar o loop no systemd com teto e sandbox.

01A porta do irreversível

Clique em cada etapa.

Clique em cada bloco do diagrama para ver o que ele faz.

É o N1 da POLITICA (aula 4): o agente prepara, o humano executa.

02Veja a fila parar na porta

Ciclo noturno do loop. A ação de envio é irreversível: na primeira execução ela para e espera. Aprove (retomar) e ela segue.

na fila

rodando

feito

esperando humano

Simulação ilustrativa. A porta de verdade está no ensaio logo abaixo.

03Ensaio: a porta do começo ao fim

Pedir, tentar sem aprovação, aprovar sem terminal, aprovar "como humano", adulterar depois, aprovar de novo, executar e tentar reusar. Nenhum modelo; o envio é uma linha em saida.log.

Terminal · ensaio da porta
bash ~/projetos/loop-r-eng-seguranca-v72/kit/porta/ensaio-porta.sh 2>&1
Exemplo do repositório
pedido 20261019-065013-4181: enviar-email → cliente@exemplo.invalid (30 caracteres). Aguardando aprovação humana.
RECUSADO: 20261019-065013-4181 sem aprovação humana
saída: 1
RECUSADO: aprovar exige um terminal humano (stdin não é tty)
saída: 1
APROVADO 20261019-065013-4181 (hash 50a9d2859698c516)
RECUSADO: o conteúdo de 20261019-065013-4181 mudou depois da aprovação
saída: 1
APROVADO 20261019-065014-b7be (hash 50a9d2859698c516)
EXECUTADO 20261019-065014-b7be: enviar-email → cliente@exemplo.invalid
saída: 0
RECUSADO: 20261019-065014-b7be sem aprovação humana
saída: 1
1

Quatro recusas e uma execução; o 1 no fim é a única linha em saida.log. Os ids mudam a cada rodada.

04Uma política real, anonimizada

Regras de ação irreversível do CLAUDE.md global de uma máquina INEMA, e lições que viraram regra.

1. Remover pede, cada vez

Exclusão ou remoção publicada exige aprovação individual para cada uma, com o alvo identificado antes. Autorização genérica, em lote ou de publicação não serve como aprovação de exclusão.

Enviar e-mail e apagar evento são irreversíveis: confirmar antes.

05Fora do terminal: teto e sandbox juntos

O systemd dá o teto (tempo, memória); o sandbox do Codex, dentro dele, dá o isolamento que o systemd do usuário não deu nesta máquina (aula 6).

Terminal · teto e isolamento no systemd
P=~/projetos/loop-r-eng-seguranca-v72/kit/prova-isolamento.sh
W=/tmp/ensaio-seg/iso; mkdir -p $W
echo "## teto de tempo: RuntimeMaxSec=3 num sleep 10"
systemd-run --user --wait --pipe --quiet -p RuntimeMaxSec=3 sleep 10; echo "saída: $?"
echo "## fora do terminal, com teto E sandbox do Codex dentro"
bash $P systemd-run --user --pipe --wait --quiet -p MemoryMax=1G -p RuntimeMaxSec=60 -- \
  codex sandbox -P :workspace -C $W --
echo "saída: $?"
Arquivo · kit/systemd/loop-seguro.service (modelo)
# loop-seguro.service — modelo de unit de usuário para rodar um ciclo do agente fora do terminal
# sem aumentar o raio de dano. Troque MEU-PROJETO e confira com o prova-isolamento.sh ANTES de ligar.
#   cp loop-seguro.service ~/.config/systemd/user/ && systemctl --user daemon-reload
#   systemctl --user start loop-seguro.service && journalctl --user -u loop-seguro -n 20
#
# O que segura de verdade (testado em 19/10/2026, systemd 255, Ubuntu, kernel com
# apparmor_restrict_unprivileged_userns=1):
#   - tetos: MemoryMax, TimeoutStartSec (oneshot não aceita RuntimeMaxSec), timeout e flock (funcionam no systemd --user)
#   - isolamento: o sandbox do Codex (-s workspace-write) DENTRO do serviço
# O que NÃO segurou nesta máquina: PrivateNetwork=, ProtectHome=, IPAddressDeny= no systemd --user.
# O journal diz "proceeding without" e o serviço roda sem a trava. Não conte com elas sem prova.
[Unit]
Description=Um ciclo do loop do agente (curso Segurança do Loop Autônomo)

[Service]
Type=oneshot
WorkingDirectory=%h/projetos/MEU-PROJETO
# PATH fixo: o serviço não herda o seu shell (nem as suas chaves). Não ponha EnvironmentFile com segredo.
Environment=PATH=%h/.npm-global/bin:/usr/local/bin:/usr/bin:/bin
StandardInput=file:%h/projetos/MEU-PROJETO/longrun/prompt.md
ExecStart=/usr/bin/flock -n %t/loop-seguro.lock timeout 2h codex exec -s workspace-write --skip-git-repo-check -C %h/projetos/MEU-PROJETO -
MemoryMax=4G
TimeoutStartSec=3h
NoNewPrivileges=yes
Exemplo do repositório
## teto de tempo: RuntimeMaxSec=3 num sleep 10
saída: 1
## fora do terminal, com teto E sandbox do Codex dentro
  escreve-dentro ABERTO
  escreve-fora BLOQUEADO
  rede BLOQUEADO
  le-segredo ABERTO
  aviso: lê arquivos fora da pasta; tire segredos do alcance ou corte a rede
ISOLAMENTO: OK
saída: 0

O sleep 10 foi morto aos 3 s (saída 1). Dentro do mesmo systemd-run, o sandbox do Codex bloqueou escrita fora e rede.

06Routines e outros agendadores

O que dá para dizer com segurança.

1. O que se sabe

Há relatos (fonte secundária, não confirmada na doc) de agentes agendados na nuvem do Claude Code, as routines, com gatilho por agenda, API ou evento do GitHub.

Os limites atuais não foram confirmados para este curso: trate como recurso a conferir na doc antes de usar.

07Prática

A porta, o systemd e a sua lista de irreversíveis.

E18 · A porta no ensaio

10 min

Rode o ensaio da porta. Depois aprove um pedido você mesmo, no seu terminal: python3 porta.py pedir, aprovar e executar.

Pronto quando: o ensaio mostra quatro linhas RECUSADO, uma EXECUTADO e termina em 1; o seu executar imprime EXECUTADO uma vez e, repetido, sem aprovação humana.

E19 · Teto e sandbox no systemd

10 min

Rode o bloco do systemd na sua máquina (Linux com systemd).

Pronto quando: o primeiro passo termina em saída: 1 (morto pelo teto) e o segundo em ISOLAMENTO: OK e saída: 0.

E20 · A lista dos seus irreversíveis

15 min

Escreva no AGENTS.md (ou CLAUDE.md) do projeto a lista das ações do seu loop que não têm volta e o caminho de cada uma: porta.py, deny da aula 4 ou guarda da aula 5.

Pronto quando: grep -ci "irreversível" AGENTS.md → um número maior que 0, e cada ação da lista aparece num deny, na guarda ou num porta.py pedir.

08Teste da aula

Pergunta 1 de 4

Por que a aprovação guarda o hash do conteúdo?competência

09Em três frases

Pedir ≠ executarO agente pede; você aprova o conteúdo exato; executa uma vez.
Fronteira, não lombadaA aprovação mora onde o agente não escreve.
Leve o teto juntoFora do terminal: timeout, MemoryMax, sandbox provado e a porta.

Para ir além

Aula anteriorPróxima aula