Skip to content

Security

Secrets and Credential Management

A secret is anything that grants access if it falls into the wrong hands: a database password, an API key, a signing certificate, a cloud provider's credentials. Secrets management is the discipline of keeping those out of source code, logs, and casual chat messages, storing them somewhere access-controlled and auditable, and rotating or revoking them when they might have leaked. It matters as much for how ordinary and easy the mistake is - a hardcoded key committed by accident - as for any exotic attack.

Why it matters

A leaked secret often grants access as complete as a stolen password would
An API key or database credential found in a public repository or a log file can let an attacker act with the same access the legitimate service had, often without anyone noticing right away.
Source control remembers everything, including things later deleted
Committing a secret and then removing it in a later commit doesn't remove it from the repository's history, which is why leaked secrets in version control need to be rotated, not just deleted.
Secrets end up in logs and error messages more often than people expect
A request logged for debugging, or an exception message that includes a connection string, can leak a secret through a channel nobody thought of as sensitive.
Rotation limits how long a leak matters
A secret that can be quickly replaced turns a leak into a bounded incident; one that's hardcoded everywhere and never rotated turns the same leak into a much larger, longer-lived problem.

Secrets don't belong in source code

Hardcoding a credential directly into application code or a config file that gets checked into version control is the most common way secrets leak, because that history is permanent and often visible to more people, past and present, than the current production environment is. The standard fix is to read secrets from the environment, or from a dedicated secrets manager, at runtime, and to keep any local file that does contain real secrets explicitly out of version control.

Shell
# secrets are read from the environment at runtime, never hardcoded
export DATABASE_URL="postgres://app_user@db.internal:5432/orders"
export DATABASE_PASSWORD="$(vault read -field=password secret/orders-db)"

# .gitignore keeps local files that DO contain secrets out of version control
echo ".env" >> .gitignore

Least privilege for machine identities, not just people

A service's credentials should be scoped to only what that service actually needs - read-only where writing isn't required, limited to the specific resources it touches - the same least-privilege principle applied to human accounts, applied here to API keys and service accounts. A single broad credential shared across many services turns any one of them being compromised into access to everything the credential can reach.

Rotation and revocation

A secret should be easy to replace without a lot of manual coordination; one that's hard to rotate tends to simply never get rotated, which turns 'was this ever exposed' into a permanent unknown. Routine rotation, done on a schedule rather than only after a confirmed leak, limits how long a secret nobody yet knows has leaked stays useful to whoever has it.

Mistakes people make here

Hardcoding a credential directly in source code
it ends up in version control history permanently, visible to anyone with repository access, past or future, even after the line is later deleted.
Committing a .env file or config file that contains real secrets
these files are meant for local, per-developer configuration; committing one puts every value in it, often including production credentials copied for convenience, into shared history.
Using the same credential across development, staging and production
it means a leak in the least-protected environment, often development, has the same consequences as a leak in production, and rotating it means rotating it everywhere at once instead of just where it leaked.
Treating rotation as something to do only after a known leak
routine rotation limits how long a secret nobody knows has leaked stays useful to whoever has it; waiting for a confirmed incident means an unknown, silent leak is never addressed at all.
Logging full request or response bodies without redacting sensitive fields
authorization headers, API keys and passwords passed in requests routinely end up captured verbatim in logs unless the logging code specifically excludes them.

Strengths and trade-offs

Where it is strong

  • Dedicated secrets managers, separate from application code and config, provide access control, an audit trail, and centralized rotation that scattered environment variables or config files can't.
  • Scoping machine credentials narrowly limits the damage of any single leaked secret to whatever that one credential could actually do.
  • Automated secret scanning in CI and pre-commit hooks catches accidental commits before they reach a shared, permanent history.

The trade-offs

  • A dedicated secrets manager is another system to run, secure and keep available - it becomes a critical dependency in its own right.
  • Fine-grained credentials are safer but require more setup and bookkeeping to issue, track and rotate than one broad credential shared everywhere.
  • Rotation has to be coordinated with everything that uses the old credential, or rotating it breaks the service instead of just securing it, which is real operational work, not a switch to flip.

Who needs this

Every developer who ever configures a database connection, an API key, or a third-party integration handles secrets, whether or not their role includes 'security' in the title. Building and operating a centralized secrets management system is a more specialized platform or security engineering responsibility.

Questions about secrets and credential management

Why not just keep secrets in a private repository?
Private still means every collaborator, past and present, along with anyone who gains access later, can see the full history, including a secret that was 'removed' in a later commit. A dedicated secrets manager, with its own access control and audit log separate from code access, doesn't have that problem.
What should I do if I accidentally commit a secret?
Rotate the credential immediately - treat it as leaked, because it likely is, even if the commit is later removed or the repository is private. Deleting the commit or force-pushing over it does not reliably remove it from every clone, cache, or fork that may already have it, so rotation is the only step that actually neutralizes the exposure.
What's the difference between a secret and just sensitive data?
A secret specifically grants access - a password, key, or token that lets someone authenticate or act as a service. Sensitive data, like a user's personal information, needs protecting too, but for different reasons and often with different controls; a secret's exposure typically has a more direct, immediate consequence because it can be used to gain further access.
Do secrets need to be encrypted if they're already in a secrets manager?
Yes - most secrets managers encrypt data at rest as a baseline, but that protects against the storage being accessed directly; it doesn't replace access control over who can ask the secrets manager for the value, or audit logging of who did ask, both of which matter just as much as the encryption itself.

The primary source

Related concepts

← All concept guides