Join our Newsletter — 33% off our NHI Course
Home› NHI Breaches› PyPI Secrets Exposure 2023: How 3,938 Secrets, 768…
Breach analysis Incident: 13 Nov 2023

PyPI Secrets Exposure 2023: How 3,938 Secrets, 768 of Them Valid, Were Found in Published Python Packages

← All NHI breaches
By Lalit Choda, NHI Mgmt Group Updated 29 September 2026 6 min read
Category: NHI
On this page

In November 2023, GitGuardian and security researcher Tom Forbes published the results of scanning every package on the Python Package Index (PyPI) for hard-coded secrets. They found 3,938 unique secrets across 2,922 projects, of which 768 were confirmed to be valid when checked. Because secrets were often left in several releases of the same project, the total number of occurrences was 56,866. The secrets covered 151 types, including AWS keys, Azure Active Directory API keys, GitHub OAuth app keys, database credentials for MongoDB, MySQL and PostgreSQL, SSH credentials and Twilio master credentials. PyPI itself was not breached: developers published the secrets by accident, often in test folders, configuration files and READMEs, and a new release does not remove the old one. GitGuardian noted that only 300 releases had been yanked, and that yanking does not make a file unavailable. No misuse of the secrets was reported in the research.

Key takeaways

  • GitGuardian and Tom Forbes found 3,938 unique secrets in 2,922 PyPI projects; 768 were valid.
  • Secrets repeated across releases added up to 56,866 occurrences.
  • Valid secrets included Azure AD API keys, GitHub OAuth app keys, database, SSH and Twilio master credentials.
  • Publishing a clean release or yanking an old one does not remove the secret; only rotation does.
  • The identity lesson: a published package is permanent and public, so every credential that reaches it must be treated as leaked.

At a glance

OrganisationsPublishers of 2,922 PyPI projects; GitGuardian and Tom Forbes (research)
WhenPublished 13 November 2023
AttackerNone known. Found by researchers
Entry pointSecrets hard-coded in published Python packages
Identities abusedCloud keys, API keys, OAuth app keys, database and SSH credentials; none confirmed misused
Impact3,938 unique secrets exposed, 768 valid; 56,866 occurrences across releases
CategoryNHI. Incident class: exposure (secrets in published packages, no confirmed misuse)

What happened

GitGuardian summarised the findings: "3,938 total unique secrets across all projects," "768 of those unique secrets were found to be valid" and "2,922 projects contained at least one unique secret." It put them in context: "there are over 450,000 projects released through the PyPI website, containing over 9.4 million files," and "If we add up all the secrets shared across all the releases, we found 56,866 occurrences of secrets, meaning once a secret enters a project, it is often included in multiple releases." Among the valid secrets it listed Azure Active Directory API keys, GitHub OAuth app keys, database credentials, Dropbox, Auth0, SSH, Coinbase and Twilio master credentials.

Most leaks were accidental. GitGuardian found 209 unique secrets in README files and 675 in test folders, and reported at least 15 cases where the publisher did not know the project was public. Often a developer published a secret and then quickly released a new version without the file. GitGuardian warned that this is not a fix: "just releasing a new version does not remedy the situation." Nor is yanking: "Only 300 releases have been yanked, compared to 56,566 releases containing secrets," and a yanked file "is still downloadable if you have the URL." It also noted that Python packaging does not honour a project's .gitignore by default, so local configuration files can end up in a release.

The research built on Forbes' earlier work. In January 2023 he wrote that after scanning every release on PyPI he "found 57 valid access keys" for AWS, and built a tool that scans new releases and reports keys to AWS. SecurityWeek summarised GitGuardian's warning about the wider risk: "Attackers can exploit this information to gain unauthorized access, impersonate package maintainers, or manipulate users through social engineering tactics."

Timeline

DateEvent
6 January 2023Tom Forbes publishes his scan finding 57 live AWS keys on PyPI.
13 November 2023GitGuardian publishes its PyPI secrets research with Forbes.
14 November 2023SecurityWeek reports the findings.

How it happened: the identity attack path

  1. Secrets in the working tree. Developers kept credentials in code, configuration, tests and READMEs.
  2. Packaged by default. Build tools included files that .gitignore kept out of the repository.
  3. Published permanently. Releases on PyPI stay downloadable, including yanked ones.
  4. Repeated across versions. A secret added once often appeared in many later releases.
  5. Found by scanning. Researchers downloaded packages and validated the secrets they found.

Impact

  • Exposed: 3,938 unique secrets of 151 types in 2,922 projects.
  • Valid: 768 secrets confirmed working; others could not be checked.
  • Misuse: none reported in the research.

What this means for NHI governance

Package registries are a publishing channel that never forgets. Every non-human credential that reaches a release, whether an AWS key for an integration test or a database password in a sample config, becomes public and stays public. GitGuardian's point that only rotation makes a secret safe is the key one: "Only once a secret has been properly rotated can you know if it is invalid."

The defences sit before publication: secret scanning of build artefacts, not only repositories, explicit file lists for packages and short-lived test credentials. See our Secrets Management Guide and CI/CD Pipeline Identity Security Guide.

Recommendations

  • Scan the built package, not just the repository. Check wheels and source distributions before upload. See our Secrets Management Guide.
  • List package contents explicitly. Do not rely on .gitignore to keep files out of releases. See the CI/CD Pipeline Identity Security Guide.
  • Rotate any secret that was published. A new release or a yank does not revoke it. See the Leaked Credential Response Playbook.
  • Use short-lived credentials for tests. Prefer local emulators or temporary cloud credentials. See the Cloud Workload Identity Guide.
  • Publish from CI, not laptops. A clean build environment keeps local configuration files out of releases.

Frequently asked questions

Was PyPI breached?

No. The secrets were published by package developers by mistake. GitGuardian and Tom Forbes found them by scanning public packages.

How many secrets were found on PyPI?

3,938 unique secrets across 2,922 projects, of which 768 were valid, with 56,866 occurrences across releases.

Does yanking a PyPI release remove a leaked secret?

No. A yanked release can still be downloaded from its URL. The secret must be rotated.

Secrets in VS Code Extensions 2025 · Docker Hub Secrets Leak 2025 · Secrets Management Guide · CI/CD Pipeline Identity Security Guide · Leaked Credential Response Playbook

How NHI Mgmt Group can help

Anything published stays published. We help teams scan releases, keep credentials out of packages and rotate quickly when a secret ships. See our NHI and AI agent security training.

References

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Written and reviewed by Lalit Choda, NHI Mgmt Group. Last updated 29 September 2026.
Based on the public sources listed under References. Details may change as investigations continue.
NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org