Secrets Management Best Practices for Web Applications
Practical secrets management best practices for web apps: avoid hardcoding, choose the right vault, rotate credentials, and secure CI/CD pipelines.
A leaked API key or database credential causes more real-world damage than most code-level vulnerabilities, yet secrets management is often an afterthought — handled informally, inconsistently, or not at all. Secrets end up in environment variables, shared Slack messages, developer machines, and occasionally public GitHub repositories.
This post covers the concrete practices that prevent secret exposure across the development lifecycle, from local development through production deployment.
Secrets Management Best Practices for Web Applications
Define what counts as a secret
Before you can manage secrets properly, you need a clear definition. Secrets are values that grant access to a system or decrypt protected data: API keys, database passwords, OAuth client secrets, private keys, tokens, and encryption keys.
Configuration values that are not sensitive — a feature flag, a log level, a public API base URL — are not secrets and do not need secret management infrastructure. Mixing them together adds operational overhead without security benefit. Keep the categories distinct from the start.
Never commit secrets to version control
This sounds obvious, and yet it remains one of the most common causes of credential exposure. Secrets end up in git history when developers add them temporarily during debugging, when .env files are committed by accident, or when a configuration file that started non-sensitive gradually accumulates sensitive values.
Mitigations:
- Add
.env,*.pem,*_rsa, and similar patterns to.gitignoreglobally and at the repository level - Install a pre-commit hook or tool like
git-secrets,detect-secrets, orgitleaksthat scans staged files for patterns matching secrets before allowing a commit - Scan your existing repository history if you suspect past exposure — secrets in git history are accessible to anyone who clones the repository, even after you delete the file in a subsequent commit
- If a secret is committed and pushed, treat it as compromised immediately. Rotate it before removing it from history.
Separate secrets from configuration
Environment variables are useful for configuration but are not designed for secrets. Their contents can appear in crash dumps, process listings, log aggregation output, and debugging tools. In containerized environments, environment variables are accessible to any process running in the container.
The hybrid model that works in practice: environment variables configure application behavior (which region to use, which service tier to hit), while a secrets manager stores and delivers the actual credentials. The application retrieves secrets at startup from the vault, not from the environment.
Use a secrets vault
For most production applications, the right tool is a managed secrets vault:
- HashiCorp Vault: Self-hosted or HCP Vault, mature ecosystem, fine-grained access control, dynamic secrets support
- AWS Secrets Manager: Integrated with IAM, automatic rotation for supported AWS services
- Google Secret Manager: GCP-native, audit logging, IAM-based access
- Azure Key Vault: Deep integration with Azure services and managed identities
- Doppler, Infisical: Developer-friendly interfaces on top of underlying storage, good for smaller teams
The right choice depends on your cloud provider and team maturity. What matters more than the specific tool is that one is chosen and used consistently, rather than different teams maintaining different practices.
Implement secret rotation
Static secrets that never change become increasingly risky over time. Every month they exist, the probability that they have been logged, accessed by a disgruntled employee, or captured in a breach increases. Rotation limits the window of exposure.
Practical rotation requires:
- Knowing where every secret is used before rotating it
- Testing the rotation process before you need to rely on it under pressure
- Application code that can reload secrets without a deployment, or at worst with a graceful restart
- Automated rotation for secrets where the upstream service supports it (most managed databases and cloud services do)
For most web applications, rotating database credentials and API keys quarterly is a reasonable baseline. Rotate immediately on any suspected exposure.
Secure your CI/CD pipeline
CI/CD pipelines are a high-value target because they have access to deployment secrets, cloud credentials, and often production systems. Common mistakes:
- Printing secrets in build logs (use masked variables in your CI platform)
- Passing secrets as plaintext command-line arguments (they appear in process listings)
- Checking out code from untrusted forks in the same pipeline context that has access to production secrets
- Using long-lived service account credentials instead of short-lived tokens or OIDC-based authentication
CI platforms (GitHub Actions, GitLab CI, CircleCI) all have first-class secrets management. Use it. For production deployments, prefer OIDC-based cloud authentication so your CI system never holds long-lived cloud credentials at all.
Scope access to secrets narrowly
Each service, pipeline, and developer should have access only to the specific secrets they need. A frontend application server does not need the database admin password. A developer working on the billing module does not need the private key used for email signing.
Apply least-privilege at the secrets level: create distinct service accounts and corresponding secrets for each logical service, and revoke access when it is no longer needed (when a developer leaves, when a service is decommissioned).
Audit secret access
A secrets vault should produce an audit log: who retrieved which secret, when, and from where. This log serves two purposes: it helps you detect anomalous access patterns (a secret being retrieved from an unusual IP or at an unusual time), and it provides forensic evidence if a breach occurs.
Enable audit logging in your vault from the start. Ship those logs to your central log aggregation system where they cannot be modified by the application that generated them.
Handle secret exposure incidents
Despite good controls, secrets are occasionally leaked. Have a process ready before you need it:
- Rotate the exposed credential immediately
- Audit access logs for the period during which it was valid
- Determine the scope of exposure (was it public? accessed by anyone?)
- Notify affected parties if required by your compliance obligations
- Conduct a post-incident review to understand how the exposure occurred and close the gap
Speed matters in secret exposure. The faster you rotate, the shorter the window for exploitation.
Building production systems and want a team that treats secrets as a first-class concern from day one? Start a build.