Como impedir que Claude Code, Codex CLI, Cursor e OpenCode leiam seu .env com um único comando

GuiasJohn Silver14 min de leitura

Para impedir que um agente de programação com IA leia seus arquivos .env, coloque entre o agente e seus arquivos uma camada que recuse essas leituras e remova os segredos do que as ferramentas do agente devolvem. O zn-gate faz isso para Claude Code, Codex CLI, Cursor e OpenCode com um único comando, npx -y zn-gate init, e um segundo comando, npx -y zn-gate check, confirma que funciona. É de código aberto (MIT), roda na sua máquina, não exige conta e, por padrão, não envia nada a lugar nenhum.

Este guia explica o que o comando muda em cada agente, como verificar, o que ele não cobre e como removê-lo.

Por que importa que um agente de programação leia seu .env?

Um agente de programação trabalha chamando ferramentas: ler um arquivo, buscar no repositório, executar um comando de shell. Tudo o que uma ferramenta devolve é adicionado à conversa, e a conversa é o que vai para o provedor do modelo. O problema começa quando o arquivo que o agente abre é o .env.

Um caso concreto. Você pergunta ao agente por que uma migração de banco de dados falha. Ele decide verificar a configuração e lê o .env. O arquivo contém DATABASE_URL=postgres://app:password@db:5432/main, uma chave de pagamento e alguns outros valores. Essas linhas agora fazem parte do contexto. Podem ser enviadas ao provedor, guardadas no registro de sessão do agente no disco e repetidas numa resposta posterior ou num comando que o agente escreva. Você nunca digitou a senha num chat, e mesmo assim ela foi parar lá.

Não é preciso um atacante: um agente prestativo lê o arquivo que explica o problema. O texto que ele lê numa página web ou numa issue também pode levá-lo a arquivos que não tinha motivo para abrir. Pedir no prompt que o agente não leia segredos é um pedido, não um controle. Uma verificação que roda antes de a ferramenta executar é um controle, e é isso que o zn-gate acrescenta.

O que você precisa antes de começar?

Você precisa do Node.js 18 ou posterior. Abra um terminal e execute:

node --version

Se o comando não for encontrado ou mostrar uma versão abaixo de 18, instale a versão LTS em nodejs.org e abra um novo terminal. O plugin do Claude Code pede um pouco mais: Node.js 20.12 ou posterior, Git e Claude Code 2.1.295 ou posterior. A versão LTS atual do Node.js atende aos dois casos.

Digite os comandos no seu próprio terminal (Terminal no macOS, PowerShell ou Prompt de Comando no Windows), não no chat do seu agente de programação. O init pede que você confirme cada passo e, quando um agente de IA ou um script o executa, ele apenas mostra os passos em vez de executá-los.

Como proteger todos os agentes da sua máquina com um único comando?

npx -y zn-gate init

O init procura Claude Code, Codex CLI, Cursor e OpenCode. Para cada um que ainda não esteja protegido, mostra a configuração que executaria, executa cada passo depois que você confirma e termina com uma verificação. Agentes que não estão instalados são ignorados.

No Windows, o PowerShell às vezes recusa com "running scripts is disabled on this system". Use npx.cmd no lugar de npx (e npm.cmd, zn.cmd para os outros comandos), ou execute os mesmos comandos pelo Prompt de Comando.

O que o init instala em cada agente?

Cada agente permite que uma ferramenta externa se conecte de forma diferente, então o init usa um mecanismo diferente para cada um:

Agente O que é instalado Mecanismo O que você faz depois
Claude Code O plugin zn-gate do marketplace usezn/zn Hooks, entregues pelo plugin Inicie uma nova sessão do Claude Code
Codex CLI Os hooks do zn, com npm install -g zn-gate e zn hooks install codex Hooks (hooks.json) Abra o Codex e aprove os novos hooks com /hooks
Cursor Os hooks do zn, com zn hooks install cursor Hooks (hooks.json) Reinicie o Cursor
OpenCode O plugin do zn, com zn hooks install opencode Arquivo de plugin (plugins/zn-gate.js) Reinicie o OpenCode

Se preferir fazer um agente de cada vez, são os mesmos passos que o init executa. Para o Claude Code:

claude plugin marketplace add usezn/zn
claude plugin install zn-gate@usezn

Para os outros três:

npm install -g zn-gate
zn hooks install codex

Troque codex por cursor ou opencode conforme o caso. Esses comandos escrevem na sua configuração de usuário. Com --project, escrevem no projeto atual (veja a seção de problemas comuns).

O que muda para o agente depois de protegido?

Com o plugin ou os hooks ativos:

  • O agente fica impedido de ler arquivos .env com valores reais e arquivos de credenciais, como os de ~/.aws e ~/.ssh.
  • Os segredos no que suas ferramentas devolvem são trocados por marcadores ou ocultados antes de o modelo vê-los.
  • Um segredo que você cola num prompt é bloqueado antes do envio.
  • O agente não pode escrever na pasta do zn (~/.zn) nem editar a configuração de hooks e plugins que o protege. No Cursor, esta última parte é feita no melhor esforço.

Até onde isso vai depende do que os hooks de cada agente permitem, e as diferenças importam:

Limpa a saída das ferramentas Bloqueia leituras de .env Bloqueia um segredo colado
Claude Code Todas as ferramentas, incluindo shell, leitura de arquivos, busca e MCP Sim Sim
Codex CLI Sim, mas o resultado é substituído pelo texto limpo, e o registro de sessão do próprio Codex guarda o original Sim Sim
Cursor Apenas a saída MCP; a saída do shell e o conteúdo de arquivos não são limpos Sim Sim
OpenCode Todas as ferramentas Sim Sim

A tabela de compatibilidade completa, com o que acontece quando um hook não consegue rodar, está em compat.md. Os guias de instalação por agente começam em Instalação.

Como verificar se funciona?

npx -y zn-gate check

O check cria uma pasta temporária com dois arquivos: um .env com uma chave falsa e um arquivo de texto comum. Para cada agente configurado para o seu usuário, pede ao hook do zn que deixe o agente ler os dois, como o seu agente faria. No OpenCode, cujo plugin roda dentro do OpenCode, verifica as regras do zn. Um agente só conta como protegido quando o .env é bloqueado e o arquivo comum é permitido.

Nada é enviado pela rede, nenhum agente é iniciado e nenhuma configuração muda. A pasta é apagada no final. Cada agente recebe um de três resultados:

  • OK: o zn está protegendo. O texto entre aspas é o que se diz ao seu agente quando ele tenta ler o arquivo.
  • -: o zn não está configurado para ele, ou só para um projeto. A linha mostra o comando que o configura. Um agente que não está instalado aparece como "not found on this machine".
  • X ... NOT protected: o zn está configurado, mas não protegeria esse agente. A linha diz por quê e o que executar.

O check termina com código 0 apenas quando todos os agentes configurados para o seu usuário estão protegidos. O significado de cada linha: Verificar que funciona.

Como o seu próprio aplicativo continua obtendo os valores do .env?

Quando o agente não consegue mais ler o .env, seu aplicativo ainda precisa dos valores. O zn-gate pode guardá-los num cofre criptografado na sua máquina e deixar marcadores no arquivo:

npx -y zn-gate unlock
npx -y zn-gate env shadow .env

O primeiro unlock cria o cofre. Depois do env shadow, o arquivo contém marcadores como __ZN_STRIPE_KEY__ no lugar dos valores, e o comando informa como desfazer a mudança. Para iniciar seu aplicativo com os valores reais, permita o programa uma vez e execute-o pelo zn-gate. Se você inicia o aplicativo com npm run dev:

npx -y zn-gate secret allow STRIPE_KEY --command npm
npx -y zn-gate run --secrets STRIPE_KEY -- npm run dev

--secrets STRIPE_KEY coloca o valor real no ambiente do seu aplicativo. A maioria dos carregadores de .env, entre eles o dotenv, mantém uma variável que já está definida, então o aplicativo recebe o valor e não o marcador. O zn pede confirmação numa caixa de diálogo do sistema, fora do agente. Em um servidor ou por SSH não há caixa de diálogo: execute npx -y zn-gate unlock --foreground num terminal à parte e responda lá. Permita o programa mais restrito possível. npm, node, python e outros interpretadores executam qualquer código que recebam, então permitir um deles deixa cada script que ele roda ler o valor, e o zn avisa quando você faz isso. Mais detalhes na documentação do cofre.

O que pode dar errado e como corrigir?

O agente bloqueia todos os prompts depois de atualizar o Node.js. O hook aponta para o Node.js que existia quando você executou o init. Se você o atualizou, moveu ou removeu (com nvm, por exemplo), o hook não consegue iniciar. Claude Code 2.1.295 ou posterior, Cursor e OpenCode passam então a bloquear os prompts em vez de deixá-los passar sem verificação; o Codex CLI os deixa passar. Execute npx -y zn-gate check: ele nomeia cada agente que não está protegido e o comando que corrige, normalmente npm install -g zn-gate seguido de zn hooks install <agent>.

O plugin e os hooks estão instalados no Claude Code. Se você executou zn hooks install claude-code antes de instalar o plugin, execute primeiro zn hooks uninstall claude-code; caso contrário, os dois conjuntos de hooks rodam.

Configurações do Claude Code desligam os hooks. Num computador gerenciado por uma organização, o Claude Code pode estar configurado para ignorar os hooks que você mesmo instala (disableAllHooks ou allowManagedHooksOnly nas configurações gerenciadas), e ele não avisa. disableAllHooks nas suas próprias configurações tem o mesmo efeito. O check lê esses arquivos de configuração e marca o agente como não protegido, e também percebe quando o plugin zn-gate está desativado. O npx -y zn-gate status mostra uma nota quando encontra uma configuração assim. Peça ao seu administrador para adicionar o zn às configurações gerenciadas. Políticas enviadas pelo claude.ai, por gerenciamento de dispositivos (MDM) ou pelo registro do Windows não são lidas.

O Codex parece não reagir. Hooks novos ou alterados só rodam depois que você os aprova em /hooks.

Você instalou só para um projeto. Uma instalação com --project grava arquivos como .claude/settings.json, .codex/hooks.json, .cursor/hooks.json ou .opencode/plugins/zn-gate.js dentro do projeto. O check lista essa configuração, mas não a executa. Um colega que clona o projeto sem o zn no PATH não recebe nenhuma verificação desses arquivos, então instale o zn em cada máquina que executa o agente.

O que o zn-gate não cobre?

  • É uma camada, não uma garantia. Um segredo num formato que o zn não reconhece, e que não está no cofre, ainda pode chegar ao modelo.
  • No Cursor, a saída do shell e o conteúdo de arquivos não são limpos. Um segredo impresso por um comando de shell, ou presente num arquivo não bloqueado, chega ao modelo. Para reduzir isso, aplique env shadow aos seus arquivos .env e mantenha os segredos no cofre.
  • No Codex CLI, os hooks são uma proteção de apoio e não um limite imposto, que é como o Codex descreve seus próprios hooks. O registro de sessão que o Codex guarda localmente ainda contém a saída original.
  • Não cobertos: o Cursor CLI (cursor-agent), Hermes Agent, Gemini CLI, Copilot CLI, sessões do Claude Code na nuvem, o Cowork e conversas de chat.
  • Enquanto o cofre está desbloqueado, qualquer programa executado como o seu usuário pode pedir a ele um segredo guardado pelo nome. Bloqueie-o quando não precisar.
  • Em outros editores (VS Code, Antigravity, Windsurf, Cline, Zed, JetBrains, Continue), o zn-gate funciona apenas como servidor MCP que o agente chama quando decide. Lá ele não consegue bloquear leituras dos seus arquivos .env. A configuração está em editores.
  • O pacote Python é para agentes que você mesmo constrói, como LangChain, CrewAI, LlamaIndex ou chamadas de ferramenta diretas. Ele não protege agentes de programação.

O que sai da sua máquina?

Nada, por padrão. A saída das ferramentas e os argumentos das chamadas nunca são enviados, em nenhuma configuração. Um prompt só vai para a verificação opcional na nuvem se você definir ZN_CLOUD=1 e ZN_API_KEY, ou a opção de chave de API do plugin do Claude Code. Os segredos que o zn-gate detecta são removidos antes, localmente; dados pessoais não são removidos nesse caminho.

Para ver a sua própria configuração, execute:

npx -y zn-gate status

O comando mostra as versões do pacote e das regras, o mecanismo de detecção ativo, se a verificação opcional na nuvem está ativada e se há uma chave de API definida. O compartilhamento de estatísticas de uso vem desativado e tem seu próprio status: zn-gate stats share status. A tabela completa está em O que sai da sua máquina.

Como removê-lo?

  • Codex CLI, Cursor ou OpenCode: npx -y zn-gate hooks uninstall <agent>, por exemplo npx -y zn-gate hooks uninstall codex. Acrescente --project se instalou só para um projeto.
  • Claude Code: abra /plugin dentro do Claude Code e remova o zn-gate, ou desative-o com claude plugin disable zn-gate@usezn. Reative com claude plugin enable zn-gate@usezn. Se você instalou os hooks do zn para o Claude Code em vez do plugin, execute npx -y zn-gate hooks uninstall claude-code.
  • O cofre: o env shadow mostra o comando exato que recoloca o .env original, npx -y zn-gate env unshadow .env --backup <name>, em que <name> é o nome da cópia que ele indica.

Perguntas frequentes

Como impeço o Claude Code de ler meu arquivo .env?

Execute npx -y zn-gate init no seu próprio terminal. Para o Claude Code, ele instala o plugin zn-gate, que bloqueia a leitura de arquivos .env com valores reais e de arquivos de credenciais. Inicie uma nova sessão do Claude Code e execute npx -y zn-gate check para confirmar.

O zn-gate também funciona com Codex CLI, Cursor e OpenCode?

Sim. Para esses três, o init instala os hooks do zn (no OpenCode, um arquivo de plugin). O Codex pede que você aprove os novos hooks com /hooks. O Cursor limpa apenas a saída de ferramentas MCP, então a saída do shell e o conteúdo de arquivos não são limpos lá.

Preciso de conta, chave de API ou acesso à rede?

Não é preciso conta nem chave de API. A instalação baixa o pacote do npm, e o plugin do Claude Code do GitHub. Depois disso, por padrão, nada sai da sua máquina: a saída das ferramentas e os argumentos das chamadas nunca são enviados, em nenhuma configuração. A verificação de prompts na nuvem fica desativada, a menos que você defina ZN_CLOUD=1 e ZN_API_KEY, ou a opção de chave de API do plugin do Claude Code.

Meu aplicativo ainda consegue ler os valores do .env depois disso?

O agente não consegue ler um .env com valores reais, mas seu aplicativo ainda pode obtê-los. Execute npx -y zn-gate env shadow .env para mover os valores para o cofre criptografado local do zn-gate e inicie seu aplicativo com o comando run do zn-gate depois de permitir o programa.

Como sei que a proteção está realmente ativa?

Execute npx -y zn-gate check. Ele cria uma pasta temporária com um .env falso e um arquivo comum, pede ao hook instalado que leia os dois e só considera um agente protegido se o .env for bloqueado e o arquivo comum for permitido.

Contra o que ele não protege?

É uma camada, não uma garantia. Um segredo em um formato que o zn não reconhece e que não está no cofre ainda pode chegar ao modelo, e no Cursor um segredo impresso por um comando de shell não é limpo. Sessões do Claude Code na nuvem, o Cowork e o chat não são cobertos.

Como removo o zn-gate?

No Codex CLI, Cursor ou OpenCode, execute npx -y zn-gate hooks uninstall seguido do nome do agente, por exemplo codex. No Claude Code, remova o plugin em /plugin ou execute claude plugin disable zn-gate@usezn.


Para experimentar no seu próprio agente, execute npx -y zn-gate init (MIT, local, sem conta) e depois npx -y zn-gate check. O código está no GitHub e os guias de cada agente começam em Instalação.

Compartilhar