Comment empêcher Claude Code, Codex CLI, Cursor et OpenCode de lire votre .env avec une seule commande

GuidesJohn Silver14 min de lecture

Pour empêcher un agent de programmation IA de lire vos fichiers .env, placez entre l'agent et vos fichiers une couche qui refuse ces lectures et retire les secrets de ce que renvoient les outils de l'agent. zn-gate le fait pour Claude Code, Codex CLI, Cursor et OpenCode avec une seule commande, npx -y zn-gate init, et une seconde commande, npx -y zn-gate check, confirme que cela fonctionne. Il est open source (MIT), s'exécute sur votre machine, n'exige aucun compte et n'envoie rien nulle part par défaut.

Ce guide explique ce que la commande change dans chaque agent, comment la vérifier, ce qu'elle ne couvre pas et comment la retirer.

Pourquoi est-ce important qu'un agent de programmation lise votre .env ?

Un agent de programmation travaille en appelant des outils : lire un fichier, chercher dans le dépôt, exécuter une commande shell. Tout ce qu'un outil renvoie est ajouté à la conversation, et la conversation est ce qui est envoyé au fournisseur du modèle. Le problème commence quand le fichier ouvert par l'agent est .env.

Un cas concret. Vous demandez à l'agent pourquoi une migration de base de données échoue. Il décide de vérifier la configuration et lit .env. Le fichier contient DATABASE_URL=postgres://app:password@db:5432/main, une clé de paiement et quelques autres valeurs. Ces lignes font désormais partie du contexte. Elles peuvent être envoyées au fournisseur, stockées dans le journal de session de l'agent sur le disque et reprises dans une réponse ultérieure ou dans une commande que l'agent écrit. Vous n'avez jamais tapé le mot de passe dans un chat, et il y a pourtant atterri.

Il n'est pas nécessaire d'avoir un attaquant : un agent serviable lit le fichier qui explique le problème. Un texte lu sur une page web ou dans un ticket peut aussi l'orienter vers des fichiers qu'il n'avait aucune raison d'ouvrir. Demander à l'agent dans un prompt de ne pas lire les secrets est une demande, pas un contrôle. Une vérification exécutée avant que l'outil ne s'exécute est un contrôle, et c'est ce qu'ajoute zn-gate.

De quoi avez-vous besoin avant de commencer ?

Il vous faut Node.js 18 ou une version plus récente. Ouvrez un terminal et lancez :

node --version

Si la commande est introuvable ou affiche une version inférieure à 18, installez la version LTS depuis nodejs.org et ouvrez un nouveau terminal. Le plugin Claude Code demande un peu plus : Node.js 20.12 ou plus récent, Git et Claude Code 2.1.295 ou plus récent. La version LTS actuelle de Node.js convient dans les deux cas.

Tapez les commandes dans votre propre terminal (Terminal sous macOS, PowerShell ou Invite de commandes sous Windows), pas dans le chat de votre agent de programmation. init vous demande de confirmer chaque étape et, lorsqu'un agent IA ou un script le lance, il se contente d'afficher les étapes au lieu de les exécuter.

Comment protéger tous les agents de votre machine avec une seule commande ?

npx -y zn-gate init

init cherche Claude Code, Codex CLI, Cursor et OpenCode. Pour chacun qui n'est pas encore protégé, il affiche la configuration qu'il exécuterait, lance chaque étape après votre confirmation et termine par une vérification. Les agents non installés sont ignorés.

Sous Windows, PowerShell refuse parfois avec « running scripts is disabled on this system ». Utilisez npx.cmd à la place de npx (et npm.cmd, zn.cmd pour les autres commandes), ou lancez les mêmes commandes depuis l'Invite de commandes.

Qu'installe init dans chaque agent ?

Chaque agent permet à un outil externe de s'y brancher de façon différente, donc init utilise un mécanisme différent pour chacun :

Agent Ce qui est installé Mécanisme Ce que vous faites ensuite
Claude Code Le plugin zn-gate du marketplace usezn/zn Hooks, fournis par le plugin Démarrez une nouvelle session Claude Code
Codex CLI Les hooks de zn, avec npm install -g zn-gate et zn hooks install codex Hooks (hooks.json) Ouvrez Codex et approuvez les nouveaux hooks avec /hooks
Cursor Les hooks de zn, avec zn hooks install cursor Hooks (hooks.json) Redémarrez Cursor
OpenCode Le plugin de zn, avec zn hooks install opencode Fichier de plugin (plugins/zn-gate.js) Redémarrez OpenCode

Si vous préférez procéder agent par agent, ce sont les mêmes étapes que celles de init. Pour Claude Code :

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

Pour les trois autres :

npm install -g zn-gate
zn hooks install codex

Remplacez codex par cursor ou opencode selon le cas. Ces commandes écrivent dans votre configuration utilisateur. Avec --project, elles écrivent dans le projet courant (voir la section sur les problèmes courants).

Qu'est-ce qui change pour l'agent une fois protégé ?

Avec le plugin ou les hooks actifs :

  • L'agent ne peut plus lire les fichiers .env contenant de vraies valeurs ni les fichiers d'identifiants, comme ceux de ~/.aws et ~/.ssh.
  • Les secrets présents dans ce que renvoient ses outils sont remplacés par des marqueurs ou masqués avant que le modèle ne les voie.
  • Un secret que vous collez dans un prompt est bloqué avant l'envoi.
  • L'agent ne peut pas écrire dans le dossier de zn (~/.zn) ni modifier la configuration des hooks et plugins qui le protège. Dans Cursor, ce dernier point est fait au mieux.

La portée de tout cela dépend de ce que permettent les hooks de chaque agent, et les différences comptent :

Nettoie la sortie des outils Bloque les lectures de .env Bloque un secret collé
Claude Code Tous les outils, y compris shell, lecture de fichiers, recherche et MCP Oui Oui
Codex CLI Oui, mais le résultat est remplacé par son texte nettoyé, et le journal de session propre à Codex conserve l'original Oui Oui
Cursor Sortie MCP uniquement ; la sortie du shell et le contenu des fichiers ne sont pas nettoyés Oui Oui
OpenCode Tous les outils Oui Oui

Le tableau de compatibilité complet, avec ce qui se passe quand un hook ne peut pas s'exécuter, est dans compat.md. Les guides d'installation par agent commencent à Installation.

Comment vérifier que cela fonctionne ?

npx -y zn-gate check

check crée un dossier temporaire avec deux fichiers : un .env contenant une fausse clé et un fichier texte ordinaire. Pour chaque agent configuré pour votre utilisateur, il demande au hook de zn de laisser l'agent lire les deux, comme le ferait votre agent. Pour OpenCode, dont le plugin s'exécute dans OpenCode, il vérifie à la place les règles de zn. Un agent n'est considéré comme protégé que lorsque le fichier .env est bloqué et le fichier ordinaire autorisé.

Rien n'est envoyé sur le réseau, aucun agent n'est démarré et aucun réglage ne change. Le dossier est supprimé à la fin. Chaque agent reçoit l'un de trois résultats :

  • OK : zn le protège. Le texte entre guillemets est ce que l'on dit à votre agent quand il essaie de lire le fichier.
  • - : zn n'est pas configuré pour lui, ou seulement pour un projet. La ligne indique la commande qui le configure. Un agent non installé apparaît comme « not found on this machine ».
  • X ... NOT protected : zn est configuré mais ne protégerait pas cet agent. La ligne dit pourquoi et quoi lancer.

check se termine avec le code 0 seulement quand tous les agents configurés pour votre utilisateur sont protégés. Le sens de chaque ligne : Vérifier que ça fonctionne.

Comment votre propre application obtient-elle encore les valeurs du .env ?

Quand l'agent ne peut plus lire .env, votre application a toujours besoin de ses valeurs. zn-gate peut les garder dans un coffre chiffré sur votre machine et laisser des marqueurs dans le fichier :

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

Le premier unlock crée le coffre. Après env shadow, le fichier contient des marqueurs comme __ZN_STRIPE_KEY__ à la place des valeurs, et la commande vous indique comment annuler le changement. Pour démarrer votre application avec les vraies valeurs, autorisez le programme une fois et lancez-le via zn-gate. Si vous démarrez votre application avec 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 place la vraie valeur dans l'environnement de votre application. La plupart des chargeurs de .env, dont dotenv, conservent une variable déjà définie : votre application reçoit donc la valeur et non le marqueur. zn vous demande de confirmer dans une boîte de dialogue système, en dehors de l'agent. Sur un serveur ou en SSH, il n'y a pas de boîte de dialogue : lancez npx -y zn-gate unlock --foreground dans un terminal à part et répondez-y. Autorisez le programme le plus étroit possible. npm, node, python et les autres interpréteurs exécutent tout code qu'on leur donne : en autoriser un permet à chaque script qu'il lance de lire la valeur, et zn vous prévient quand vous le faites. Plus de détails dans la documentation du coffre.

Qu'est-ce qui peut mal tourner, et comment y remédier ?

L'agent bloque tous les prompts après une mise à jour de Node.js. Le hook pointe vers le Node.js présent quand vous avez lancé init. Si vous l'avez mis à jour, déplacé ou supprimé (avec nvm, par exemple), le hook ne peut pas démarrer. Claude Code 2.1.295 ou plus récent, Cursor et OpenCode bloquent alors les prompts au lieu de les laisser passer sans vérification ; Codex CLI les laisse passer. Lancez npx -y zn-gate check : la commande nomme chaque agent non protégé et la commande qui le répare, en général npm install -g zn-gate suivi de zn hooks install <agent>.

Le plugin et les hooks sont tous deux installés dans Claude Code. Si vous avez lancé zn hooks install claude-code avant d'installer le plugin, lancez d'abord zn hooks uninstall claude-code ; sinon les deux jeux de hooks s'exécutent.

Des réglages de Claude Code désactivent les hooks. Sur un ordinateur géré par une organisation, Claude Code peut être configuré pour ignorer les hooks que vous installez vous-même (disableAllHooks ou allowManagedHooksOnly dans les réglages gérés), sans vous le dire. disableAllHooks dans vos propres réglages a le même effet. check lit ces fichiers de réglages et signale l'agent comme non protégé ; il détecte aussi quand le plugin zn-gate est désactivé. npx -y zn-gate status affiche une note lorsqu'il trouve un tel réglage. Demandez à votre administrateur d'ajouter zn aux réglages gérés. Les politiques envoyées par claude.ai, par la gestion des appareils (MDM) ou par le registre Windows ne sont pas lues.

Codex ne semble pas réagir. Les hooks nouveaux ou modifiés ne s'exécutent qu'après que vous les avez approuvés dans /hooks.

Vous avez installé pour un seul projet. Une installation avec --project écrit des fichiers comme .claude/settings.json, .codex/hooks.json, .cursor/hooks.json ou .opencode/plugins/zn-gate.js dans le projet. check liste cette configuration mais ne l'exécute pas. Un collègue qui clone le projet sans zn dans son PATH n'obtient aucune vérification de ces fichiers : installez donc zn sur chaque machine qui exécute l'agent.

Que ne couvre pas zn-gate ?

  • C'est une couche, pas une garantie. Un secret dans un format que zn ne reconnaît pas, et qui n'est pas dans le coffre, peut encore atteindre le modèle.
  • Dans Cursor, la sortie du shell et le contenu des fichiers ne sont pas nettoyés. Un secret affiché par une commande shell, ou présent dans un fichier non bloqué, atteint le modèle. Pour réduire ce risque, appliquez env shadow à vos fichiers .env et gardez les secrets dans le coffre.
  • Dans Codex CLI, les hooks sont un garde-fou et non une barrière imposée, c'est ainsi que Codex décrit ses propres hooks. Le journal de session que Codex conserve en local contient toujours la sortie d'origine.
  • Non couverts : le Cursor CLI (cursor-agent), Hermes Agent, Gemini CLI, Copilot CLI, les sessions Claude Code dans le cloud, Cowork et les conversations de chat.
  • Tant que le coffre est déverrouillé, tout programme exécuté sous votre utilisateur peut lui demander un secret enregistré par son nom. Verrouillez-le quand vous n'en avez pas besoin.
  • Dans les autres éditeurs (VS Code, Antigravity, Windsurf, Cline, Zed, JetBrains, Continue), zn-gate fonctionne uniquement comme serveur MCP que l'agent appelle quand il le décide. Il ne peut pas y bloquer la lecture de vos fichiers .env. La configuration est dans éditeurs.
  • Le paquet Python est destiné aux agents que vous construisez vous-même, comme LangChain, CrewAI, LlamaIndex ou l'appel d'outils direct. Il ne protège pas les agents de programmation.

Qu'est-ce qui quitte votre machine ?

Rien, par défaut. La sortie des outils et les arguments de leurs appels ne sont jamais envoyés, quelle que soit la configuration. Un prompt n'est envoyé à la vérification cloud optionnelle que si vous définissez ZN_CLOUD=1 et ZN_API_KEY, ou l'option de clé d'API du plugin Claude Code. Les secrets que zn-gate détecte sont retirés d'abord en local ; les données personnelles ne sont pas retirées dans ce cas.

Pour voir votre propre configuration, lancez :

npx -y zn-gate status

La commande affiche les versions du paquet et des règles, le moteur de détection actif, si la vérification optionnelle dans le cloud est activée et si une clé d’API est définie. Le partage des statistiques d’utilisation est désactivé par défaut et a son propre statut : zn-gate stats share status. Le tableau complet se trouve dans Ce qui quitte votre machine.

Comment le retirer ?

  • Codex CLI, Cursor ou OpenCode : npx -y zn-gate hooks uninstall <agent>, par exemple npx -y zn-gate hooks uninstall codex. Ajoutez --project si vous avez installé pour un seul projet.
  • Claude Code : ouvrez /plugin dans Claude Code et retirez zn-gate, ou désactivez-le avec claude plugin disable zn-gate@usezn. Réactivez-le avec claude plugin enable zn-gate@usezn. Si vous avez installé les hooks de zn pour Claude Code au lieu du plugin, lancez npx -y zn-gate hooks uninstall claude-code.
  • Le coffre : env shadow affiche la commande exacte qui remet le .env d'origine, npx -y zn-gate env unshadow .env --backup <name>, où <name> est le nom de la sauvegarde qu'il indique.

Questions fréquentes

Comment empêcher Claude Code de lire mon fichier .env ?

Lancez npx -y zn-gate init dans votre propre terminal. Pour Claude Code, la commande installe le plugin zn-gate, qui bloque la lecture des fichiers .env contenant de vraies valeurs et des fichiers d'identifiants. Démarrez ensuite une nouvelle session Claude Code et lancez npx -y zn-gate check pour confirmer.

zn-gate fonctionne-t-il aussi avec Codex CLI, Cursor et OpenCode ?

Oui. Pour ces trois agents, init installe les hooks de zn (un fichier de plugin pour OpenCode). Codex vous demande d'approuver les nouveaux hooks avec /hooks. Cursor ne nettoie que la sortie des outils MCP : la sortie du shell et le contenu des fichiers n'y sont pas nettoyés.

Faut-il un compte, une clé d'API ou un accès réseau ?

Ni compte ni clé d'API. L'installation télécharge le paquet depuis npm, et le plugin Claude Code depuis GitHub. Ensuite, par défaut, rien ne quitte votre machine : la sortie des outils et les arguments de leurs appels ne sont jamais envoyés, quelle que soit la configuration. La vérification des prompts dans le cloud est désactivée tant que vous ne définissez pas ZN_CLOUD=1 et ZN_API_KEY, ou l'option de clé d'API du plugin Claude Code.

Mon application peut-elle encore lire les valeurs du .env ensuite ?

L'agent ne peut pas lire un .env contenant de vraies valeurs, mais votre application peut toujours les obtenir. Lancez npx -y zn-gate env shadow .env pour déplacer les valeurs dans le coffre chiffré local de zn-gate, puis démarrez votre application avec la commande run de zn-gate une fois le programme autorisé.

Comment savoir que la protection est réellement active ?

Lancez npx -y zn-gate check. La commande crée un dossier temporaire avec un faux .env et un fichier ordinaire, demande au hook installé de lire les deux, et ne déclare un agent protégé que si le .env est bloqué et le fichier ordinaire autorisé.

Contre quoi ne protège-t-il pas ?

C'est une couche, pas une garantie. Un secret dans un format que zn ne reconnaît pas et qui n'est pas dans le coffre peut encore atteindre le modèle, et dans Cursor un secret affiché par une commande shell n'est pas nettoyé. Les sessions Claude Code dans le cloud, Cowork et le chat ne sont pas couverts.

Comment supprimer zn-gate ?

Pour Codex CLI, Cursor ou OpenCode, lancez npx -y zn-gate hooks uninstall suivi du nom de l'agent, par exemple codex. Pour Claude Code, retirez le plugin dans /plugin ou lancez claude plugin disable zn-gate@usezn.


Pour l'essayer sur votre propre agent, lancez npx -y zn-gate init (MIT, local, sans compte), puis npx -y zn-gate check. Le code est sur GitHub, et les guides pour chaque agent commencent à Installation.

Partager