Skip to main content

Hardcoded Secrets

Hardcoded secrets are credentials written directly into source code, where they persist in version-control history and spread to logs, CI, and binaries. Store secrets in a secrets manager or inject them at runtime, and rotate anything that was ever committed.

Hardcoded secrets are credentials — API keys, database passwords, OAuth tokens, private keys — written as string literals inside application code or configuration that ships with the code. The moment a secret is committed, it is permanent in version-control history and copied to every clone, fork, and CI cache.

Why It Happens

It is the path of least resistance. During prototyping a developer pastes a key inline to make something work, then forgets to remove it. Teams without a secrets-management story have nowhere else to put the value. Sample code and tutorials frequently show inline keys, normalizing the habit. Deadlines discourage the extra step of wiring up a vault or environment variable.

Why It Hurts

Secrets in source code spread uncontrollably. They appear in Git history forever, so deleting the line in a later commit does not remove the exposure. They land in CI logs, container layers, crash dumps, and developer laptops. Anyone with read access to the repository — including former employees and compromised CI tokens — gains the credential. Automated scanners constantly crawl public repos for leaked keys, often exploiting them within minutes. Rotation becomes painful because the value is scattered across builds, so teams avoid rotating, extending the window of compromise.

Warning Signs

  • Grep for password =, api_key, BEGIN PRIVATE KEY, or high-entropy strings returns hits in application code.
  • Secret-scanning tools (gitleaks, TruffleHog, GitHub secret scanning) flag commits.
  • Credentials are identical across dev, staging, and production.
  • No one can answer how a given secret would be rotated.

Better Alternatives

Store secrets outside the codebase and inject them at runtime. A dedicated secrets manager (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, GCP Secret Manager) provides access control, audit logging, and rotation. For local development, environment variables loaded from an untracked .env file keep values out of source. Best of all, eliminate long-lived secrets entirely with workload identity: cloud platforms can grant short-lived, automatically rotated credentials to a service based on its identity, so there is no static key to leak.

How to Refactor Out of It

  1. Scan the full history, not just the working tree, with a secret scanner.
  2. Treat every found secret as compromised and rotate it immediately — assume it has leaked.
  3. Replace the literal with a lookup against environment variables or a secrets manager.
  4. Purge the secret from history (git filter-repo or BFG) and force-push, coordinating with the team; rotation matters more than purging because clones already exist.
  5. Add a pre-commit hook and CI gate that blocks new secrets, so the problem cannot reappear.
  6. Document a rotation runbook so credentials can be replaced routinely, not only after an incident.