Back to Insights
SECURITY9 min read

Secrets, Least Privilege, and the Blast Radius Nobody Measures

Published Jun 23, 2026alphabench Engineering

The breaches we get called in after are almost never clever. There is rarely a novel exploit or a determined adversary doing something impressive. There is a credential that lived too long, had far more access than it ever needed, and ended up somewhere it should not have been - a CI log, a laptop, a repository that went public for six hours in 2023.

The interesting question is not how the credential leaked. Credentials leak. The interesting question is what it could reach once it did, and how long it stayed useful. That is blast radius, and most teams have never measured theirs.


Ask What This Key Can Do

Pick a service in your system and answer three questions about the credentials it holds.

What can this credential reach? Not what does the service use it for - what would it permit. A database user that the application uses to read two tables, but which was granted broad access because that was faster during setup, has the blast radius of the broad grant, not of the two tables.

How long is it valid? A static key in an environment variable is valid until someone rotates it, which in practice means indefinitely.

How would you know it was used by someone else? If the answer involves reading raw logs and noticing something unusual, the honest answer is that you would not.

Run that exercise across a system and the picture is usually uncomfortable. Not because anyone was careless, but because permissions accumulate. Someone needed broader access for a one-off migration in 2024 and the grant was never narrowed. That is the normal path.

Every credential is eventually exposed. The only variable you control is what it is worth to whoever finds it.


Kill Long-Lived Static Credentials

The single highest-value change available to most teams is eliminating static secrets in favor of short-lived, automatically issued ones.

Between your own services, use workload identity. A service proves what it is to the platform and receives a token valid for minutes. Nothing is stored, nothing needs rotating, and a leaked token is worthless before anyone can use it. Every major platform supports some form of this, and it is usually one of the less painful migrations available.

For third parties that require an API key, put it in a real secret manager with automated rotation, and make sure the application fetches it at runtime rather than baking it into an image or a config file at build time. A secret in an image layer is a secret in your registry forever.

For humans, no shared credentials. Individual identity, SSO, short-lived sessions, and MFA on anything that matters. A shared production password means your audit log cannot answer who did something, which means it is decoration.

Assume rotation will happen under pressure. Build and rehearse the ability to rotate any credential in minutes. Teams that have never practiced it discover during an incident that rotating the main database password requires a coordinated restart nobody has documented.


Least Privilege as a Default, Not a Cleanup Task

Least privilege stated as a principle is easy to agree with and easy to ignore. What makes it stick is making the narrow path the easy one.

  • Start from deny. New service, no permissions. Add each one deliberately when something fails. This is more tedious for a day and correct for years. Starting broad with the intention of narrowing later is a plan nobody has ever executed.

  • Separate read and write identities. A reporting job that only reads should hold a credential that cannot write. This one change caps the damage of an enormous class of compromise.

  • Scope by resource, not just by action. Permission to read one bucket, not all buckets. Access to the rows belonging to one tenant, not the table. Broad action scoping is where multi-tenant systems leak across tenants.

  • Time-box elevated access. Production write access for a human should be requested, justified, granted for an hour, and logged. Standing admin access held by eight people is eight permanent openings.

  • Expire access with a review date. Permissions granted for a specific project should carry an expiry. Without one, the only mechanism that ever removes access is someone leaving the company, and often not even then.


Where Secrets Actually Leak

In our experience, in rough order of frequency:

CI/CD logs. A build script echoes an environment variable, or a tool prints its config on error. Mask secrets in log output at the platform level and never rely on individual scripts being careful.

Error reporting and observability tools. An exception captures the request context including an Authorization header, and it is now in a third-party service with a different access model than the rest of your stack. Scrub at the SDK level, before transmission.

Local developer environments. A .env file with production credentials, on a laptop, backed up to a personal cloud account. Developers should never hold production secrets - if a task requires them, that is a gap in tooling, not a reason to hand over the keys.

Committed to the repository. Still happens constantly. Pre-commit scanning plus server-side push protection catches most of it. Note that a secret committed and then removed is still in the history and must be treated as compromised regardless.

Ticketing and chat. Someone pastes a token into a ticket to help a colleague debug. It is now in a system with a broad access list and a long retention policy.


Detection Is the Half Nobody Builds

Prevention fails eventually. What separates a contained incident from a bad one is how quickly you notice.

Log every use of a privileged credential, including the source. If your database access logs do not record which identity and which network origin, you cannot investigate anything.

Alert on shape, not just volume. A service account that has read the same three tables every day for a year suddenly enumerating schemas is the signal. So is a credential appearing from a new region, or being used outside its normal hours. These are simple rules and they catch real things.

Plant canaries. A credential that is never legitimately used, placed somewhere an attacker would look, wired to an alert. Zero false positives by construction, and it is one of the cheapest detections you can build.

Test that the alerts fire. An alerting rule nobody has verified is a belief, not a control. Deliberately trigger each one on a schedule.


Segmentation Limits What a Foothold Is Worth

Credential hygiene limits what one key opens. Network and data segmentation limit what an attacker can do once inside with a legitimate key.

Default-deny between services. Most internal networks are flat by accident - anything can reach anything because that was the state on day one and nobody narrowed it. If a compromised image-resizing service can open a connection to the payments database, the blast radius of a trivial service is the blast radius of your most sensitive one.

Separate environments completely. Staging should not be able to reach production data, and staging credentials should not work against production. This sounds obvious and is violated constantly, usually via a shared secret store or a convenience path someone added to debug an issue.

Isolate the highest-value data. The tables holding payment details, health records, or credentials deserve a different access path than general application data - a separate schema with a distinct role, ideally a separate database. This makes both least privilege and audit substantially easier to reason about.

Constrain outbound traffic, not just inbound. Exfiltration needs a path out. Services that have no reason to make arbitrary outbound connections should not be able to, and most services have no such reason.


When the Credential Is Already Out

Assume this will happen. The quality of the response depends almost entirely on decisions made beforehand.

Revoke before you investigate. The instinct is to determine the scope of the problem first. Rotate immediately instead - you can investigate a revoked credential at leisure, and every minute a live one stays valid is a minute of exposure. This is only possible if rotation is fast, which is the argument for practicing it.

Know what it touched. This is where access logging pays for itself. Without per-identity logs you cannot distinguish "leaked but never used" from "leaked and used extensively", and you will end up assuming the worst in every regulatory notification you file.

Check for persistence. An attacker who used a credential to create a second credential still has access after you rotate the first. Review what was created or modified during the exposure window, not just what was read.

Treat the history as compromised. A secret committed to a repository is in every clone and every fork. Removing the commit does not help. Rotate, always.

Write the timeline as you go. In a regulated environment you will need it, and reconstructing it a week later from memory and chat logs is far worse than keeping a running note during the response.


Where to Start

Do the inventory first, because you cannot fix what you have not enumerated. List every credential in the system with three columns: what it can reach, how long it lives, and who or what holds it. That list is usually the most persuasive security document a team produces all year.

Then work in this order: eliminate the static credentials that can be replaced with workload identity, narrow the two or three permission grants with the largest blast radius, add scrubbing to logs and error reporting, and stand up one detection rule you have actually tested.

That is a couple of weeks of work and it removes most of the paths that turn a minor exposure into an incident. In regulated environments the bar is higher and the evidence requirements are specific - we cover that ground in HIPAA Compliance Is Not a Checkbox and Building PCI-Compliant Checkout in 2026. If you want an outside read on where your blast radius actually is, that is part of what a Software Architecture Audit covers.

You will not prevent every leak. You can make sure the thing that leaks is not worth much and does not stay valid for long.

Have a similar challenge?

Let's discuss how we can help you build the right solution.

START A PROJECT