Sécuriser ses clés API MCP dans Claude Code (et pourquoi c'est urgent)

Sécuriser ses clés API MCP dans Claude Code (et pourquoi c'est urgent)

·6 min de lecture·Mis à jour le 15 mars 2026

Le problème : des clés en clair dans mcp.json

Le contenu typique d'un ~/.claude/mcp.json non sécurisé :

{
  "mcpServers": {
    "mon-serveur": {
      "command": "npx",
      "args": ["-y", "mon-mcp-server@latest"],
      "env": {
        "API_KEY": "sk-1234567890abcdef..."
      }
    }
  }
}

Des clés API en clair. Pas chiffrées, pas dans un vault.

L'argument « c'est local, ce n'est pas grave » ne tient pas. En février 2026, deux CVE sont tombées sur Claude Code (CVE-2025-59536 et CVE-2026-21852). La seconde était vicieuse : un repo malveillant pouvait overrider ANTHROPIC_BASE_URL dans les settings projet et rediriger tout le trafic API vers un serveur tiers. Corrigé depuis la v2.0.65.

Et il n'y a pas besoin d'une CVE pour se faire avoir : un git add . trop enthousiaste, un collègue qui copie votre config, un script npm douteux qui scanne ~/.claude/. Une clé API leakée, ce sont parfois des centaines d'euros de consommation frauduleuse avant qu'on remarque quoi que ce soit.

L'interpolation ${VAR}

Claude Code supporte les variables d'environnement entre ${} dans mcp.json :

{
  "mcpServers": {
    "mon-serveur": {
      "command": "npx",
      "args": ["-y", "mon-mcp-server@latest"],
      "env": {
        "API_KEY": "${MON_SERVEUR_API_KEY}"
      }
    }
  }
}

Au lancement du serveur MCP, Claude Code remplace ${MON_SERVEUR_API_KEY} par la vraie valeur depuis l'environnement. Le fichier JSON reste propre.

La mise en place, en 4 étapes

1. Un fichier secrets avec les bonnes permissions

# Créer le fichier
cat > ~/.env.claude << 'EOF'
# API keys pour MCP servers Claude Code
MON_SERVEUR_API_KEY="sk-1234567890abcdef"
AUTRE_SERVICE_TOKEN="token_ici"
SERVICE_EMAIL="mon@email.com"
EOF

# Permissions : lecture/écriture uniquement pour le propriétaire
chmod 600 ~/.env.claude

Le chmod 600 n'est pas optionnel : sans lui, n'importe quel process de la machine peut lire le fichier.

2. Charger les variables au démarrage du shell

Les variables doivent exister dans l'environnement avant que Claude Code démarre.

Fish (dans ~/.config/fish/config.fish) — verbeux, parce que fish ne source pas les fichiers .env nativement :

# Load Claude MCP secrets
if test -f ~/.env.claude
    for line in (grep -v '^#' ~/.env.claude | grep '=')
        set -l key (echo $line | cut -d= -f1)
        set -l val (echo $line | cut -d= -f2- | tr -d '"')
        set -x $key $val
    end
end

Bash/zsh (dans ~/.bashrc ou ~/.zshrc) :

# Load Claude MCP secrets
[ -f ~/.env.claude ] && set -a && source ~/.env.claude && set +a

Le set -a exporte automatiquement toutes les variables sourcées, ce qui évite un export par ligne, et set +a restaure le comportement normal ensuite.

3. Nettoyer mcp.json

{
  "mcpServers": {
    "serveur-recherche": {
      "command": "npx",
      "args": ["-y", "mcp-recherche@latest"],
      "env": {
        "SEARCH_API_KEY": "${SEARCH_API_KEY}"
      }
    },
    "serveur-gestion": {
      "command": "npx",
      "args": ["-y", "mcp-gestion@latest"],
      "env": {
        "GESTION_API_KEY": "${GESTION_API_KEY}",
        "GESTION_TOKEN": "${GESTION_TOKEN}"
      }
    },
    "serveur-ia": {
      "command": "uvx",
      "args": ["mcp-ia-server"],
      "env": {
        "IA_API_KEY": "${IA_API_KEY}"
      }
    }
  }
}

Quiconque ouvre ce fichier ne voit plus que des noms de variables.

4. Deny rules, ceinture et bretelles

Claude Code peut lire n'importe quel fichier de la machine, y compris ~/.env.claude. Une hallucination ou une prompt injection via un MCP douteux suffirait à l'y pousser. Dans ~/.claude/settings.json :

{
  "permissions": {
    "deny": [
      "Edit(~/.env.claude)",
      "Read(~/.env.claude)",
      "Edit(~/.ssh/**)",
      "Edit(~/.aws/**)",
      "Read(~/.ssh/id_*)",
      "Read(~/.aws/credentials)"
    ]
  }
}

Defense in depth : même si tout le reste échoue, la lecture du fichier se heurte à un mur.

Vérifier que ça marche

Relancez le shell (exec fish / source ~/.bashrc), puis :

# Les variables sont-elles chargées ?
echo $MON_SERVEUR_API_KEY
# Doit afficher la clé

# Le fichier secrets est-il bien protégé ?
ls -la ~/.env.claude
# Doit afficher -rw------- (600)

# Plus de secrets en dur dans mcp.json ?
grep -c "sk-\|token_\|AIza" ~/.claude/mcp.json
# Doit afficher 0

Si un serveur MCP refuse de démarrer, la variable n'est probablement pas exportée dans l'environnement — un env | grep MON_SERVEUR le confirme.

Quelques compléments

Rotation des clés : renouveler une clé revient à changer une ligne dans ~/.env.claude et relancer le shell, au lieu d'éditer le JSON en priant pour ne pas casser la syntaxe.

Plusieurs environnements : rien n'empêche d'avoir ~/.env.claude.perso, ~/.env.claude.work, ~/.env.claude.client-x et de charger le bon via un alias.

Le .gitignore, si vous avez un dossier .claude/ dans un projet versionné :

# Claude Code
.env.claude*
.claude/settings.local.json

HTTP Hooks : depuis début 2026, les hooks HTTP ("type": "http") interpolent aussi des variables d'environnement via allowedEnvVars. Même réflexe — jamais de token en dur, et une liste de variables autorisées réduite au strict nécessaire.

Récapitulatif

  1. ~/.env.claude — toutes les clés, chmod 600
  2. mcp.json — que des ${VAR}, zéro secret
  3. settings.json — deny rules sur le fichier secrets
  4. Shell config — loader automatique au démarrage

Vu les CVE de février et l'accès grandissant des agents IA à nos machines, sécuriser ses clés MCP n'est pas de l'excès de zèle mais de l'hygiène de base — et ça prend quinze minutes.

PartagerLinkedInXBluesky

Articles similaires