Every AI coding tool stores your conversations. That is what makes them useful — context persists across sessions, projects can be resumed, and the model can reference earlier work.
The problem is that those same conversation stores accumulate whatever you paste into them. And developers routinely paste API keys into AI chat.
Where the secrets end up
When you ask Claude Code "help me set up my Supabase client" and paste your .env file for context, those values land in a JSONL file under ~/.claude/projects/. When you ask Cursor to debug an authentication flow and include your JWT secret, it writes to a SQLite database in your application support directory. When you ask Copilot Chat to explain your database schema and include a connection string, that connection string is now in your VS Code profile.
Here are the locations for each tool:
Claude Code
~/.claude/projects/<project-hash>/<conversation-id>.jsonl
Conversations are stored as newline-delimited JSON. Each line is a message turn. The full text of every user message and every assistant response is stored, including any credentials you included inline.
Cursor
~/Library/Application Support/Cursor/User/globalStorage/state.vscdb
A SQLite database. Cursor stores workspace-level and global chat history here. You can open it with any SQLite browser to see what is stored.
VS Code with Copilot Chat
~/Library/Application Support/Code/User/globalStorage/github.copilot-chat/
Similar structure to Cursor — JSON and SQLite files depending on the version.
Windsurf
~/Library/Application Support/Windsurf/User/globalStorage/
Follows the same VSCode-derived structure.
None of these locations are obviously "secret storage." They are not checked by default git ignore rules. They are not encrypted at rest. They persist indefinitely unless you manually clear them.
What attackers do with this
The threat model is not primarily "someone hacks your machine remotely." It is:
Backups. Time Machine, iCloud Desktop sync, and corporate MDM backup solutions often include ~/Library/Application Support. A developer who lets their credentials expire might leave years of chat history — including API keys — in an iCloud backup accessible from any of their devices.
Machine handoffs. Developers leave companies. If the machine is wiped but the backup is not, the chat history may remain. If it is transferred without a wipe, the new owner inherits everything.
Shared developer environments. Not everyone runs dev tools on a personal machine. Shared build servers, pair programming setups, or shared developer accounts can expose one person's chat history to another.
Malware. Info-stealers routinely target ~/Library/Application Support. The SQLite databases used by Cursor and VS Code are the same databases used by browsers for credentials storage — malware authors know exactly where to look.
The specific patterns that show up most
From scanning developer machines, the secrets that appear most frequently in AI chat histories are:
sk_live_Stripe secret keys (included when asking AI to help with payment flows)SUPABASE_SERVICE_ROLE_KEYvalues (included when asking AI to set up server-side Supabase)sk-...OpenAI keys (included when asking AI to help wire up API clients, which is recursive in an uncomfortable way)eyJ...JWT tokens, sometimes with admin-level claims- Database connection strings like
postgresql://user:password@host/db .envfile contents pasted wholesale for context
The Supabase service role key is particularly dangerous. Unlike the anon key, the service role key bypasses Row Level Security entirely. Whoever has it has full admin access to your database.
How to scan your AI chat histories
Sieve is a Mac app that scans your local AI coding assistant histories for leaked keys and tokens. It is free, local-only, and takes under a minute to run.
It supports Claude Code, Cursor, VS Code, Windsurf, Codex CLI, and plain .env files. It recognizes over 80 secret patterns, including all the types listed above.
After a scan, Sieve shows you exactly which conversations contain which secret types and lets you redact them from the stored databases without losing the rest of the conversation context.
For teams running Claude Code, Sieve also ships a local MCP server. Once enabled, Claude itself can run Sieve scans before committing, flag when it detects a pattern that matches a known secret format, and inject vault-backed credentials into commands without exposing the raw values.
To enable the MCP server in your Claude Code config:
{
"mcpServers": {
"sieve": {
"command": "/Applications/Sieve.app/Contents/MacOS/sieve-mcp"
}
}
}
Once connected, Claude has access to tools for scanning histories, listing findings by severity, and running commands with credentials sourced from the Sieve vault — all without the raw secret values ever appearing in the conversation.
The habit that prevents this
Beyond scanning retroactively, the most effective prevention is a simple rule: never paste raw secret values into AI chat.
Instead of:
Here is my .env file: STRIPE_SECRET_KEY=sk_live_abc123...
Help me add a webhook handler.
Do this:
I have a STRIPE_SECRET_KEY set as an environment variable via process.env.
Help me add a webhook handler that reads it that way.
The AI does not need your actual key to help you write code. It needs to know the variable name and the pattern you are using to access it.
If you need to give the AI context about what a specific API response looks like, redact the sensitive fields before pasting. Every major AI coding tool is good enough to understand [REDACTED] in an example payload.
Scan your machine before your next deploy. The habit takes ten minutes to build and prevents the kind of breach that shows up in your inbox from a stranger two days after launch.