← All news
security4 min read

Your AI Assistant Just Committed a Secret

By Seaworthy · 20 September 2026

Black flat screen computer monitor displaying code in a dark terminal window

Photo by Riku Lu on Unsplash

The quiet leak in your repo

I keep seeing the same pattern in code reviews. A developer asks an AI assistant to wire up a payment integration, and the generated snippet includes something like this:

import stripe

stripe.api_key = "sk_live_51H8x..."

def charge_customer(amount, token):
    return stripe.Charge.create(
        amount=amount,
        currency="usd",
        source=token,
    )

That key is fake, but the shape is real. The assistant did exactly what it was asked to do. It produced working code. It also produced a credential sitting in plaintext, ready to be committed.

This is not a hypothetical. I have watched teams merge these snippets because the code ran, the tests passed, and nobody looked at the diff long enough to notice the string that starts with sk_live_.

Why this keeps happening

AI assistants are trained on a huge amount of public code. Public code is full of hardcoded secrets. Tutorials do it. Sample apps do it. Stack Overflow answers do it. So when you ask for a quick integration, the model reaches for the pattern it has seen most often. That pattern is a literal string.

The problem is not that the model is malicious. The problem is that the model does not know your deployment context. It does not know that the repository is public. It does not know that the CI logs are visible to contractors. It does not know that the key it invented (or worse, the key you pasted into the chat) will end up in a git history that lives forever.

Developers skip security basics because the basics feel slow. Setting up a secrets manager, writing a .env.example, configuring environment variables in three different environments. That is real work. Asking the assistant to "just make it run" is fast. I get it. I have done it.

But the cost of that speed is asymmetric. A leaked database password costs a weekend of incident response, a rotation across every service, and a very uncomfortable email to customers. The five minutes you saved are not worth it.

The fix is boring and that is fine

You do not need a new tool. You need a habit. When the assistant hands you a credential, do not accept it. Replace it with an environment variable and add a placeholder to your .env.example file.

import os
import stripe

stripe.api_key = os.environ["STRIPE_SECRET_KEY"]

def charge_customer(amount, token):
    return stripe.Charge.create(
        amount=amount,
        currency="usd",
        source=token,
    )

Then create .env.example with a fake value:

STRIPE_SECRET_KEY=sk_test_replace_me

And make sure .env is in .gitignore before you write a single line of real configuration. That last step is the one people skip. I have seen .env files committed in repos that also had a .gitignore file listing .env on line four. The file was created before the ignore rule. Git does not care about your intentions.

What I actually want you to do

Stop treating the assistant's output as final. Treat it as a first draft from a very confident intern who has never seen your infrastructure. That means reading every line that touches a credential, a connection string, or a private key.

If you already committed a secret, rotate it. Do not just delete the line and force-push. The old commit is still in the reflog, in forks, in CI caches, and in any clone that anyone made. Rotation is the only real fix. Deletion is theater.

Add a pre-commit hook that scans for common patterns. There are several open source options. A simple regex for AKIA[0-9A-Z]{16} and sk_live_ will catch the obvious cases. It will not catch everything, but it will catch the mistakes you are most likely to make at 11 PM.

Finally, stop pasting real credentials into AI chat windows. If you need the assistant to understand your schema, use a fake key with the same format. The model does not need the real one to help you write the code.

The uncomfortable part

I like AI coding assistants. They make me faster. They also make it easier to be careless, because the code looks finished. A finished-looking snippet invites you to commit it without thinking. That is the tradeoff. You get speed, and you have to pay for it with attention.

Security basics are not glamorous. They are not the reason anyone gets promoted. But they are the reason you do not spend your Saturday rotating every token in your production environment. Do the boring thing. Use environment variables. Rotate early. Scan your commits.

Seaworthy provides a way to detect exposed secrets and other security issues in your codebase without adding friction to your workflow.

This article was generated by AI and summarises publicly available sources.

From the makers of Seaworthy

Seaworthy scans your repo for the issues covered in articles like this one.

Security gaps, exposed secrets, and misconfigurations — caught before you deploy. Free to run, no account needed.

$ npx seaworthycode