A Practical Guide to Exposed Credentials and How to Fix Them

Credential leaks are one of the most common and most preventable security incidents in modern software development. As a DevOps engineer, I encounter these issues regularly and have built this guide to help developers and teams understand the risks, recognize the patterns, and take action before a leaked secret becomes a real incident.

Why This Matters

According to GitGuardian's 2024 State of Secrets Sprawl report, over 12.8 million new secret occurrences were detected in public GitHub commits in a single year. That number has been growing year over year. Most of these leaks are unintentional, and almost all of them are preventable. If you write code and push it to a repository, this guide is for you.

OPENAI_API_KEY

The OpenAI API key authenticates your application to access models like GPT-4. It is one of the most frequently leaked credentials because developers hardcode it during local prototyping and forget to remove it before pushing to a remote repository. A leaked OpenAI key means anyone can make API calls on your account, running up costs and potentially accessing conversation history tied to the key.

Treat your API key like your credit card number. You would not paste it into a README and push it to GitHub.

AWS_SECRET_ACCESS_KEY

The AWS secret access key, paired with an access key ID, authenticates programmatic requests to AWS services. Exposing this credential is particularly dangerous because AWS permissions can span dozens of services. An attacker with your key can spin up EC2 instances for cryptocurrency mining, exfiltrate data from S3 buckets, read your databases, or modify your infrastructure. In many documented cases, compromised AWS keys have resulted in bills exceeding $50,000 within hours.

One key, full access to the cloud. Scope your IAM policies, use temporary credentials via STS, and never store long-lived keys in code.

DATABASE_URL

A database connection string typically contains the protocol, username, password, host, port, and database name in a single URL. When this lands in a public repository, your entire data layer is one connection attempt away from unauthorized access. Even if the database is behind a firewall, the credentials themselves can often be reused elsewhere or provide enough information for targeted attacks.

Your connection string is a complete access package. It belongs in a secrets manager, not in version control.

Common Mistakes That Lead to Exposure

Most credential leaks are not the result of negligence. They happen because of gaps in workflow and tooling. Here are the patterns I see most often:

  • Missing .gitignore entries for .env, .env.local, and similar files. Always configure this before the first commit in any project.
  • Hardcoding values during prototyping and forgetting to extract them into environment variables later. What starts as a quick test often ends up in production.
  • Assuming a private repo is safe is a dangerous assumption. Repositories change visibility, teams change membership, and forks can expose history.
  • Deleting the secret without rotating it gives a false sense of security. Git history preserves every commit. If it was ever pushed, consider it compromised.
  • Logging secrets in CI/CD output through debug statements or verbose build logs. Pipeline logs are often accessible to more people than the codebase itself.

What to Do If a Secret Is Exposed

Speed matters. The window between exposure and exploitation can be minutes, not hours. Here is a practical incident response checklist:

  1. Revoke and rotate the credential immediately. Do not wait until you have cleaned the repository. Revoke first, then investigate.
  2. Check for unauthorized usage. Review access logs, billing dashboards, and audit trails for the affected service. Look for activity you did not initiate.
  3. Remove the secret from Git history. Use git filter-repo or BFG Repo-Cleaner to scrub the credential from all commits. A simple git rm is not enough.
  4. Force-push and notify collaborators. After rewriting history, force-push the cleaned branch and inform your team to re-clone or rebase.
  5. Document the incident. Record what was exposed, when, what actions were taken, and what preventive measures are being added. This builds organizational memory.

Prevention Toolkit

The best incident is the one that never happens. Here are the tools and practices I recommend to every team:

Pre-commit Scanning

Install gitleaks or detect-secrets as a pre-commit hook. This catches secrets before they ever leave your machine. It takes five minutes to set up and prevents the most common leak scenario entirely.

CI/CD Pipeline Scanning

Add trufflehog or gitleaks as a step in your CI pipeline. Even if a developer bypasses local hooks, the pipeline acts as a second line of defense. Fail the build if secrets are detected.

Secrets Management Solutions

Use a dedicated secrets manager like AWS Secrets Manager, HashiCorp Vault, Phase, or Doppler. These tools inject secrets at runtime, support rotation policies, and provide audit logs. They eliminate the need to store sensitive values in files or environment variables on disk.

GitHub Native Features

Enable GitHub Secret Scanning and push protection on all repositories. GitHub automatically detects patterns from over 200 service providers and can block pushes that contain known secret formats. This is free for public repositories and available on GitHub Advanced Security for private ones.

Environment Variable Hygiene

Maintain a .env.example file with placeholder values committed to the repository. Add .env, .env.local, .env.production, and all variants to .gitignore. Use separate credentials for development, staging, and production environments. Never share credentials across environments.

Quick Reference

ToolStageWhat It Does
gitleaksPre-commit / CIScans commits and repos for hardcoded secrets
trufflehogCI / Ad-hocDeep scans Git history, S3, and other sources
detect-secretsPre-commitLightweight baseline-based secret detection by Yelp
GitHub Secret ScanningRepositoryAlerts on known secret patterns from 200+ providers
git filter-repoIncident ResponseRewrites Git history to remove sensitive data
HashiCorp VaultRuntimeCentralized secrets storage with rotation and audit

Credential security is not a one-time fix. It is an ongoing practice built into your workflow, your pipelines, and your team culture. Start with one tool, build the habit, and iterate.

Back to Home