17 March 2026 · 5 min read

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.

Share of credentials leaked in 2022 that still worked years later Two horizontal bars: about 70 percent of the credentials confirmed valid in 2022 were still valid in January 2025, and about 64 percent were still valid in January 2026. The decay over a year is small. Four years on, most of them still work Credentials confirmed valid in 2022, retested later, per cent still valid January 2025 about 70 January 2026 above 64 A half-life measured in years, for keys that were public the whole time. The 28.65 million new secrets of 2025 will decay at about the same pace.
Source: GitGuardian, The State of Secrets Sprawl 2026.

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 blast clock for one leaked credential A horizontal timeline from the leak to the moment the credential stops working, split into three segments: detection, revocation and rotation. Below, two versions: a long-lived API key where each segment is days or longer, and a short-lived federated token where the whole clock is under an hour because the token expires on its own. Three segments, one clock From the leak to the moment the credential is useless Long-lived API key detect: months revoke: days rotate: days Short-lived token expires on its own; no one has to notice leak credential dead Target: minutes for CI credentials, hours for anything a human issued.
Illustrative: the three segments the programme is designed around; durations are typical, not measured.

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.

Credential classes by how fast a leaked one can be killed Four rows. Federated tokens: seconds to minutes, expire on their own; the default for CI. Keys you issue yourself, such as API keys and database passwords: minutes, if rotation is automated. Keys a vendor issues, such as an app upload key: days, via a support process. Keys that identify the product itself, such as a legacy signing key: never; they must not touch CI at all. The revocation ladder CLASS TIME TO KILL RULE Federated, short-lived tokens minutes, alone the default for every job Keys you issue yourself minutes, scripted rotate on a schedule Keys a vendor issues days, by support split custody Keys that are the product never must not touch CI at all Sorted by blast clock, not by how sensitive the secret feels.
Illustrative: the ladder as applied to a small team's pipeline; the classes are general, the examples are from Android and cloud release work.

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.

Secrets ManagementCI/CDSecurity
All writing

Written by Mohd Shayan

Get new posts by email

Occasional essays on engineering, AI, and building for the people technology leaves behind.

One email per new post. Unsubscribe any time.

Subscribe with RSS