Tu asistente de codificación IA está filtrando secretos
May 12, 2026
Los asistentes de escritorio de IA y las herramientas de codificación necesitan credenciales para acceder a servicios externos, y muchas de ellas almacenan esas credenciales como JSON en texto plano en rutas predecibles dentro del directorio personal del usuario. Esta investigación cubre cómo funciona el almacenamiento de credenciales en 14 herramientas populares de IA, dónde está presente o ausente la integración con el llavero del sistema operativo, y ocho escenarios de ataque que convierten esa exposición en un riesgo real, desde el robo basado en malware hasta el secuestro de sesiones remotas y la compromisión de la cadena de suministro a través de servidores MCP.
Cómo Claude, Copilot, Cursor y otras herramientas de IA almacenan credenciales en texto plano y 8 ejemplos de cómo los atacantes las explotan
El problema
Las aplicaciones de escritorio de IA necesitan autenticarse con servicios externos. Claude Code necesita tus tokens OAuth. GitHub Copilot necesita tu autenticación de GitHub. Continue.dev necesita tus claves API. Los servidores MCP necesitan tokens para Azure DevOps, Slack, bases de datos y todo lo demás que hayas conectado. ¿Dónde van todas estas credenciales? Principalmente en archivos JSON de texto plano en tu directorio personal. Estos archivos están en ubicaciones conocidas o predecibles, lo que facilita encontrarlos con acceso de lectura a un sistema.
Lo que encontré
Exploré 14 herramientas populares de IA (ver referencia al final del blog) en Windows, macOS y Linux. Estas son las cosas que más me llamaron la atención.
Claude Code CLI
~/.claude/.credentials.json contiene sus tokens de acceso y actualización OAuth en JSON en texto plano:
{
"claudeAi": {
"type": "oauth",
"access": "sk-ant-oat01-...",
"refresh": "sk-ant-ort01-...",
"expires": 1776098433694
}
}
En Linux, el archivo se crea con permisos 0600 (solo lectura/escritura para el propietario). En macOS, las credenciales se almacenan en el Keychain. Pero en WSL, el archivo del lado de Windows hereda los permisos predeterminados 0777 haciendo que tus tokens OAuth de Claude sean legibles para todo el mundo para cualquier proceso en el sistema. El token de actualización es el realmente peligroso aquí. Tiene una larga duración y puede generar nuevos tokens de acceso indefinidamente. Un atacante que lo obtenga tendrá acceso persistente a tu cuenta de Claude hasta que lo revokes explícitamente.
Configuraciones del servidor MCP: el problema de la agregación
Los servidores Model Context Protocol (MCP) permiten que los asistentes de IA se conecten a herramientas externas. Cada conexión requiere autenticación, y esos tokens normalmente terminan en un único archivo de configuración como este:
{
"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 archivo. Múltiples servicios. Una operación de lectura puede comprometerlos a todos. Trend Micro descubrió que el 48% de 19,402 implementaciones de servidores MCP recomiendan el almacenamiento de credenciales en texto plano.
Continue.dev: claves API en texto plano
Continue.dev almacena cada clave API configurada directamente en ~/.continue/config.json:
{
"models": [{
"provider": "anthropic",
"apiKey": "sk-ant-api03-YOUR-ACTUAL-KEY"
}]
}
La comunidad reconoce esto como un problema (issue de GitHub #1729). Se admite la sustitución de variables de entorno (${VAR_NAME}) pero no es el comportamiento predeterminado.
Cline: credenciales sincronizadas con la nube
La configuración MCP de Cline se encuentra en un archivo JSON sin cifrar dentro del globalStorage de VS Code. El problema es que VS Code Settings Sync sube automáticamente este archivo a GitHub. Si tienes habilitado Settings Sync, tus credenciales MCP están almacenadas en la nube de GitHub.
La confusión de VS Code SecretStorage
GitHub Copilot, Cline y otras extensiones de VS Code usan la API SecretStorage, que cifra secretos en una base de datos SQLite (state.vscdb) usando AES-128-CBC. Esto parece seguro hasta que te das cuenta de que:
- Las extensiones de VS Code se ejecutan sin sandboxing
- La clave de cifrado se encuentra en el llavero del sistema operativo, accesible por cualquier proceso a nivel de usuario
- Cualquier extensión maliciosa puede leer los secretos de otras extensiones
- El sistema de identificación de extensiones es vulnerable a suplantaciones
El cifrado proporciona defensa contra el acceso al disco sin conexión, pero no contra ningún proceso que se ejecute como el mismo usuario.
Ejemplos de superficie de ataque
Identifiqué 8 escenarios de ataque del mundo real que quería señalar, habilitados por la exposición de credenciales de IA.
1. Robo de credenciales mediante malware
Las rutas de los archivos son predecibles y consistentes en todas las instalaciones:
~/.claude/.credentials.json
~/.continue/config.json
~/.aws/credentials
~/.config/gcloud/application_default_credentials.json
~/Library/Application Support/Claude/claude_desktop_config.json
~/.claude.json
El malware Infostealer ya apunta a las cookies del navegador, claves SSH y credenciales en la nube. Añadir unas pocas rutas de herramientas de IA a la lista de objetivos es trivial. No se requiere escalada de privilegios; la lectura de archivos a nivel de usuario estándar es suficiente.
Una sola infección de malware podría revelar los tokens Claude OAuth, todas las claves API en Continue.dev, cada token del servidor MCP y las credenciales de AWS. Las rutas son las mismas en cada instalación de cada herramienta.
Riesgo: CRÍTICO. Alta probabilidad, alto impacto.
2. Secuestrar una sesión de control remoto de Claude Code
Este es el escenario que debería asustarte. Claude Code tiene una función de Remote Control (claude remote-control) que permite a los usuarios controlar su sesión local de Claude Code desde un teléfono, tableta o navegador a través de claude.ai/code. Toda la ejecución del código permanece en la máquina local. El dispositivo remoto es solo una interfaz de control.
Aquí está el problema: la conexión remota no requiere reautenticación. Una vez que la sesión está activa, cualquiera con la URL de la sesión puede enviar instrucciones. Y todas esas instrucciones se ejecutan localmente en la máquina del desarrollador.
Ahora combine eso con --dangerously-skip-permissions.
Esta bandera desactiva todos los avisos interactivos de permisos. Las escrituras de archivos, comandos de shell, solicitudes de red, llamadas a herramientas MCP, todo se ejecuta automáticamente sin preguntar al usuario. Está destinada a contenedores CI/CD aislados, pero a veces los usuarios la usan en sus estaciones de trabajo por conveniencia. También se puede configurar como un valor predeterminado persistente en settings.json mediante "defaultMode": "bypassPermissions".
La cadena de ataque:
- El atacante roba tokens OAuth de
~/.claude/.credentials.json(a través de malware, SSRF o cualquier vulnerabilidad de lectura de archivos) - Los tokens son portátiles, por lo que funcionan desde cualquier máquina
- Si la víctima tiene una sesión activa de Remote Control, el atacante se conecta y toma el control
- If the victim runs with
--dangerously-skip-permissions, the attacker now has unrestricted shell access as the victim's user:- Leer/escribir cualquier archivo en el sistema
- Ejecutar comandos arbitrarios (
curl,ssh,docker, gestores de paquetes, etc.) - Instalar puertas traseras, extraer datos, pivotar a otras máquinas
- Acceda a claves SSH, credenciales en la nube y todos los demás secretos del sistema
- Modificar repositorios git, pipelines CI/CD y configuraciones de despliegue
Incluso sin --dangerously-skip-permissions, Claude Code en acceptEdits modo aprueba automáticamente las ediciones de archivos y comandos comunes del sistema de archivos. Esto aún puede ser peligroso. El modelo de permisos fue diseñado para proteger contra acciones accidentales, no contra un actor malicioso que controle la sesión.
Riesgo: CRÍTICO (con --dangerously-skip-permissions), ALTO (permisos predeterminados).
3. Movimiento lateral mediante tokens Claude OAuth
Un atacante que obtenga un token de actualización OAuth de Claude desde ~/.claude/.credentials.json puede:
- Genere nuevos tokens de acceso de forma remota (los tokens de acceso expiran en ~60 minutos, pero el token de actualización tiene una vida útil prolongada)
- Accede a las conversaciones de Claude y archivos del espacio de trabajo de la víctima
- Utilice cualquier servidor MCP que la víctima haya configurado (accediendo a sus repositorios de GitHub, proyectos de Azure DevOps, espacios de trabajo de Slack y bases de datos a través del asistente de IA como proxy)
Los tokens son portátiles. Copie el archivo de credenciales a otra máquina y Claude Code lo usará. Anthropic implementa la rotación de tokens de actualización, por lo que usar un token robado puede invalidar eventualmente el original, pero el uso inicial tiene éxito y el atacante puede obtener acceso antes de que comience la rotación.
Riesgo: ALTO. Probabilidad media-alta, alto impacto.
4. Agregación de tokens MCP: movimiento lateral
Un único archivo de configuración MCP agrega tokens para múltiples servicios externos. Por ejemplo, un archivo podría generar:
GITHUB_PERSONAL_ACCESS_TOKEN→ repositorios de código, PRs, CI/CDADO_MCP_AUTH_TOKEN→ proyectos de Azure DevOpsSLACK_BOT_TOKEN→ espacio de trabajo interno de Slack- Contraseñas de bases de datos → datos de producción
JIRA_API_TOKEN→ gestión de proyectos, tickets internos
A diferencia del almacenamiento distribuido de credenciales, donde comprometer un canal expone solo un subconjunto de credenciales, el patrón de agregación de MCP significa que la divulgación de un solo archivo provoca una cascada que compromete todos los servicios conectados.
Riesgo: CRÍTICO. Alta probabilidad, alto impacto.
5. Extensión maliciosa de VS Code: exfiltración de credenciales
Las extensiones de VS Code se ejecutan sin sandboxing. Todas las extensiones comparten los mismos permisos de proceso. Una extensión maliciosa o comprometida puede:
- Acceda directamente a la base de datos SQLite
state.vscdb - Recupere la clave de cifrado del llavero del sistema operativo (accesible por cualquier proceso a nivel de usuario)
- Descifrar todos los secretos de la extensión: tokens de Copilot, claves API de Cline, credenciales MCP
El archivo cline_mcp_settings.json ni siquiera necesita descifrado. Es texto sin cifrar en globalStorage de VS Code, y se sincroniza con la nube mediante Settings Sync.
Los campos publisher y name de package.json que identifican las extensiones son vulnerables a la suplantación, lo que hace posible hacerse pasar por extensiones legítimas.
Riesgo: ALTO. Probabilidad media, alto impacto.
6. Escalada de permisos en WSL
Los desarrolladores que usan WSL reciben impactos desde ambos lados. Las herramientas de IA instaladas en Windows almacenan credenciales en C:\Users\<you>\, que se monta en WSL como /mnt/c/Users/<you>/ con permisos 0777 por defecto. El mismo archivo de credenciales que está protegido por NTFS en el lado de Windows es legible para todo el mundo desde el lado de Linux.
En entornos WSL multiusuario o contenedores comprometidos, esto es fácil de explotar. Cualquier proceso que se ejecute en el sistema WSL puede leer tokens Claude OAuth, configuraciones MCP, etc., almacenados en el lado de Windows.
Riesgo: ALTO para usuarios de WSL. Alta probabilidad, impacto medio-alto.
7. .mcp.json comprometido en git: crexfiltración de credenciales
El archivo .mcp.json en la raíz del repositorio está diseñado para ser controlado por versiones, de modo que los equipos puedan compartir configuraciones del servidor MCP. Si un desarrollador incluye tokens en línea en lugar de referencias a variables de entorno:
- Los tokens aparecen en el historial de git
- Incluso después de la eliminación,
git log -p .mcp.jsonlos revela - Los escáneres automáticos (TruffleHog, GitLeaks, etc.) pueden encontrarlos a gran escala en GitHub/GitLab
La asociación de escaneo secreto entre Anthropic y GitHub detecta algunas claves API expuestas, pero los tokens de configuración MCP para otros servicios (Azure DevOps, Slack, bases de datos) no están cubiertos por el escaneo automatizado. No existe un patrón de escáner secreto de GitHub para ADO_MCP_AUTH_TOKEN o SLACK_BOT_TOKEN incrustados en bloques JSON de entorno.
Riesgo: MEDIO. Probabilidad media, impacto medio-alto.
8. Ataque a la cadena de suministro a través de servidores MCP
Los servidores MCP suelen ser paquetes npm. El riesgo en la cadena de suministro es el mismo que cualquier dependencia npm, pero con una diferencia crítica: Los servidores MCP reciben credenciales al inicio.
- El paquete popular de servidor MCP en npm está comprometido (o se ha publicado un typosquat)
- Los usuarios lo configuran en su
claude_desktop_config.jsoncon tokens reales en elenvbloque - El proceso del servidor MCP tiene acceso a todas las variables de entorno que se le pasan, incluidos los tokens
- Servidor comprometido exfiltra tokens a la infraestructura del atacante
Sin una validación adecuada de audiencia OAuth 2.1 (RFC 8707), un servidor MCP malicioso también podría recibir tokens de acceso y reproducirlos contra otros servicios (ataque de paso de token).
La estadística del 48 % de credenciales en texto plano significa que casi la mitad de todas las configuraciones de servidores MCP entregan las credenciales directamente al proceso del servidor al iniciarse. Si ese proceso del servidor se ve comprometido, todos los usuarios que lo instalaron también se ven comprometidos.
Riesgo: MEDIO. Probabilidad baja-media, alto impacto.
Bono: robo de token CI/CD
El comando claude setup-token genera un token OAuth de un año (CLAUDE_CODE_OAUTH_TOKEN) para pipelines CI/CD. Esto crea un riesgo único:
- El token funciona desde cualquier máquina durante hasta un año
- Los sistemas CI/CD a menudo tienen una gestión débil de secretos y un aislamiento limitado de trabajos
- Los registros de compilación pueden exponer accidentalmente los valores de las variables de entorno
- Un runner de CI/CD comprometido proporciona acceso prolongado a Claude con los permisos que ejecute la canalización
Si su canalización CI/CD ejecuta Claude Code con --dangerously-skip-permissions (como muchos para la automatización), un CLAUDE_CODE_OAUTH_TOKEN robado otorga ejecución de shell sin restricciones en cualquier máquina donde se use el token.
Riesgo: ALTO. Probabilidad media, alto impacto.
Qué necesita cambiar
Para usuarios (ahora mismo)
- Ejecute AIHound. Sepa qué está expuesto en su máquina.
- Corrija los permisos:
chmod 600en los archivos de credenciales. - Nunca uses
**--dangerously-skip-permissions**en máquinas con credenciales reales o acceso a la red. Si lo necesitas, úsalo dentro de un contenedor aislado sin secretos montados. - Usar referencias de variables de entorno en configuraciones MCP en lugar de tokens en línea:
"env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" }
- Rotar tokens que han estado en archivos legibles por el mundo o en el historial de git.
- Deshabilitar la sincronización de configuración de VS Code si usas Cline con servidores MCP.
- Trata
**CLAUDE_CODE_OAUTH_TOKEN**como una contraseña root. Rótala regularmente, nunca la pongas en los registros de compilación y limita los permisos de CI/CD al mínimo necesario. - Agregue
**.mcp.json**a**.gitignore**si contiene secretos en línea.
Para desarrolladores de herramientas
- Utilice los llaveros del sistema operativo. macOS Keychain, Windows Credential Manager y Linux libsecret existen exactamente para este propósito. Nunca almacene credenciales en JSON sin cifrar.
- Cree archivos con
**0600**permisos. No0644ni0777. - Advertir a los usuarios cuando detecte secretos en línea en las configuraciones de MCP.
- No sincronice las credenciales con la nube a través de los mecanismos de sincronización de configuraciones.
- Implemente OAuth 2.1 con validación adecuada de la audiencia del token para servidores MCP remotos.
- Requerir reautenticación para sesiones de Remote Control. La URL de una sesión no debe ser un token portador para la ejecución arbitraria de código.
- Auditar paquetes de servidor MCP antes de permitir la instalación y soportar la lista blanca del servidor.
Para el ecosistema
El OWASP MCP Top 10 enumera "Mala gestión de tokens y exposición de secretos" como MCP01-2025. La colaboración entre Anthropic y GitHub para la detección automática de claves API en GitHub es un gran comienzo, pero solo cubre las claves Anthropic en repositorios públicos. Los tokens MCP para Azure DevOps, Slack, bases de datos y otros servicios no tienen una protección equivalente.
Necesitamos:
- Escaneo de secretos que cubre patrones de configuración MCP, no solo formatos de claves API
- Ayudantes de credenciales para MCP (similar a los ayudantes de credenciales de git) que recuperan tokens del almacenamiento seguro en tiempo de ejecución
- Integración obligatoria del llavero del sistema operativo como predeterminado
- Aislamiento para extensiones de VS Code
- Control remoto con alcance de token - Las sesiones remotas deben requerir su propia autenticación, no heredar todas las capacidades de la sesión local
La conclusión
El ecosistema de herramientas de IA avanzó rápidamente para lanzar funciones y dejó la seguridad de las credenciales como una consideración secundaria. Casi la mitad de los servidores MCP almacenan credenciales en texto plano. Los asistentes de IA guardan tokens OAuth en archivos JSON en disco. Las funciones de Remote Control permiten que esos tokens se conviertan en ejecución remota de código. Y --dangerously-skip-permissions convierte una credencial robada en acceso completo a shell en la máquina de otra persona. Cuantas más herramientas conectes, mayor será tu riesgo. Muchas credenciales de IA no se almacenan de forma segura, así que asegúrate de implementar las mejores prácticas para el almacenamiento de credenciales. Herramientas como AIHound pueden ayudarte a encontrar estas credenciales en texto plano en tus sistemas.
Ubicaciones de almacenamiento de credenciales de aplicaciones de escritorio AI para referencia
Esta referencia cataloga cada ubicación donde algunas de las aplicaciones de escritorio de IA más populares, asistentes de codificación y herramientas CLI almacenan credenciales en disco.
Claude Code CLI
Desarrollador: Anthropic Método de autenticación: OAuth 2.0 (suscripción Claude.ai) o clave API
Archivos de credenciales
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 |
Compartir en
Aprende más
Acerca del autor
Darryl Baker
Investigador Principal de Seguridad
Darryl G. Baker es un Investigador Senior de Seguridad en Netwrix y una autoridad reconocida en seguridad de Identity y Active Directory. Con más de una década de experiencia en sistemas de identidad, ha liderado evaluaciones de seguridad empresarial, capacitaciones en seguridad de identidad y emulaciones de amenazas centradas en Active Directory, Entra ID y entornos Azure. Darryl ha impartido capacitaciones y demostraciones muy valoradas en BlueTeamCon, BSidesCT, The Experts Conference y Wild Wild West Hackin’ Fest. Es el arquitecto detrás de numerosos laboratorios prácticos de emulación de ataques, aprovechando las herramientas actuales de red team y blue team para ayudar a los defensores a dominar desde el análisis de rutas de ataque hasta la caza de amenazas. En sus sesiones, Darryl combina un profundo conocimiento técnico con estudios de casos reales, capacitando a los profesionales de blue team para fortalecer su postura de seguridad de identidad y defenderse contra técnicas adversarias en evolución.