Claude Code no homelab: CLAUDE.md é pedido, deny no settings.json é trava
Uso o Claude Code nos containers do meu homelab, até pelo celular. Uma ferramenta que roda comando sozinha dentro do servidor pede regras claras, e descobri que há dois tipos de regra: a que é só pedido e a que é bloqueio de verdade.
Primeiro, o acesso
A regra mais forte não é texto. No meu homelab, o Claude Code trabalha nos containers de serviço e nas aplicações, mas não no host Proxmox. O host é a única peça que derruba tudo de uma vez. O que a IA não alcança, ela não estraga.
As três regras que repito
- Segredos em
/etc/<app>/*.env, com permissão600. Nunca no repositório, nunca em log. - Nada externo e nenhum gasto sem minha confirmação. Publicar, enviar, criar recurso em nuvem: passa por mim.
- Não mexer em produção sem pedir.
Parecem óbvias. O problema é que uma IA tentando resolver a tarefa acha o caminho mais curto, e às vezes o caminho mais curto é colar a senha no código ou reiniciar o serviço de produção para testar.
CLAUDE.md: o lugar das regras
O CLAUDE.md é carregado no começo de toda sessão. O ~/.claude/CLAUDE.md vale para todos os projetos do usuário; o ./CLAUDE.md vale só para o projeto e vai para o git. Regras gerais no primeiro, regras do app no segundo. A documentação recomenda ficar abaixo de 200 linhas por arquivo, e o /context mostra o que foi carregado.
Mas CLAUDE.md não trava nada
A documentação é clara: o CLAUDE.md é tratado como contexto, não como configuração obrigatória. Para bloquear de verdade, use as regras de permissão do settings.json, que o próprio Claude Code aplica:
{
"permissions": {
"deny": [
"Bash(git push *)",
"Read(./.env)",
"Read(./secrets/**)"
]
}
}
A ordem é sempre deny, depois ask, depois allow, e um allow não abre exceção num deny.
Atualização: o deny tem furo, o sandbox fecha
O @plugandship apontou aqui nos comentários dois furos, e a documentação confirma os dois:
- Regra de Bash casa com o texto do comando. O
Bash(git push *)pegagit push, mas não/usr/bin/git pushnemsh -c 'git push'. - Regra de
Readnão segura subprocesso. Vale para as ferramentas do Claude e paracat,heade afins, mas um script Python que abre o.envpassa direto.
Para os dois, o caminho é o sandbox do Bash (/sandbox na sessão ou sandbox.enabled no settings.json). Ele age no sistema operacional, para o comando e para os processos que ele abre. Só que, por padrão, deixa ler quase tudo, inclusive ~/.ssh, então o que fica de fora precisa ir no denyRead:
{
"sandbox": {
"enabled": true,
"allowUnsandboxedCommands": false,
"filesystem": {
"denyRead": ["~/.ssh", "~/.aws", "~/**/.env", "/etc/meuapp"]
}
}
}
O allowUnsandboxedCommands: false impede o Claude de tentar de novo fora do sandbox quando um comando falha. E a rede do sandbox só libera domínios permitidos, então um push não chega ao GitHub sem você liberar.
Para o push, fico com a conclusão dele: nada de credencial com permissão de escrita dentro do container. Regra pode ter furo; credencial que não existe, não.
As camadas
- CLAUDE.md: o que eu espero.
denynosettings.json: recusa as ferramentas do Claude e os comandos do jeito que ele costuma escrever.- Sandbox do Bash: vale no sistema, para o que estiver listado.
- Permissão de arquivo e usuário no Linux.
- Acesso: o host fica de fora, e credencial de escrita também.
E por baixo de tudo, git e backup. Todo projeto meu tem repositório no GitHub, e os containers entram no vzdump da noite.
Vocês deixam a IA rodar comando no homelab? Que regras usam, e onde elas ficam?
O post completo está no meu blog: https://blog.brumarino.com/claude-code-regras-homelab/?de=tabnews