Every engineering team has secrets: database passwords, third-party API tokens, signing keys, cloud credentials. Most teams also have a few in places they should not be. A .env file in a repository's history, a token in a CI variable nobody owns, a password pasted into a support ticket two years ago.
Auditors rarely ask whether you "manage secrets". They ask how a developer gets a production database password, who else could get it, and what happens to it when that developer leaves. The answers reveal the program quickly.
This article covers where secrets belong, how to remove the long-lived ones, how to scan for leaks, what to do when one happens, and what to keep as evidence. Encryption keys held in a key management service follow different rules (rotation there means something specific) and are a separate topic.
What the frameworks ask for
None of the common frameworks has a control called secrets management. The requirement is spread across access and authentication controls.
ISO 27001:2022 Annex A 5.17 (authentication information) covers how passwords and other authentication secrets are allocated and protected. Annex A 8.24 (use of cryptography) covers cryptographic keys.
SOC 2 CC6.1 covers logical access security over protected information assets, which includes how the credentials to those assets are issued and stored.
PCI DSS v4.0 Requirement 8.6 covers system and application accounts. Requirement 8.6.2 says passwords for application and system accounts that can be used for interactive login must not be hard coded in scripts, configuration files or custom source code.
NIST SP 800-53 Rev. 5 IA-5 (authenticator management) includes an enhancement against embedded unencrypted static authenticators.
Read together, they ask for the same outcome: credentials are stored deliberately, access to them is controlled and logged, and they change when they should.
Where secrets should live
The answer is one managed store per environment: your cloud provider's secrets service or a self-hosted secrets manager. Whichever you choose, it should encrypt values at rest, control access per secret or path, log every read, keep versions, and support rotation.
Applications fetch secrets at runtime, or the platform injects them at start. Nothing is baked into an image or committed alongside the code.
The places secrets end up instead, and what to do about each:
| Where it ends up | Why it is a problem | What to do instead |
|---|---|---|
| Source code and committed config | Copied into every clone and kept in history indefinitely | Store a reference; resolve the value from the secrets store at runtime |
| CI/CD variables | Often readable by every pipeline in a project, with no owner | Federated short-lived credentials, or secrets scoped per environment |
| Container images | Anyone who can pull the image can extract it | Inject at runtime from the secrets store |
Developer .env files | Outside central logging, and they survive offboarding | Fetch on demand using the developer's own identity |
| Chat, tickets and wikis | Searchable, retained and widely readable | Share the name of the secret, never the value |
Retire long-lived credentials where you can
The safest secret is one that does not exist. Much of what teams store as static credentials can now be replaced by short-lived ones issued on demand.
Workloads. All three major cloud providers let a running service obtain temporary credentials from its own platform identity: an instance or task role on AWS, an attached service account on Google Cloud, a managed identity on Azure. Nothing is stored, and the credentials expire on their own.
Pipelines. CI systems can federate with cloud providers using OpenID Connect. The pipeline presents a signed token describing which repository and branch it is running for, and receives short-lived cloud credentials in return. This removes the stored access key that is otherwise the most valuable secret in the build system.
People. Engineers reach production through single sign-on and temporary elevation, not shared passwords in a vault folder. The principles are covered in managing privileged access.
What remains after this is usually a short list: third-party API keys, a few database credentials, signing keys, webhook secrets. Some secrets stores can issue database credentials per session, which shrinks the list further. Each remaining secret should have a named owner and a rotation interval.
Rotation that actually happens
A rotation policy nobody executes is a finding waiting to be sampled. Record, for each long-lived secret: the owner, the system it grants access to, when it was last rotated, the interval, and what breaks if rotation goes wrong.
Rotate on events as well as on the calendar:
When someone who could read the secret leaves or changes role. Tie this to offboarding, so it is a step in the checklist rather than a separate memory.
When a secret may have been exposed, however unlikely misuse seems.
When the third party that issued it reports a security incident.
The pattern that avoids outages is overlap. Create the new credential, deploy it, confirm traffic is using it, then revoke the old one. A rotation that has never been rehearsed is often an outage, which is why teams quietly stop doing it.
Scanning before and after commit
Scanning has two jobs: stop new secrets from landing, and find the ones that already did.
On the developer's machine. Pre-commit hooks catch secrets before they leave the laptop. They are optional and easy to skip, so treat them as a courtesy, not a control.
At push. Server-side push protection rejects commits that contain recognizable secrets. This is the control, because it cannot be skipped locally.
On a schedule. Scan full history across every repository, plus CI logs and container images. New detection patterns find old secrets.
False positives are inevitable. Give them a triage path: mark a finding as a test value or a revoked credential, record who decided, and move on. An unreviewed backlog of thousands of findings tells an auditor the scanner is running and nobody is reading it.
When a secret leaks
Speed matters more than tidiness. Work in this order:
Revoke or rotate the credential first. Removing it from the repository does not undo the exposure. Public repositories are scanned continuously by automated tools, so assume the value was copied as soon as it was pushed.
Check what the credential did. Review the logs of the system it grants access to from the time of exposure onward.
Remove it from code and, if needed, from history. Do this after rotation, so scanners stop flagging it. Rewriting shared history disrupts other people's work, so coordinate it.
Record it as a security event under your incident response plan, even if you find no misuse. The record of a well-handled leak is good evidence.
Fix the cause. A secret leaked because a service had no other way to get it. Change that, or the next one follows.
Evidence auditors ask for
When the auditor tests credential management, these answer most requests:
A secrets inventory: names, owners, systems, rotation interval and last rotation date. Never the values.
Access policies on the secrets store, showing who and what can read each secret or path.
Read logs from the secrets store, so you can show that access is recorded and, when asked, who read a given secret.
Scanning configuration and results over the period, with how each finding was resolved.
Rotation records for the secrets with a defined interval, and for rotations triggered by departures.
Incident records for any leaks, with the timeline from detection to revocation.
Branch protection and secret scanning tend to be tested together, since both concern what reaches the repository. The settings auditors look for there are in branch protection rules auditors look for.
How TrustLynce helps
TrustLynce continuous monitoring runs control checks against the cloud, identity and code systems you connect, and routes failures to the owner who can fix them. Evidence collection pulls configuration and logs from those systems on a schedule, so the access policies and scanning results above are on file for the whole period.