Secrets have a half-life
Leaked credentials keep working for years. The number that matters is not how many leak but how fast a leaked one stops working, and a secrets programme should be built on that.
The assumption most secrets programmes are built on is that leaks are preventable. Scan the commits, block the push, train the team, and the secret never reaches a public repository. The assumption is wrong at scale, and GitGuardian's State of Secrets Sprawl 2026 puts numbers on how wrong: 28.65 million new hard-coded secrets reached public GitHub commits in 2025 alone, up 34 percent on the year before. Prevention is worth doing. It is not the thing that decides whether a leak hurts you. What decides that is how long the secret keeps working after it leaks, and the report's other finding is the one to build on.
The secret that keeps working
Of the credentials GitGuardian confirmed valid in 2022, close to 70 percent were still valid in January 2025, and when retested in January 2026, more than 64 percent still worked. Four years after being pushed to a public repository, nearly two thirds of those keys had not been rotated or revoked. They had simply been forgotten, by everyone except whoever had copied them.
That is a half-life, in the physical sense: a leaked credential population that loses a small fraction of its validity each year and is mostly still alive after four. It should be measured in minutes. The distance between those two numbers, years and minutes, is the whole design space of a secrets programme, and prevention does not touch it.
The blast clock
The number I care about for each secret is what I call its blast clock: the elapsed time from the moment it leaks to the moment it stops working. The clock has three segments. Detection, the time until anyone notices the leak. Revocation, the time from noticing until the credential is dead. Rotation, the time until the systems that depended on it are running on a replacement, which is what allows revocation to happen without an outage. A secrets programme sets a target for the clock per class of secret, and then chooses mechanisms by how much each one shortens which segment.
The segments are not equally hard. Detection depends on scanning, on the repository being public, and on luck; the GitGuardian figures are for secrets that were found, which is a lower bound on the population. Revocation depends on whether anyone can revoke the credential quickly, which for a key issued by a vendor's console means a person with the right login and a working day. Rotation depends on whether the systems that use the credential can pick up a new one without a redeploy, which is a property of how the credential was wired in.
The lever that shortens all three at once is lifetime. A credential that expires on its own in fifteen minutes has a blast clock of at most fifteen minutes whether or not anyone detects the leak, revokes anything or rotates anything. That is why the biggest single change a small team can make is not a scanner. It is replacing long-lived credentials in CI with short-lived ones obtained at the start of each job, through federation with the cloud provider, so that the pipeline never holds a secret that outlives the job. GitHub's OpenID Connect integration is the usual mechanism: the job presents a signed token about itself, the cloud provider exchanges it for credentials scoped to that job and that repository, and there is nothing to store, nothing to leak and nothing to rotate.
The shape of that change is worth dwelling on, because it is the difference between managing secrets and not having them. Every secret in a pipeline is a liability with a half-life, and the cheapest way to shorten the half-life is to make the secret not exist between jobs. A long-lived cloud key stored in the repository's secret settings is a credential that outlives every job that used it; the federated token is a credential that dies with the job that requested it. Nothing about the work the job does changes. Only the clock does.
Ranking secrets by how fast they die
SocialSure's platform ships through a CI/CD pipeline into containers, and the Habits app builds on GitHub Actions, so the pipeline is where most of the credentials in my life live. Sorting them by blast clock, rather than by how sensitive they feel, produced a ladder with four rungs.
The ladder sorts by a different property from the one most teams use, and the difference matters. Sensitivity asks how bad a leak would be. The blast clock asks how long a leak would stay bad. A database password is sensitive and, if rotation is automated, dies in minutes; a read-only analytics key is far less sensitive and, if it was issued by a vendor and nobody knows how to revoke it, lives for years. Sorting by sensitivity puts the first one at the top of the worry list. Sorting by the clock puts the second one there, which is where the four-year-old keys in the GitGuardian figures came from.
The bottom rung is the one that changes behaviour. An Android app signing key from the era before Play App Signing cannot be replaced: lose it or leak it and the app can never be updated under its old identity on older devices. A credential with a blast clock of never does not belong in a pipeline, in a repository, or on a laptop; it belongs in an escrow with a ceremony, and the pipeline uses an upload key that Google can reset on request. The rung above, vendor-issued keys with a days-long clock, gets split custody and never appears in plaintext in a build log. The two top rungs are what the pipeline actually runs on, and the top one needs no revocation at all.
What it changes day to day
Three practical consequences fell out of thinking in clocks rather than in prevention.
The scanner stayed, but its job changed. It is no longer the thing that keeps secrets safe; it is the detection segment of the clock, and its value is measured by how much it shortens that segment, which for a public repository is from months to minutes. For private repositories it is a cheaper and less urgent control, because the population that can read the leak is smaller, though not, as the GitGuardian figures on private and internal leaks show, small.
Rotation became a scheduled, automated event rather than a response to an incident. A key that is rotated every week by a job has a rotation segment of zero on the day it leaks, because the replacement path already exists and has been exercised. A key that has never been rotated has a rotation segment that includes discovering how, which is the segment that turns a leak into an outage.
And every new credential now arrives with a question before it is created: what is its blast clock, and can it be made shorter by not creating it at all. Most of the time the answer is a federated token, and the secret never exists.
The leak rate will keep rising. The report's numbers say so, and a small team is not going to reverse the trend. What a small team controls is the half-life, and a half-life of minutes makes the leak rate a statistic rather than a threat.
Get new posts by email
Occasional essays on engineering, AI, and building for the people technology leaves behind.
Subscribe with RSS