AIMC
Retour

Sécurité

Claude Code : verrouille tes .env

Par défaut, Claude Code peut lire tes fichiers .env, capturer des clés via les sorties de commandes et les exposer dans la conversation. La fix tient en 10 lignes de settings.json.

3 min lecture562 mots2026-05-01

Tu démarres une session Claude Code dans ton repo. Sans rien faire, Claude peut lire ton .env au moment où il indexe le projet. Tes clés Anthropic, Stripe, OpenAI, ta DATABASE_URL deviennent du contexte — donc potentiellement des logs côté provider.

Ajouter "ne lis pas mes .env" dans ton CLAUDE.md ne suffit pas. C'est une consigne, pas une contrainte. Sous pression (tâche complexe, contexte long, instruction ambiguë) le modèle peut l'ignorer. La seule protection fiable c'est une deny rule dans settings.json — appliquée par la CLI elle-même, avant que Claude ne voie le fichier.

Les 3 chemins de leak à connaître

  1. Lecture directe. Claude scanne ton repo, ouvre .env, le contenu rentre dans la conversation. Le cas évident.
  2. Sortie de commande. Claude lance npm test ou bun run dev. Une requête HTTP plante en logguant Authorization: Bearer sk-.... Une connexion Postgres timeout en dumpant la connection string. Claude capture toute la sortie. Tes secrets sont dans la conversation, sans qu'il n'ait jamais ouvert un .env.
  3. Grep / search. Claude grep une fonction et tombe sur un fichier de config qui contient des credentials. La sortie du grep inclut la ligne entière.

La majorité des protections en circulation ne couvrent que le chemin 1.

La fix qui marche : deny rules globales

Dans ~/.claude/settings.json (config globale, s'applique à tous tes projets) :

{
  "permissions": {
    "deny": [
      "Read(**/.env*)",
      "Read(**/*.pem)",
      "Read(**/*.key)",
      "Read(**/secrets/**)",
      "Read(**/credentials/**)",
      "Read(**/.aws/**)",
      "Read(**/.ssh/**)",
      "Read(**/.npmrc)",
      "Read(**/.pypirc)",
      "Write(**/.env*)",
      "Write(**/.ssh/**)"
    ]
  }
}

Ces règles bloquent l'accès en lecture avant que Claude ne voie le fichier. Le double-asterisk ** couvre tous les sous-dossiers, donc même si tu as un .env au fond de apps/web/, c'est protégé.

Tu peux ajouter une règle équivalente dans le settings.json du repo pour chaque projet client (utile si t'as des conventions spécifiques, comme un dossier vault/ qui contient des secrets).

Bloquer le leak via sortie de commande

Les deny rules ne couvrent pas la capture de sortie. Pour ça, utilise un .env.test avec des valeurs fictives :

# .env.test — safe à lire, safe à leak
STRIPE_SECRET_KEY=sk_test_dummy_key
DATABASE_URL=postgres://test:test@localhost:5432/testdb
OPENAI_API_KEY=sk-test-not-real

Pointe ton framework de test sur .env.test (Vitest, Jest, Playwright le font tous via une option). Quand Claude lance les tests, il voit des dummies, jamais les vrais secrets.

Filet de sécurité : pre-commit hook

Même avec les deny rules, un copier-coller malheureux peut envoyer un secret dans un commit. Dans .git/hooks/pre-commit :

#!/bin/bash
PATTERNS=('sk-ant-' 'sk-live-' 'sk_live_' 'ghp_' 'gho_' 'AKIA' 'xox[bpors]-' 'SG\.' 'BEGIN.*PRIVATE KEY')

for pattern in "${PATTERNS[@]}"; do
  if git diff --cached | grep -qE "$pattern"; then
    echo "BLOCKED: secret matching '$pattern' detected"
    exit 1
  fi
done

if git diff --cached --name-only | grep -qE '\.env$|id_rsa|\.pem$|\.key$'; then
  echo "BLOCKED: sensitive file in staging"
  exit 1
fi

Rend-le exécutable :

chmod +x .git/hooks/pre-commit

Tu peux aussi utiliser gitleaks en pre-commit — plus de patterns, plus à jour.

Checklist avant ta prochaine session

  1. Deny rules .env* dans ~/.claude/settings.json
  2. .env.test avec valeurs fictives pour les tests
  3. Pre-commit hook qui scanne les patterns de secrets
  4. .env dans .gitignore (évident, mais on vérifie)
  5. Credentials de prod dans un vault, pas en plaintext

Si t'as les 5, t'es propre. Si tu démarres à zéro, copie-colle juste le bloc deny ci-dessus dans ton ~/.claude/settings.json — c'est la protection qui couvre 80% du risque en 10 lignes.