Your API Key Is in Git Again: Fixing Secrets in Source Code
Von Seaworthy · 15. Oktober 2026
Photo by Garakhan Safarli on Unsplash
I keep seeing the same mistake in code reviews. Someone, usually under deadline pressure, drops an API key or database URL right into a config file. Then they commit it. Then they push. And now that secret lives in your Git history forever, visible to anyone with repo access, including that contractor you forgot to remove.
This is not a new problem. But it is getting worse because AI coding assistants make it trivially easy to generate working code that hardcodes credentials. You ask for a quick integration, the assistant writes const apiKey = "sk-..." and you paste it into your editor without thinking. The code runs. The tests pass. You move on.
Stop doing this. I do not care how small the project is or how temporary the key is. Hardcoded secrets are a configuration failure, not a time-saving trick.
Why the environment variable approach wins
Environment variables live outside your source tree. They are set by the runtime (your shell, your container orchestrator, your hosting platform) and read by the process when it starts. That separation means your code can be shared, reviewed, and versioned without leaking credentials.
The alternative, storing secrets in a file that gets committed, fails at the first step: version control. Git does not forget. Even if you delete the file in a later commit, the secret remains in the history. Rotating the key is then mandatory, which is exactly the kind of emergency you were trying to avoid.
The pattern you should never ship
Here is a typical offender in a Node.js project. The developer needed a Stripe key, so they put it in a config file.
// config.js
module.exports = {
stripeKey: "sk_live_51H8x...",
databaseUrl: "postgres://admin:password123@localhost:5432/myapp"
};
This file is one git add away from disaster. If the repository is public, the key is compromised in seconds. If it is private, you are still relying on every collaborator to be careful. That is a weak control.
The fix requires two changes. First, read from process.env in your code. Second, provide those values through your environment.
// config.js
module.exports = {
stripeKey: process.env.STRIPE_KEY,
databaseUrl: process.env.DATABASE_URL
};
Now the source file contains only names. The actual values live in a .env file for local development (which you add to .gitignore) and in your platform's secret manager for production. A .env.example file with placeholder values can be committed to document what is needed.
The AI assistant problem
AI coding assistants are not security tools. They optimize for working code, not safe configuration. When you ask for a quick example, they will often inline credentials because that is what makes the snippet runnable. You have to treat their output as a first draft, not a finished product.
My rule: if an assistant generates a literal secret, I replace it with an environment variable read before I run anything. This takes five extra seconds. It prevents a rotation incident that could cost hours.
What about client-side code?
You cannot hide secrets in frontend JavaScript. Any value shipped to the browser is public. Environment variables in build tools like Vite or Create React App are embedded at build time, so they are still visible. The only correct answer is to keep sensitive keys on a server you control and proxy requests through it. Do not let an assistant convince you that obfuscation is protection.
A checklist that actually helps
- Add
.envto.gitignorebefore you create any secret files. - Use a pre-commit hook or scanner (like
git-secretsortrufflehog) to block commits containing patterns that look like keys. - Rotate any secret that has ever been committed, even in a private repo. Assume it is compromised.
- Store production secrets in your cloud provider's secret manager (AWS Secrets Manager, GCP Secret Manager, Azure Key Vault) or a dedicated tool like HashiCorp Vault.
- When an AI assistant writes code, review every string literal that looks like a credential.
My honest reaction
I am tired of seeing this. It is a solved problem. The pattern is well known, the tooling is free, and the cost of doing it right is negligible. The only reason it persists is that developers, especially those leaning on AI assistants, treat configuration as an afterthought. That is a mistake. Your source code is not a safe place for secrets. Treat it like a public document, because one day it might be.
If you want a practical way to audit your repositories for this pattern, Seaworthy is a tool that scans for secrets in source code and configuration files.
Dieser Artikel wurde von KI generiert und fasst öffentlich verfügbare Quellen zusammen.
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.