Votre assistant de codage IA fuit des secrets
May 12, 2026
Les assistants de bureau IA et les outils de codage ont besoin de justificatifs pour accéder aux services externes, et beaucoup d'entre eux stockent ces justificatifs sous forme de JSON en clair à des emplacements prévisibles dans le répertoire personnel de l'utilisateur. Cette recherche couvre le fonctionnement du stockage des justificatifs dans 14 outils IA populaires, où l'intégration du trousseau OS est présente ou absente, ainsi que huit scénarios d'attaque qui transforment cette exposition en risque réel, du vol par malware au détournement de session à distance en passant par la compromission de la chaîne d'approvisionnement via les serveurs MCP.
Comment Claude, Copilot, Cursor et d’autres outils d’IA stockent les identifiants en clair et 8 exemples d’exploitation par des attaquants
Le problème
Les applications de bureau IA doivent s’authentifier auprès de services externes. Claude Code a besoin de vos tokens OAuth. GitHub Copilot a besoin de votre authentification GitHub. Continue.dev a besoin de vos clés API. Les serveurs MCP ont besoin de tokens pour Azure DevOps, Slack, bases de données et tout ce que vous avez connecté. Où vont toutes ces informations d’identification ? Principalement dans des fichiers JSON en clair dans votre répertoire personnel. Ces fichiers se trouvent dans des emplacements connus ou prévisibles, ce qui les rend faciles à trouver avec un accès en lecture à un système.
Ce que j'ai trouvé
J'ai exploré 14 outils d'IA populaires (voir la référence à la fin du blog) sur Windows, macOS et Linux. Ce sont les éléments qui m'ont le plus marqué.
Claude Code CLI
~/.claude/.credentials.json contient vos jetons d'accès et de rafraîchissement OAuth en JSON en texte clair:
{
"claudeAi": {
"type": "oauth",
"access": "sk-ant-oat01-...",
"refresh": "sk-ant-ort01-...",
"expires": 1776098433694
}
}
Sous Linux, le fichier est créé avec des permissions 0600 (lecture/écriture uniquement pour le propriétaire). Sur macOS, les identifiants sont stockés dans le trousseau (Keychain). Mais sous WSL, le fichier côté Windows hérite des permissions par défaut 0777 rendant vos jetons OAuth Claude accessibles en lecture par tous pour n'importe quel processus du système. Le jeton de rafraîchissement est celui vraiment dangereux ici. Il est à longue durée de vie et peut générer indéfiniment de nouveaux jetons d'accès. Un attaquant qui l'obtient a un accès persistant à votre compte Claude jusqu'à ce que vous le révoquiez explicitement.
Configurations du serveur MCP : le problème d'agrégation
Les serveurs Model Context Protocol (MCP) permettent aux assistants IA de se connecter à des outils externes. Chaque connexion nécessite une authentification, et ces jetons se retrouvent généralement dans un seul fichier de configuration comme celui-ci :
{
"mcpServers": {
"github": { "env": { "GITHUB_TOKEN": "ghp_realToken..." } },
"azure": { "env": { "ADO_MCP_AUTH_TOKEN": "eyJ0eX..." } },
"slack": { "env": { "SLACK_BOT_TOKEN": "xoxb-..." } },
"database": { "env": { "DB_PASSWORD": "prod_password" } }
}
}
Un fichier. Plusieurs services. Une seule opération de lecture peut tous les compromettre. Trend Micro a constaté que 48 % des 19 402 implémentations de serveurs MCP recommandent le stockage des identifiants en texte clair.
Continue.dev : clés API en texte clair
Continue.dev stocke chaque clé API configurée directement dans ~/.continue/config.json:
{
"models": [{
"provider": "anthropic",
"apiKey": "sk-ant-api03-YOUR-ACTUAL-KEY"
}]
}
La communauté reconnaît cela comme un problème (issue GitHub #1729). La substitution des variables d'environnement est prise en charge (${VAR_NAME}) mais ce n'est pas le comportement par défaut.
Cline : identifiants synchronisés dans le cloud
Les paramètres MCP de Cline se trouvent dans un fichier JSON non chiffré dans le globalStorage de VS Code. Le problème est que VS Code Settings Sync télécharge automatiquement ce fichier sur GitHub. Si vous avez activé Settings Sync, vos identifiants MCP sont stockés dans le cloud de GitHub.
La confusion autour de VS Code SecretStorage
GitHub Copilot, Cline et d'autres extensions VS Code utilisent l'API SecretStorage, qui chiffre les secrets dans une base de données SQLite (state.vscdb) en utilisant AES-128-CBC. Cela semble sécurisé jusqu'à ce que vous réalisiez que :
- Les extensions VS Code s’exécutent sans sandboxing
- La clé de chiffrement se trouve dans le trousseau du système d’exploitation, accessible par tout processus au niveau utilisateur
- Toute extension malveillante peut lire les secrets des autres extensions
- Le système d’identification des extensions est vulnérable à la falsification
Le chiffrement protège contre l'accès hors ligne au disque, mais pas contre un processus s'exécutant sous le même utilisateur.
Exemples de surface d'attaque
J'ai identifié 8 scénarios d'attaque réels que je voulais souligner, rendus possibles par l'exposition des identifiants IA.
1. Vol d’identifiants via un malware
Les chemins des fichiers sont prévisibles et cohérents entre les installations :
~/.claude/.credentials.json
~/.continue/config.json
~/.aws/credentials
~/.config/gcloud/application_default_credentials.json
~/Library/Application Support/Claude/claude_desktop_config.json
~/.claude.json
Les malwares Infostealer ciblent déjà les cookies de navigateur, les clés SSH et les identifiants cloud. Ajouter quelques chemins d’outils d’IA à la liste des cibles est trivial. Aucune escalade de privilèges n’est requise ; une lecture de fichiers au niveau utilisateur standard suffit.
Une seule infection par un malware pourrait compromettre les tokens Claude OAuth, toutes les clés API dans Continue.dev, chaque token de serveur MCP et les identifiants AWS. Les chemins sont les mêmes sur chaque installation de chaque outil.
Risque : CRITIQUE. Forte probabilité, fort impact.
2. Détournement d'une session de contrôle à distance Claude Code
C'est le scénario qui devrait vous effrayer. Claude Code dispose d'une fonction Remote Control (claude remote-control) qui permet aux utilisateurs de contrôler leur session locale Claude Code depuis un téléphone, une tablette ou un navigateur via claude.ai/code. Toute l'exécution du code reste sur la machine locale. L'appareil distant est juste une interface de contrôle.
Voici le problème : la connexion à distance ne nécessite pas de ré-authentification. Une fois la session active, toute personne disposant de l'URL de la session peut envoyer des instructions. Et toutes ces instructions sont exécutées localement sur la machine du développeur.
Combinez cela maintenant avec --dangerously-skip-permissions.
Ce paramètre désactive toutes les invites de permission interactives. Les écritures de fichiers, commandes shell, requêtes réseau, appels aux outils MCP, tout s'exécute automatiquement sans demander à l'utilisateur. Il est destiné aux conteneurs CI/CD isolés, mais parfois les utilisateurs l'utilisent sur leurs postes de travail par commodité. Il peut également être défini comme valeur par défaut persistante dans settings.json via "defaultMode": "bypassPermissions".
La chaîne d'attaque :
- L'attaquant vole les jetons OAuth depuis
~/.claude/.credentials.json(via malware, SSRF ou toute vulnérabilité de lecture de fichiers) - Les jetons sont portables, ils fonctionnent donc depuis n'importe quelle machine
- Si la victime a une session Remote Control active, l'attaquant se connecte et prend le contrôle
- If the victim runs with
--dangerously-skip-permissions, the attacker now has unrestricted shell access as the victim's user:- Lire/écrire n'importe quel fichier sur le système
- Exécuter des commandes arbitraires (
curl,ssh,docker, gestionnaires de paquets, etc.) - Installer des portes dérobées, exfiltrer des données, pivoter vers d'autres machines
- Accédez aux clés SSH, aux identifiants cloud et à tous les autres secrets du système
- Modifier les dépôts git, les pipelines CI/CD et les configurations de déploiement
Même sans --dangerously-skip-permissions, Claude Code en acceptEdits mode approuve automatiquement les modifications de fichiers et les commandes courantes du système de fichiers. Cela peut toujours être dangereux. Le modèle de permissions a été conçu pour protéger contre les actions accidentelles, pas contre un acteur malveillant contrôlant la session.
Risque : CRITIQUE (avec --dangerously-skip-permissions), ÉLEVÉ (autorisations par défaut).
3. Mouvement latéral via les jetons Claude OAuth
Un attaquant qui obtient un jeton de rafraîchissement OAuth Claude depuis ~/.claude/.credentials.json peut :
- Générez de nouveaux jetons d'accès à distance (les jetons d'accès expirent en ~60 minutes, mais le jeton de rafraîchissement est à longue durée de vie)
- Accédez aux conversations Claude et aux fichiers de l’espace de travail de la victime
- Utilisez tous les serveurs MCP que la victime a configurés (en accédant à leurs dépôts GitHub, projets Azure DevOps, espaces de travail Slack et bases de données via l'assistant IA comme proxy)
Les jetons sont portables. Copiez le fichier d’identifiants sur une autre machine, et Claude Code l’utilisera. Anthropic met en œuvre la rotation des jetons de rafraîchissement, donc l’utilisation d’un jeton volé peut éventuellement invalider l’original, mais la première utilisation réussit et l’attaquant peut accéder avant que la rotation ne commence.
Risque : ÉLEVÉ. Probabilité moyenne-élevée, impact élevé.
4. Agrégation de jetons MCP : mouvement latéral
Un seul fichier de configuration MCP agrège des jetons pour plusieurs services externes. Par exemple, un fichier pourrait produire :
GITHUB_PERSONAL_ACCESS_TOKEN→ dépôts de code, PR, CI/CDADO_MCP_AUTH_TOKEN→ projets Azure DevOpsSLACK_BOT_TOKEN→ espace de travail Slack interne- Mots de passe de base de données → données de production
JIRA_API_TOKEN→ gestion de projet, tickets internes
Contrairement au stockage distribué des identifiants où compromettre un canal expose seulement un sous-ensemble d’identifiants, le modèle d’agrégation de MCP signifie qu’une divulgation d’un seul fichier entraîne la compromission de tous les services connectés.
Risque : CRITIQUE. Forte probabilité, fort impact.
5. Extension malveillante de VS Code : exfiltration des identifiants
Les extensions VS Code s'exécutent sans sandboxing. Toutes les extensions partagent les mêmes autorisations de processus. Une extension malveillante ou compromise peut :
- Accédez directement à la base de données SQLite
state.vscdb - Récupérez la clé de chiffrement depuis le trousseau du système d'exploitation (accessible par tout processus au niveau utilisateur)
- Déchiffrer tous les secrets d’extension : jetons Copilot, clés API Cline, identifiants MCP
Le fichier cline_mcp_settings.json n'a même pas besoin de déchiffrement. C'est du texte en clair non chiffré dans le globalStorage de VS Code, et il est synchronisé dans le cloud via Settings Sync.
Les champs publisher et name de package.json qui identifient les extensions sont vulnérables à l’usurpation, ce qui rend possible l’imitation d’extensions légitimes.
Risque : ÉLEVÉ. Probabilité moyenne, impact élevé.
6. Escalade des permissions WSL
Les développeurs utilisant WSL sont touchés des deux côtés. Les outils d’IA installés sur Windows stockent les identifiants sous C:\Users\<you>\, qui est monté dans WSL en tant que /mnt/c/Users/<you>/ avec des permissions 0777 par défaut. Le même fichier d’identifiants protégé par NTFS côté Windows est accessible en lecture par tous depuis le côté Linux.
Dans les environnements WSL multi-utilisateurs ou les conteneurs compromis, cela est facile à exploiter. Tout processus s'exécutant sur le système WSL peut lire les jetons Claude OAuth, les configurations MCP, etc., stockés côté Windows.
Risque : ÉLEVÉ pour les utilisateurs WSL. Forte probabilité, impact moyen-élevé.
7. .mcp.json engagé dans git : crexfiltration des identifiants
Le fichier .mcp.json à la racine du dépôt est conçu pour être versionné afin que les équipes puissent partager les configurations du serveur MCP. Si un développeur inclut des jetons en ligne au lieu de références aux variables d'environnement :
- Les jetons apparaissent dans l'historique git
- Même après suppression,
git log -p .mcp.jsonles révèle - Les scanners automatisés (TruffleHog, GitLeaks, etc.) peuvent les trouver à grande échelle sur GitHub/GitLab
Le partenariat de scan secret entre Anthropic et GitHub détecte certaines clés API exposées, mais les jetons de configuration MCP pour d'autres services (Azure DevOps, Slack, bases de données) ne sont pas couverts par le scan automatisé. Il n'existe pas de modèle de scanner secret GitHub pour ADO_MCP_AUTH_TOKEN ou SLACK_BOT_TOKEN intégrés dans les blocs JSON env.
Risque : MOYEN. Probabilité moyenne, impact moyen-élevé.
8. Attaque de la chaîne d'approvisionnement via les serveurs MCP
Les serveurs MCP sont souvent des packages npm. Le risque de la chaîne d'approvisionnement est le même que pour toute dépendance npm, mais avec une différence critique : Les serveurs MCP reçoivent des identifiants au démarrage.
- Le paquet serveur MCP populaire sur npm est compromis (ou un typosquat est publié)
- Les utilisateurs le configurent dans leur
claude_desktop_config.jsonavec des jetons réels dans leenvbloc - Le processus du serveur MCP a accès à toutes les variables d'environnement qui lui sont transmises, y compris les jetons
- Serveur compromis exfiltre des jetons vers l'infrastructure de l'attaquant
Sans une validation appropriée de l’audience OAuth 2.1 (RFC 8707), un serveur MCP malveillant pourrait également recevoir des jetons d’accès et les rejouer contre d’autres services (attaque par passage de jeton).
La statistique de 48 % de credentials en texte clair signifie que près de la moitié de toutes les configurations de serveurs MCP transmettent les credentials directement au processus serveur au lancement. Si ce processus serveur est compromis, chaque utilisateur qui l’a installé est également compromis.
Risque : MOYEN. Probabilité faible à moyenne, impact élevé.
Bonus : vol de jeton CI/CD
La commande claude setup-token génère un jeton OAuth d’une durée de un an (CLAUDE_CODE_OAUTH_TOKEN) pour les pipelines CI/CD. Cela crée un risque unique :
- Le jeton fonctionne depuis n'importe quelle machine pendant jusqu'à un an
- Les systèmes CI/CD ont souvent une gestion faible des secrets et un isolement limité des tâches
- Les journaux de build peuvent accidentellement exposer les valeurs des variables d’environnement
- Un runner CI/CD compromis donne un accès prolongé à Claude avec les permissions que le pipeline exécute
Si votre pipeline CI/CD exécute Claude Code avec --dangerously-skip-permissions (comme beaucoup pour l'automatisation), un CLAUDE_CODE_OAUTH_TOKEN volé accorde une exécution shell illimitée sur toute machine où le jeton est utilisé.
Risque : ÉLEVÉ. Probabilité moyenne, impact élevé.
Ce qui doit changer
Pour les utilisateurs (pour l'instant)
- Exécutez AIHound. Sachez ce qui est exposé sur votre machine.
- Corrigez les permissions :
chmod 600sur les fichiers d'identification. - N'utilisez jamais
**--dangerously-skip-permissions**sur des machines avec des identifiants réels ou un accès réseau. Si vous en avez besoin, utilisez-le dans un conteneur isolé sans secrets montés. - Utilisez des références de variables d'environnement dans les configurations MCP au lieu des jetons en ligne :
"env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" }
- Faire pivoter les jetons qui ont été dans des fichiers lisibles par tous ou dans l’historique git.
- Désactiver la synchronisation des paramètres de VS Code si vous utilisez Cline avec des serveurs MCP.
- Traitez
**CLAUDE_CODE_OAUTH_TOKEN**comme un mot de passe root. Faites-le tourner régulièrement, ne le mettez jamais dans les journaux de build et limitez les permissions CI/CD au minimum nécessaire. - Ajoutez
**.mcp.json**à**.gitignore**s’il contient des secrets en ligne.
Pour les créateurs d'outils
- Utilisez les trousseaux de clés du système d'exploitation. macOS Keychain, Windows Credential Manager et Linux libsecret existent précisément à cet effet. Ne stockez jamais les identifiants en JSON en clair.
- Créez des fichiers avec
**0600**permissions. Pas0644ni0777. - Avertir les utilisateurs lorsque vous détectez des secrets en ligne dans les configurations MCP.
- Ne synchronisez pas les identifiants dans le cloud via les mécanismes de synchronisation des paramètres.
- Implémentez OAuth 2.1 avec une validation appropriée de l’audience du jeton pour les serveurs MCP distants.
- Exiger une ré-authentification pour les sessions de Remote Control. Une URL de session ne doit pas être un jeton porteur pour l'exécution arbitraire de code.
- Auditer les packages serveur MCP avant d’autoriser l’installation et prendre en charge la liste blanche des serveurs.
Pour l'écosystème
Le OWASP MCP Top 10 liste « Mauvaise gestion des jetons et exposition des secrets » comme MCP01-2025. Le partenariat entre Anthropic et GitHub pour la détection automatique des clés API sur GitHub est un excellent début, mais il ne couvre que les clés Anthropic dans les dépôts publics. Les jetons MCP pour Azure DevOps, Slack, bases de données et autres services ne bénéficient d’aucune protection équivalente.
Nous avons besoin de :
- Analyse des secrets qui couvre les modèles de configuration MCP, pas seulement les formats de clés API
- Assistants d'identifiants pour MCP (similaire aux assistants d'identifiants git) qui récupèrent les jetons depuis un stockage sécurisé à l'exécution
- Intégration obligatoire du trousseau OS par défaut
- Sandboxing pour les extensions VS Code
- Contrôle à distance à portée de jeton - Les sessions à distance doivent nécessiter leur propre authentification, sans hériter de toutes les capacités de la session locale
Le résultat
L'écosystème des outils d'IA a évolué rapidement pour déployer des fonctionnalités et a laissé la sécurité des identifiants un peu en arrière-plan. Près de la moitié des serveurs MCP stockent les identifiants en clair. Les assistants IA conservent les jetons OAuth dans des fichiers JSON sur disque. Les fonctionnalités de Remote Control permettent à ces jetons de devenir une exécution de code à distance. Et --dangerously-skip-permissions transforme un identifiant volé en un accès shell complet sur la machine de quelqu'un d'autre. Plus vous connectez d'outils, plus votre risque augmente. Beaucoup d'identifiants IA ne sont pas stockés de manière sécurisée, alors assurez-vous de mettre en œuvre les meilleures pratiques pour le stockage des identifiants. Des outils comme AIHound peuvent vous aider à trouver ces identifiants en clair sur vos systèmes.
Emplacements de stockage des identifiants des applications de bureau AI à titre de référence
Cette référence recense chaque emplacement où certaines des applications de bureau d'IA les plus populaires, assistants de codage et outils CLI stockent les identifiants sur le disque.
Claude Code CLI
Développeur : Anthropic Méthode d'authentification : OAuth 2.0 (abonnement Claude.ai) ou clé API
Fichiers d'identification
Platform | Path | Format | Encryption | Contents |
|---|---|---|---|---|
|
Linux |
|
JSON
|
Plaintext (mode 0600) |
OAuth access/refresh tokens, multi-provider auth |
|
macOS |
Keychain: |
Keychain |
OS Keychain (encrypted) |
OAuth access/refresh tokens |
|
Windows |
|
JSON
|
Plaintext (NTFS ACLs) |
OAuth access/refresh tokens |
|
WSL |
Both Linux path AND |
JSON
|
Plaintext (often 0777 via mount) |
Same as above |
Credential file structure
{
"claudeAi": {
"type": "oauth",
"access": "sk-ant-oat01-...",
"refresh": "sk-ant-ort01-...",
"expires": 1776098433694
}
}
Every OAuth connection stores its own entry. The file contains credentials for Claude.ai, Claude API, Azure Auth, Bedrock Auth, and Vertex Auth depending on what the user has configured.
Key finding: On WSL, the Windows-side credential file inherits the mount's default permissions (0777), making it world-readable, which is a CRITICAL risk that doesn't exist on native Linux where the file is created with 0600.
Configuration files with potential secrets
Path | Contents |
|---|---|
|
|
Global MCP server configurations (may contain inline tokens) |
|
|
Project-scoped MCP server configs |
|
|
User preferences and permissions |
Authentication precedence order
Claude Code checks credentials in this order (first match wins):
- Cloud provider env vars (
CLAUDE_CODE_USE_BEDROCK, CLAUDE_CODE_USE_VERTEX,CLAUDE_CODE_USE_FOUNDRY) ANTHROPIC_AUTH_TOKENenvironment variableANTHROPIC_API_KEYenvironment variableapiKeyHelperscript output (for dynamic/rotating credentials)CLAUDE_CODE_OAUTH_TOKENenvironment variable (long-lived, fromclaude setup-token)- OAuth credentials from
~/.claude/.credentials.jsonor Keychain
Known bug
A documented bug (GitHub issue #36779) shows that OAuth credentials are not properly persisted to macOS Keychain. Only the mcpOAuth field is stored while the primary auth token is missing, forcing re-authentication in new sessions.
Claude Desktop
Developer: Anthropic
Platform | Paths |
|---|---|
|
macOS |
|
|
Windows |
|
|
Linux |
|
Auth method: Claude.ai session (Keychain-backed on macOS)
Configuration files
Platform | Path | Format | Encryption |
|---|---|---|---|
|
macOS |
|
JSON |
Plaintext (often 0644) |
|
Windows |
|
JSON
|
Plaintext |
|
Linux |
|
JSON
|
Plaintext |
MSIX virtualization issue (Windows)
On Windows, the MSIX installer creates filesystem virtualization. The "Edit Config" button opens %APPDATA%\Claude\claude_desktop_config.json, but the application may actually read from a virtualized path inside the MSIX container. This means:
- Users may edit the wrong file
- MCP server configurations are silently ignored
- No error messages indicate the problem
Pre-MSIX installations are grandfathered and read from the real AppData path.
What's in the config
The config file primarily holds MCP server definitions:
{
"mcpServers": {
"azure-devops": {
"command": "npx",
"args": ["-y", "@anthropic/azure-devops-mcp"],
"env": {
"ADO_MCP_AUTH_TOKEN": "actual-token-here"
}
}
}
}
The env block frequently contains plaintext tokens for external services.
GitHub Copilot
Developer: GitHub / Microsoft Auth method: GitHub OAuth
Credential storage
Platform | Location | Format | Encryption |
|---|---|---|---|
|
macOS |
Keychain: |
Keychain |
OS Keychain |
|
Windows |
Credential Manager |
Credential Manager |
DPAPI |
|
Linux (with libsecret) |
GNOME Keyring / KWallet |
libsecret |
OS-level |
|
Linux (no libsecret) |
|
JSON |
Plaintext (fallback) |
VS Code extension storage
Platform | Path |
|---|---|
|
Linux |
|
|
macOS |
|
|
Windows |
|
The state.vscdb file is a SQLite database encrypted with Electron's safeStorage API (AES-128-CBC). However, security research has shown this is vulnerable to malicious VS Code extensions. Any extension can access other extensions' secrets due to lack of sandboxing.
The encryption key is stored in the OS keychain (Code Safe Storage on macOS), accessible by any process with user permissions.
Token types
Prefix | Type | Supported |
|---|---|---|
|
|
OAuth token (default via |
Yes |
|
|
Fine-grained PAT (needs "Copilot Requests" permission) |
Yes |
|
|
GitHub App user-to-server token |
Yes (env var only) |
|
ghp_ |
Classic PAT
|
Not supported |
GitHub CLI auth (also used by Copilot)
Platform | Path | Format |
|---|---|---|
|
Linux |
|
YAML |
|
macOS |
|
YAML |
|
Windows |
|
YAML |
Cursor IDE
Developer: Anysphere Auth method: Cursor account + optional API keys
Storage locations
Platform | Paths |
|---|---|
|
macOS |
|
|
Windows |
|
|
Linux |
|
MCP configuration
~/.cursor/mcp.json, which follows the same mcpServers JSON structure as Claude Desktop. May contain inline auth tokens.
Known issues
Cursor stores conversation logs with world-readable permissions. These logs can contain credentials if users paste tokens into the chat interface.
Continue.dev
Developer: Continue (open source) Auth method: Direct API keys per provider
Configuration files
Platform | Path | Format | Encryption |
|---|---|---|---|
|
All |
|
JSON
|
Plaintext |
|
All |
|
YAML
|
Plaintext |
Credential format
{
"models": [
{
"title": "Claude 3.5 Sonnet",
"provider": "anthropic",
"model": "claude-3-5-sonnet-20241022",
"apiKey": "sk-ant-api03-ACTUAL-KEY-HERE"
}
]
}
All API keys are stored in plaintext at the user root. This is acknowledged by the Continue.dev community as a security concern (GitHub issue #1729).
Mitigation
Continue.dev supports environment variable substitution:
"apiKey": "${CONTINUE_ANTHROPIC_API_KEY}"
It checks .env files at the project root and custom locations specified via envFiles. However, the default behavior is plaintext if env vars aren't configured.
Cline (VS Code extension)
Developer: Saoud Rizwan Extension ID: saoudrizwan.claude-dev
MCP settings (plaintext)
Platform | Path |
|---|---|
|
macOS |
|
|
Windows |
|
|
Linux |
|
Critical: These files are plaintext JSON and are automatically synced to the cloud through VS Code Settings Sync. This means API keys and MCP credentials get uploaded to GitHub if sync is enabled.
API key storage
Cline stores API keys through VS Code's SecretStorage API (the same AES-128-CBC encrypted state.vscdb used by Copilot). Subject to the same malicious extension vulnerability.
Windsurf / Codeium
Developer: Codeium Auth method: Codeium account
Storage locations
Platform | Path |
|---|---|
|
All |
|
Look for config.json, auth.json, credentials.json within this directory.
MCP configuration
~/.codeium/windsurf/mcp_config.json with the same mcpServers structure.
Credential details are not well-documented publicly. Authentication appears to go through Codeium's centralized backend rather than local token storage in many cases.
ChatGPT Desktop
Developer: OpenAI Auth method: OpenAI account session
Storage locations
Platform | Path | Encryption |
|---|---|---|
|
macOS |
|
Keychain for session |
|
macOS |
|
Keychain for session |
|
Windows |
|
Credential Manager |
|
Windows |
|
Credential Manager |
ChatGPT Desktop primarily uses OS credential stores (Keychain on macOS, Credential Manager on Windows) for session tokens. JSON config files in the app data directory may also contain session data.
Amazon Q Developer / AWS
Developer: Amazon Web Services Auth method: IAM Identity Center / AWS Builder ID / IAM credentials
Credential files
Path | Format | Contents |
|---|---|---|
|
|
INI
|
Plaintext access key ID, secret access key, session token (per profile) |
|
|
INI |
Region, output format, SSO configuration |
|
|
JSON |
Plaintext SSO access tokens (cached) |
Credential file structure
[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
aws_session_token = FwoGZXIvYXdzEBY...
Notes
- Amazon Q itself authenticates through IAM Identity Center or Builder ID, not through local file storage
- Default SSO session duration is 90 days (for setups created after April 2024)
- Static credentials in
~/.aws/credentialsare the primary risk. Consider using SSO/IAM Identity Center instead
Google Gemini CLI / GCloud
Developer: Google Auth method: Google account OAuth, API key, or service account
API key storage
Location | Format | Contents |
|---|---|---|
|
|
Environment variable |
Gemini API key |
|
|
Environment variable |
Google API key |
|
|
Dotenv |
API keys |
|
|
Dotenv |
API keys |
Application default credentials (ADC)
Platform | Path | Format |
|---|---|---|
|
Linux |
|
JSON |
|
macOS |
|
JSON |
|
macOS (alt) |
|
JSON |
|
Windows |
|
JSON |
ADC files contain client_secret, refresh_token, and potentially private_key (for service accounts) in plaintext JSON.
Authentication methods
Method | How | Local Storage |
|---|---|---|
|
Sign in with Google |
|
Cached locally for future sessions |
|
Gemini API Key |
|
Environment or |
|
Service Account |
|
JSON key file on disk |
|
ADC via gcloud |
|
|
|
Cloud Shell |
Automatic (metadata server) |
No local storage |
OpenClaw
Developer: OpenClaw (open source) Auth method: OAuth 2.0 per provider, API keys, channel-specific tokens
Overview
OpenClaw is a local-first AI agent platform that connects to 20+ messaging channels (WhatsApp, Telegram, Slack, Discord) and executes tools on the local machine. It stores credentials for both LLM providers and messaging channels.
Credential files
Path | Format | Encryption | Contents |
|---|---|---|---|
|
|
JSON
|
Plaintext (0600) |
OAuth access/refresh tokens + API keys per LLM provider |
|
|
JSON
|
Plaintext |
WhatsApp Baileys auth state |
|
|
JSON
|
Plaintext |
Legacy OAuth tokens (migration file) |
|
|
JSON |
Plaintext |
Channel pairing allowlists |
|
|
JSON
|
Plaintext |
Optional secrets payload for SecretRef resolution |
|
|
JSON5
|
Plaintext |
Main config with gateway auth token, channel tokens, agent API keys |
|
|
Dotenv
|
Plaintext |
Environment variable overrides (may contain API keys) |
Auth profile structure
Each agent has its own auth-profiles.json containing provider credentials:
{
"anthropic": {
"accessToken": "sk-ant-...",
"refreshToken": "sk-ant-ort01-...",
"expiresAt": 1776098433694
},
"openai": {
"apiKey": "sk-proj-..."
}
}
All tokens are stored in plaintext JSON by default. No OS keychain integration.
SecretRef system (opt-in)
OpenClaw supports an opt-in SecretRef system that replaces plaintext values with references to external sources:
Provider | Example | Description |
|---|---|---|
|
|
|
Reads from environment variable |
|
|
|
Reads from file (JSON pointer or single value) |
|
|
|
Runs vault-like executable |
Users must run openclaw secrets configure to scrub existing plaintext values and migrate to SecretRefs. The default behavior is plaintext storage.
Gateway authentication
The gateway uses a token for local access control:
{
"gateway": {
"auth": {
"mode": "token",
"token": "long-random-string-here"
}
}
}
This token can be a SecretRef but is commonly hardcoded in openclaw.json.
Known security issues
Issue | Severity | Details |
|---|---|---|
|
Plaintext credential storage |
HIGH |
OAuth tokens and API keys in
|
|
Agent tool bypass |
HIGH |
Agents with filesystem/exec tools can |
|
Tailscale exposure |
MEDIUM |
Remote access via Tailscale could expose the local gateway if token auth isn't configured
|
|
OAuth refresh failures |
MEDIUM |
Silent token refresh failures, Anthropic token truncation bugs
|
|
Session persistence |
LOW |
WhatsApp sessions not always persisted across restarts |
Credential locations summary
All files live under ~/.openclaw/ on all platforms (Linux, macOS, Windows). On WSL, both Linux-native and Windows-mounted paths should be checked.
MCP server configurations
Config file locations
Tool | Path | Scope |
|---|---|---|
|
Claude Desktop (macOS) |
|
Application |
|
Claude Desktop (Windows) |
|
Application |
|
Claude Code (local) |
|
User (private) |
|
Claude Code (project) |
|
Repository (shared) |
|
Cursor |
|
User |
|
VS Code |
|
Workspace |
|
Cline |
|
Extension |
Common MCP auth environment variables
Variable | Service |
|---|---|
|
|
Azure DevOps |
|
|
GitHub |
|
|
GitHub |
|
|
Slack |
|
|
Atlassian Jira |
|
|
Notion |
|
|
Linear |
Environment variables
The following environment variables are commonly set by users or tools and contain AI-related secrets:
Anthropic / Claude
Variable | Description |
|---|---|
|
|
Anthropic API key ( |
|
|
Bearer auth token |
|
|
Long-lived OAuth token (from |
OpenAI
Variable | Description |
|---|---|
|
|
OpenAI API key ( |
|
|
Organization identifier |
Variable | Description |
|---|---|
|
|
Gemini API key |
|
|
Google API key ( |
|
|
Path to service account JSON key file |
GitHub
Variable | Description |
|---|---|
|
|
GitHub token |
|
|
GitHub CLI token |
|
|
GitHub PAT |
|
|
Copilot-specific token |
AWS
Variable | Description |
|---|---|
|
|
AWS access key ( |
|
|
AWS secret key |
|
|
Temporary session token |
Azure
Variable | Description |
|---|---|
|
|
Azure DevOps MCP token |
|
|
Azure OpenAI key |
Other AI providers
Variable | Description |
|---|---|
|
|
Hugging Face |
|
|
Cohere |
|
|
Replicate |
|
|
Together AI |
|
|
Groq |
|
|
Mistral AI |
|
|
DeepSeek |
|
|
xAI / Grok |
|
|
Perplexity |
|
|
Fireworks AI |
Partager sur
En savoir plus
À propos de l'auteur
Darryl Baker
Chercheur principal en sécurité
Darryl G. Baker est un chercheur principal en sécurité chez Netwrix et une autorité reconnue en sécurité de l’Identity et d’Active Directory. Avec plus d’une décennie d’expérience dans les systèmes d’identité, il a dirigé des évaluations de sécurité d’entreprise, des formations en sécurité de l’identité et des émulations de menaces axées sur Active Directory, Entra ID et les environnements Azure. Darryl a donné des formations et des démonstrations très appréciées lors de BlueTeamCon, BSidesCT, The Experts Conference et Wild Wild West Hackin’ Fest. Il est l’architecte de nombreux laboratoires pratiques d’émulation d’attaques, utilisant les outils actuels des red teams et blue teams pour aider les défenseurs à maîtriser tout, de l’analyse des chemins d’attaque à la chasse aux menaces. Lors de ses sessions, Darryl allie une profonde expertise technique à des études de cas réels, permettant aux professionnels du blue team de renforcer leur posture de sécurité de l’identité et de se défendre contre les techniques adverses en évolution.