Why your AI coding assistant keeps hardcoding secrets
Par Seaworthy · 20 juillet 2026
I've read a lot of AI-generated code this year, and I keep seeing the same mistake: a secret, sitting in plain text, three lines below a comment that says // TODO: move to env vars.
That TODO never gets actioned. The code ships, the demo works, the secret sits in the repo. I don't think this is a coincidence. I think it's a structural property of how these tools work, and it's worth understanding why if you're using one to write production code.
The model is optimizing for a different goal than you are
When you ask an assistant to "add Stripe integration," it has one job: produce code that runs. A hardcoded key runs. An .env file that isn't wired up to your deployment config doesn't, or at least not without a follow-up question the model has no way to ask. So it takes the path that visibly works in the sandbox it's reasoning about, which is almost never the path that's safe in your actual deployment.
This is not a knock on any particular model. Claude does this. GPT does this. Every assistant I've tested does this, because the training signal rewards "code that executes" far more reliably than it rewards "code that's still safe six months from now, after someone forks the repo." Nobody labeled a training example "bad" because the API key was inline. It ran. It looked done.
What this looks like in practice
Here's a fairly typical example, lightly adapted from something I saw an assistant produce for a weekend project:
const stripe = require('stripe')('sk_live_51H8x...redacted...');
app.post('/checkout', async (req, res) => {
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
line_items: req.body.items,
mode: 'payment',
});
res.json({ url: session.url });
});
The person who asked for this got a working checkout flow in under a minute. They also got a live secret key committed straight into version control the first time they ran git add .. If that repo is ever made public, or shared with a contractor, or pushed to a template site, the key is gone the moment it's indexed.
The fix is one line different:
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
But that one line requires the model to assume you have a .env file, that you've wired it into your process manager or hosting platform, and that you know to add .env to .gitignore before your first commit. Those are three separate pieces of infrastructure knowledge that a "make it work" prompt never asked for.
Why this keeps surprising people
The developers I talk to who get burned by this aren't careless. They're often careful, experienced people who are using an assistant specifically to move faster on the parts of the stack they know less well, like billing integrations or third-party APIs. The assistant fills the gap competently on the happy path and silently on the parts that would normally trigger their own instincts, like "wait, should this be in an env var."
If you'd written this code yourself, you'd have paused at the string literal. Typing sk_live_ by hand feels wrong in a way that accepting a generated block of working code doesn't. The friction that used to catch this mistake is gone, and nothing has replaced it.
What actually helps
Asking the model to "use environment variables" in your prompt helps, but only if you remember to ask every time, for every secret, in every file. That's not a habit, that's a hope. A pre-commit hook that scans for high-entropy strings and known key prefixes catches it before the commit lands, which is the only point in the workflow where a fix is still cheap. After the push, you're rotating a key, not editing a line.
I don't think the fix here is "distrust AI-generated code." I think it's "stop trusting yourself to catch this by reading the diff," because you won't, not every time, not at 11pm on a Tuesday when the checkout flow finally works.
Seaworthy scans for exactly this pattern, along with the other habits AI assistants tend to skip, before you find out about them from Stripe's fraud team.
Cet article a été généré par IA et résume des sources publiquement disponibles.
Seaworthy analyse votre dépôt pour détecter les problèmes abordés dans des articles comme celui-ci.
Failles de sécurité, secrets exposés et mauvaises configurations détectés avant le déploiement. Gratuit, aucun compte requis.