One npm Token Survived. 11,465 Postgres Passwords Did. Revocation Decides Whether a Leaked Key Dies.

Written by the Rafter Team

As of October 1, 2026.
Whether a leaked credential dies depends on who issued it. If the issuer runs a pipeline that revokes leaked tokens, almost none survive. If you minted the credential yourself, a database password or a service account key, it stays live until you rotate it, and in public code that has meant years.
What Truffle found
On September 29 Truffle Security published a scan of 224,553,295 public GitHub repositories, taken from The Stack v3, a snapshot of public code assembled to train AI models. The snapshot keeps only each repository's default branch as of August 7, 2025. Truffle tested every candidate credential against its issuer on July 27 and 28, 2026, and 543,699 still authenticated.
The median live credential had sat in public for 784 days. The 90th percentile was 6.3 years. The oldest, database credentials in an Erlang web server config, was last modified on June 13, 2009.
Just under 200,000 of them, 199,843, landed after GitHub turned push protection on by default for public repositories on February 29, 2024.
The split is the issuer
Sort the credentials by family, count how many were committed and how many still work, and the result runs from almost nothing to almost everything:
- npm tokens: 101,886 committed, 1 still live.
- GitHub tokens: 73,048 committed, 260 still live.
- Hugging Face tokens: 30,437 committed, 15 still live.
- AWS access keys: 82,411 committed, 6,819 still live.
- Google Cloud service accounts: 126,963 committed, 69,041 still live.
- Postgres connection strings: 12,985 committed, 11,465 still live.
Truffle's reading: "GitHub and npm revoke their own tokens and almost nothing survives. Nobody revokes a Postgres URL, and almost everything does."
The middle of that list matters as much as the ends. GitHub runs a secret scanning partner program that forwards a leaked token to the provider that issued it, but "the program does not require partners to revoke anything." So a provider can be told about a leak and still leave the key working. Truffle found an AWS key from November 2009 that still worked.
What push protection did and did not do
Push protection blocks a push to a public repository that contains a secret GitHub recognizes, unless the developer chooses to bypass it. Truffle compared the families GitHub blocks with the families it does not, across the twelve months either side of the rollout. The protected group fell 53 percent; the unprotected group fell 7 percent. The block works at the door.
It does nothing for what is already inside, and it does not cover the shapes that survive best. Connection strings and private keys count as generic patterns, which are off by default. Google API keys are on GitHub's list and marked as not push protected. In Truffle's count, "51.8 percent of every live credential in this corpus is a connection string, a Google API key or a private key, none of which are blocked by default."
Its conclusion: "What keeps a leaked credential alive is revocation, not the block at push time."
You are the revocation pipeline
For a token GitHub or npm issued, someone else runs the kill switch. For a credential your team created, no one does. That covers database users and connection strings, cloud service account keys you exported, SSH and TLS private keys, and API keys for internal services. Connection strings have the highest survival rates in Truffle's data: 88 percent for Postgres and 75 percent for MySQL.
The useful question about an old connection string in a public commit is not whether the commit was deleted. It is whether the password has changed since the day it was pushed.
The same keys are being looked for. An OpenAI misalignment report published September 16 describes a model in training that searched public GitHub repositories for leaked API keys and used one that authenticated; we covered a related OpenAI report on a model that published a token.
What to do now
- List the credentials you issue yourself. Database users, exported service account keys, private keys, internal API keys. These have no issuer-side kill switch.
- Scan your full history, not only new pushes. Truffle's advice: "Anything committed before February 2024 was never in scope" for push protection. Scan old branches, forks and archived repositories too.
- Rotate first, clean history second. Truffle says to "treat a committed credential as burned the moment it lands." Deleting the file or rewriting history does not stop anyone who already copied it; our leaked-key response guide covers the order.
- Give credentials a lifetime. Short-lived tokens and workload identity expire whether or not anyone notices a leak. Truffle notes that most of what it found "would have aged out harmlessly if it had ever been given a lifetime."
- Ask your providers whether they revoke. Being in a scanning partner program means a provider hears about a leak; acting on it is up to the provider.
- Turn on what push protection leaves off. Organizations can enable generic patterns, including private keys and connection strings, which GitHub does not block by default. Our post on what GitHub secret scanning catches and misses has the details.
Where Rafter fits
rafter secrets . scans a directory locally with no account, and its built-in patterns include database connection strings and private keys, two of the shapes push protection skips by default.
rafter agent install-hook runs the same scan on staged files before each commit.
Neither revokes anything: a scanner finds the credential, and only its issuer, or you, can kill it.