Application & API Security • 3 min read
Secrets Management: Preventing and Responding to Hardcoded Credentials
Why secrets leak, how to detect them with scanning and push protection, what to do within the first hour of a leak, and how to design systems that keep secrets out of code.
By CryptoAgile Labs Editorial Team • Published October 2026 • Last updated October 10, 2026
A secret is any value that grants access: API keys, database passwords, private keys, OAuth client secrets, signing keys and tokens. Hardcoding one in source code, a configuration file or a container image is among the most common and most damaging security mistakes, because version control keeps history and public repositories are scanned by attackers within minutes.
How secrets leak
- Committed
.envfiles or config files that were meant to stay local - Keys pasted into code "temporarily" for testing
- Credentials in CI logs, build artifacts or container layers
- Secrets in client-side JavaScript bundles (anything shipped to a browser is public)
- Copies in chat tools, tickets and screenshots
- Old forks and clones that retain deleted history
Detection: three layers
1. Pre-commit hook. Scans staged changes locally and blocks the commit. Fastest feedback, and the secret never enters history. Tools include gitleaks and trufflehog.
2. Pull-request and CI scanning. Catches what the hook missed and what teammates without hooks commit. See running scanners in GitHub Actions.
3. Platform push protection. Code hosting platforms can reject pushes containing recognized token formats and alert on exposed ones, and some providers revoke leaked tokens automatically. Enable these features on every repository.
Detectors combine patterns (known formats such as cloud access key prefixes) with entropy checks (random-looking strings). Patterns have few false positives but miss custom secrets; entropy finds more but flags test data. Use both, and keep an allowlist with documented reasons.
When a secret leaks: the first hour
- Revoke or rotate it immediately. This is the only step that actually fixes the exposure. Assume the secret is already compromised.
- Check for misuse. Review access logs and billing for the credential's activity during the exposure window.
- Replace it in the application using the secrets manager (not a new hardcoded value).
- Remove it from history with
git filter-repoor BFG, then force-push and have collaborators re-clone. Do this after rotation; history rewriting does not undo exposure, since clones and caches may persist. - Find the cause and add a control that would have prevented it.
Never treat deleting the file in a new commit as remediation. The secret stays in history.
Designing secrets out of the code
Use a secrets manager. Services such as AWS Secrets Manager, Parameter Store, HashiCorp Vault and Azure Key Vault store secrets encrypted, control access through identity policies, audit every read and support rotation.
// Fetch at startup, cache in memory, never log
import { SecretsManagerClient, GetSecretValueCommand } from '@aws-sdk/client-secrets-manager';
const client = new SecretsManagerClient({});
const { SecretString } = await client.send(new GetSecretValueCommand({ SecretId: 'prod/api/db' }));
const dbCreds = JSON.parse(SecretString);Prefer identity over static keys. Workloads should authenticate with cloud IAM roles or workload identity, so there is no long-lived key to leak. For CI, use OpenID Connect federation instead of stored cloud keys.
Keep secrets out of environment dumps. Environment variables are convenient but appear in process listings, crash reports and debug endpoints. In AWS Lambda they are encrypted at rest but readable by anyone allowed to view the function configuration (see IAM hardening).
Separate by environment and purpose. Distinct credentials for development, staging and production, each with minimum permissions, limit what one leak can do.
Rotate regularly and automatically. Short-lived credentials reduce the value of anything stolen. Practice rotation so it is routine, not an emergency.
Frontend and mobile caveat
Anything in a browser bundle or mobile app can be extracted. Public identifiers (a publishable key) are fine; secret keys must stay on a server. If a feature needs a secret, put a thin backend API in front of it.
Team checklist
- Pre-commit scanning installed by default (via a shared config)
- CI secret scanning on every pull request
- Push protection enabled on all repositories
- A written leak runbook with named owners
- A secrets manager as the only approved storage
- Quarterly review of who can read which secrets
Sources and further reading
Related articles
This article is for educational purposes and is not professional security, legal or compliance advice. Spotted an error or an out-of-date detail? Email us a correction. See our editorial policy.