If Cursor wrote an API key into your source and it reached a commit or a shared prompt, treat it as compromised now. The key is the thing to fix, not the code around it. Rotate it first, then clean up, then stop it happening again. The order matters, and most people get it backwards.
Why it's a problem
A key in committed source is readable by anyone with access to the repo or its history, and public repos are scraped by bots within minutes. Cursor also indexes files in your workspace, including .env unless you exclude it, which means a secret can end up pasted into a prompt and leave your machine even if it was never committed. Either way, the key is out.
How to fix it, in order
- 1Rotate the key first. Go to the provider that issued it and revoke or regenerate the key. This is the only step that actually protects you. Deleting the commit feels like a fix and does almost nothing, because the value is already copied.
- 2Check for unauthorized use. Open the provider's usage or billing dashboard and look for activity you do not recognize. If the key touched money or user data, treat anything odd as an incident, not just cleanup.
- 3Purge it from git history. If it was committed, remove it with git filter-repo or BFG and force-push. Know that forks, clones, and caches can still hold the old commit, which is why rotation came first.
- 4Move it to an environment variable. Put the new key in a .env file, confirm .env is in .gitignore, and read it via process.env or import.meta.env. Never inline it again.
Why Cursor does this
Cursor optimizes for code that runs, and inlining the key is the shortest path to running code, so it reaches for it whenever the surrounding context makes that the quick win. Separately, Cursor indexes your workspace for its AI features, so a .env that is not in .cursorignore can be read into context. Neither is malice; both leak secrets.
Stop it happening again
Two Cursor-specific guards: add .env (and any secret files) to a .cursorignore so Cursor never indexes them into a prompt, and add a rule to .cursor/rules telling it to always read secrets from environment variables and never inline them. Then install a gitleaks pre-commit hook so a hardcoded key fails the commit regardless.
The quick fix
- Rotate the key at the provider before anything else.
- Check provider logs for use you do not recognize.
- Purge from git history if committed; move the new key to .env.
- Add .env to .cursorignore and a secrets rule to .cursor/rules; install a gitleaks pre-commit hook.