← Alle Neuigkeiten
security5 Min. Lesezeit

The secrets AI coding assistants accidentally commit to Git

Von Seaworthy · 26. Mai 2026

A gold padlock resting on a laptop keyboard, representing digital security and the risk of leaked credentials

Photo by FLY:D on Unsplash

What actually ends up in your repository

There is a pattern that shows up constantly in repos built with AI coding assistants. The developer is moving fast, the assistant is generating working code, and somewhere in the middle of that flow a secret lands in a file that gets committed. Not in a .env file, which most developers know to gitignore. In the actual source code.

The assistant doesn't know the difference between a placeholder and a real credential. It sees you paste a real API key to demonstrate what format you want, and it uses that key. Verbatim. In a config file that goes straight into src/.

Here are the specific files where this happens most often.

Hardcoded credentials in config files. The assistant generates a database config and fills in real values because you showed it a real connection string once. The result is something like:

// generated by AI, committed by developer
const db = new Client({
  host: "prod-db.internal.example.com",
  password: "s3cr3tActualPassword123",
  database: "production"
});

That password field is now in your Git history. Rotating it on the server doesn't help. The history is permanent.

Private keys in test fixtures. The assistant writes a test, needs a JWT signing key to make the test pass, generates one, and puts it in tests/fixtures/auth.ts. Done. Committed.

Third-party API keys in example code. You ask for an example of how to call the Stripe API and paste your real test key to show the format. The assistant writes the example using your real key. The example gets committed as documentation.

Cloud provider credentials in CI-adjacent files. Serverless config files, CDK stack definitions, Terraform variable files that were supposed to stay local: all of them are natural targets. The assistant fills in values that look like what you need, using what you gave it.

Why the assistant doesn't catch this

You might expect the assistant to flag when it is about to write a secret into a committed file. It usually doesn't, for a few reasons.

It has no concept of what is already in your .gitignore. It doesn't run git status. It doesn't know whether the file it's writing to will be tracked or not. From its perspective, it's generating code that works.

It also can't reliably distinguish between a placeholder and a real credential. YOUR_API_KEY_HERE and sk-live-xK9mFd3vQ2wPLzRtN8bYcH look structurally similar to a model that is trying to produce working code. Real keys often look like placeholders.

Finally, the developer is going fast. The whole point of using an AI assistant is speed. Slowing down to audit every generated file for secrets feels like it defeats the purpose. So the audit doesn't happen.

What the Git history problem actually means

Deleting the secret from the current file doesn't help. The secret is in the commit where it was added. Anyone with read access to the repository can check out that commit and read the secret.

# anyone with repo access can do this
git log --all --oneline
git show abc1234:src/config/database.ts

If your repository is public, that commit has probably already been indexed by automated scanners. GitHub's secret scanning catches some of this, but only for supported providers and only on public repos by default.

The only real remedies are: rotate the credential immediately (before anything else), then consider whether you need to rewrite history with git filter-repo to remove it from all commits. Rewriting history on a shared repository is painful and disruptive. Prevention is significantly cheaper.

Practical prevention

The most useful thing you can do right now is add git-secrets or gitleaks as a pre-commit hook. These tools scan staged changes before the commit lands and reject anything that looks like a credential.

# install gitleaks and add a pre-commit hook
brew install gitleaks

# in .git/hooks/pre-commit
#!/bin/sh
gitleaks protect --staged --redact -v

A few other things that actually help:

  • Keep a .env.example file with fake values and a strict .gitignore for real .env files. When you show the AI an example, show it the fake version.
  • If you're using a service that supports it, use short-lived credentials or scoped tokens with the minimum permissions. A leaked read-only token for a dev bucket is a much smaller problem than a leaked admin credential.
  • Treat anything the AI generates that contains a string longer than about 20 characters with suspicion. Pause and check whether it came from context you provided.

The habit that matters most: never paste a real secret into the chat with an AI assistant. Not even "just to show the format." Use a clearly fake placeholder and describe the format in plain text instead.

The cost of finding out the hard way

A rotated credential is an hour of work. A credential that has been live in a public repository for six months means auditing everything that credential had access to, checking for exfiltration, and potentially notifying users. The gap between those two outcomes is a pre-commit hook and a five-second review before git push.

Seaworthy's static analysis checks flag hardcoded credentials and secrets in source files as part of its security category scan.

Dieser Artikel wurde von KI generiert und fasst öffentlich verfügbare Quellen zusammen.

Von den Machern von Seaworthy

Seaworthy scannt dein Repository nach den Problemen, die in Artikeln wie diesem behandelt werden.

Sicherheitslücken, offengelegte Geheimnisse und Fehlkonfigurationen — erkannt, bevor du bereitstellst. Kostenlos, kein Konto nötig.

$ npx seaworthycode