DEV Community

Cover image for The API Key Cursor Just Wrote Into Your Code Is Already in Git History
Chandan Karn
Chandan Karn

Posted on

The API Key Cursor Just Wrote Into Your Code Is Already in Git History

TL;DR

  • AI coding assistants hardcode API keys, tokens, and credentials directly into source files more often than you'd think
  • Once committed, that secret lives in git history even after you delete it from the file
  • Fix: scan with gitleaks before pushing, and check your AI isn't skipping env vars

I was doing a quick review of a side project last month when I spotted it. Right there in config.js, sitting in plain text: const OPENAI_KEY = "sk-proj-...". The developer had asked their AI assistant to add an OpenAI integration, reviewed the output, tested it, and shipped it. The key worked, so they moved on.

It had been in the repository for three months. Three months of git history, three months of anyone who cloned the repo having access to it.

The key had been rotated by the time I found it. But rotating a key doesn't fix the history.

The Vulnerable Pattern

This is what AI assistants generate when you ask them to "add OpenAI to this project":

// CWE-798: Use of Hard-coded Credentials
const OpenAI = require('openai');

const client = new OpenAI({
  apiKey: 'sk-proj-abc123xyz...' // hardcoded credential
});
Enter fullscreen mode Exit fullscreen mode

The same pattern shows up with Stripe keys, database connection strings, JWT secrets, AWS credentials. The AI knows the API, it knows the shape of the code, and it fills in the blank with whatever it saw in training data. A lot of those examples had real-looking keys in them.

Why This Keeps Happening

Tutorials hardcode credentials. That's just how tutorials are written. They're trying to show you the shape of the code, not teach secret management, and the fastest way to do that is to put a value directly in the example.

AI models trained on that data reproduce the pattern. When you ask "add OpenAI to my Express app", the model reaches for the template it's seen a thousand times. It doesn't reason about production security. It completes the pattern.

The other thing is that AI assistants often don't know whether you've set up a .env file. If OPENAI_KEY is already in your environment, a well-prompted model might use process.env.OPENAI_KEY. But if you're starting fresh and haven't mentioned it, it defaults to hardcoding.

The Fix

Two parts. First, the code:

const OpenAI = require('openai');
require('dotenv').config();

const client = new OpenAI({
  apiKey: process.env.OPENAI_KEY // from environment
});
Enter fullscreen mode Exit fullscreen mode

And your .env file (never committed):

OPENAI_KEY=sk-proj-abc123xyz...
Enter fullscreen mode Exit fullscreen mode

Add .env to .gitignore if it isn't already.

Second part: scan your git history, not just your current files. Deleting a hardcoded key from a file and committing the deletion does not remove it from history. Anyone can run git log -p and find it.

# Scan current files and full git history
gitleaks detect --source . --log-opts="--all"
Enter fullscreen mode Exit fullscreen mode

Run that on every repo you own, including old ones. Then add it as a pre-commit hook so it catches the next one before it gets pushed:

gitleaks protect --staged
Enter fullscreen mode Exit fullscreen mode

If gitleaks finds something in your history, rotate the key immediately. Then use git filter-repo or BFG Repo Cleaner to scrub it from history before sharing the repo with anyone.

I've been running SafeWeave for this. It hooks into Cursor and Claude Code as an MCP server and flags hardcoded credentials before I move on. That said, gitleaks alone will catch most of what's in this post. The important thing is running it before you push, not after.

Top comments (0)