543,699 live keys sit in public GitHub repos
Truffle Security tested secrets in 224 million public repos and 543,699 still worked, with a median age of 784 days. What leaks, why it survives, what to do.
By Yaali. October 3, 2026, 5 min read, Identity, Threat intel, Resilience.
Truffle Security scanned 224,553,295 public GitHub repositories and found 543,699 unique credentials that still authenticated when it tested them on July 27 and 28, 2026. The median live credential had been sitting on a public default branch for 784 days, a little over two years. One in ten had been public for more than 6.3 years, and the oldest, a database credential committed in June 2009, still worked.
If your developers have ever pushed to a public repository, some of these could be yours. GitHub's push protection has reduced new leaks of the formats it covers, but it does nothing about keys already public, and many providers do not revoke keys that leak. Whether a leaked key keeps working comes down to who issued it.

How the study worked
The data came from The Stack v3, a snapshot of public code assembled to train AI models. Its crawl closed on August 7, 2025 and covers 58,467,468,698 files. It keeps only each repository's default branch as it stood at crawl time, so deleted branches and rewritten history are not in it. The real number of exposed secrets on GitHub is likely higher.
Truffle matched credential patterns, then tested each candidate against the service that issued it. A key counted as live only if that service accepted it in July 2026, close to a year after the crawl. Because the same secret often appears in many forks, Truffle counted each credential once by its value: 543,699 unique credentials came from 1,103,438 separate exposures.
The largest group was Google Cloud service account keys, with 69,041 live. Behind them came 51,067 MongoDB connection strings and 33,343 Google API keys.
Why push protection did not save them
Push protection is the GitHub feature that rejects a git push when it spots a known secret format in the commit. GitHub turned it on by default for public repositories on February 29, 2024. Truffle compared leak rates in the 12 months before and after that date: for credential types the default blocks, leaks per million files fell by 53 percent, against 7 percent for types it does not block.
Push protection matches provider patterns, meaning token formats a vendor has registered with GitHub. Connection strings and private keys fall under what GitHub calls non-provider patterns, which Truffle describes as opt-in. According to Truffle, 51.8 percent of all live credentials in the study were of a type a default-configured public repository accepts without complaint, mostly database connection strings, Google API keys and private keys.
Push protection also only acts at push time. It does nothing for a key committed in 2019. Of the live credentials, 199,843 (36.8 percent) were pushed after the default changed; the other 63.2 percent were pushed before it.
What decides whether a leaked key dies
Some providers revoke their own tokens when they find them in public code. Others leave it to the owner, and the key keeps working until the owner notices.

Only 1 of 101,886 committed npm tokens still worked. GitHub tokens were close behind at 260 live out of 73,048, and Hugging Face tokens at 15 of 30,437. At the other end, 11,465 of 12,985 PostgreSQL connection strings, about 88 percent, still connected. Google Cloud service accounts sat in the middle at 69,041 of 126,963, roughly 54 percent.
A database URL has no issuer watching for it. The password inside it stays valid until someone with access to the database changes it, and that only happens if the team knows the string is public.
What to do
Start by treating any credential that has ever been committed to a public repository as compromised, whether the repository is still public, was later made private or had the file deleted. Forks and clones keep the old commit.
- Find what you have exposed. Scan your organization's repositories, including history, with a tool that verifies findings against the issuer. With TruffleHog that is
trufflehog github --org=<your-org> --only-verified. Include personal repositories of developers who have worked on your code, since many leaks come from side projects and test copies. - Revoke and reissue, do not just delete the file. For an AWS key, deactivate it in IAM and create a new one. For a Google Cloud service account, disable and delete the key under IAM and Admin, Service Accounts, Keys. For a PostgreSQL connection string, change the role's password with
ALTER ROLE <name> WITH PASSWORD '<new>';and update the applications that use it. For a MongoDB Atlas string, rotate the database user's password. - Check whether the key was used. For AWS, search CloudTrail for the
AccessKeyIdover the full period it was public. For Google Cloud, filter Cloud Audit Logs on the service account's email as the principal. For databases, look at connection logs for source IP addresses outside your hosting ranges. - Turn on the detection you are missing. On GitHub Team or Enterprise Cloud with Secret Protection, open the repository's Settings, Advanced Security, and enable Non-provider patterns under Secret Protection. That adds MongoDB, MySQL and Postgres connection strings, RSA, OpenSSH and PGP private keys, and HTTP authentication headers to scanning. Findings appear under a separate Other tab in the secret scanning alerts.
- Make the next leak expire on its own. Replace long-lived keys with short-lived ones: workload identity federation for Google Cloud, IAM roles and OIDC federation for AWS from CI pipelines, and database credentials issued per session where your platform supports it.
AI training data carries these secrets too
The Stack v3 exists to train AI models, so every live key in this study also sits in a training corpus. Truffle found the same problem when it scanned 7.6 petabytes of Hugging Face training data and found 221,303 working credentials. This GitHub result is more than double that. Deleting a commit today does not remove a key from a dataset that copied it in 2025. Only revoking the key does.
We look for committed and leaked secrets as part of attack surface management, and review how keys are stored and rotated in cloud and Kubernetes security work. If you want to know what your organization has left in public code, open the chat and Yaali, our AI agent, will pass your question to an engineer.
Sources: Truffle Security, Truffle Security, Hugging Face training data scan, GIGAZINE, Cyber Security News, GBHackers, GitHub Docs, non-provider patterns.
Read next
- Cloudflare becomes a CA for post-quantum certificates
- One AI-written mail script exposed 95,364 customer emails
- TA419 poses as AI policy figures to hijack M365 logins
Back to the blog, or tell us about your system in the chat. Yaali, our AI agent, answers first and brings in an engineer.