Most enterprise security teams know to worry about the third party packages they consume. Far fewer worry about the third party packages they have published. Yet for any company that has been writing JavaScript, TypeScript, or any other npm compatible language for more than five years, there is a near certainty that public packages exist on the registry under the company's own scope, or under personal accounts of current and former employees, that nobody actively maintains. These packages are a small but real attack surface, and they are often invisible to the organizations that own them.
The risk is not theoretical. Account takeover, expired domains tied to maintainer email, scope name reuse, and abandoned package republishing have all been used in real supply chain incidents. Each of these vectors becomes more dangerous when the organization that nominally owns the package no longer remembers it exists.
How packages get forgotten
Forgotten packages tend to be created through a small set of recurring patterns.
The hackathon project. A team builds something interesting at an internal hackathon, decides it might be useful to the broader community, and publishes it. The hackathon ends, the team rotates, and the package sits on the registry under either the company's organizational scope or under the personal account of the engineer who happened to run npm publish.
The shared utility. Engineers extract a small helper library from an internal codebase to make it reusable across teams. They publish it publicly because making an internal registry was too much friction at the time. Six years later, the original use case is gone, but the package is still installable and still part of the public dependency graph.
The vendor relationship. A consulting firm or partner published packages while working with the company, and ownership of those packages was never formally transferred when the engagement ended. The maintainer email points to a domain that may or may not still exist.
The CI integration. A team built and published a small CLI tool to automate something specific to the company's tooling. It is technically still in use, but it is no longer maintained, no longer audited, and no longer reviewed as part of the supply chain program.
In each case, the package keeps existing. Versions can still be added to it. Tags can still be moved. Anyone who controls the maintainer account can ship code that will be installed by anyone who depends on the package, or by anyone who imports it transitively.
Why this matters more than it used to
The threat model around forgotten packages has evolved. Several recent shifts have made these packages more valuable to attackers.
The volume of automated dependency intake has increased. Renovate, Dependabot, and similar bots constantly pull new versions. A new patch release on an old, sleepy package gets installed quickly across many consumers, often before any human review.
Supply chain attackers have shifted from "find a popular package to compromise" to "find any package whose maintainer account is weak." A package with a few dozen dependents is a cheaper target than a package with a million, and it still produces interesting blast radius if those dependents include enterprise consumers.
Provenance signals are present but not yet load bearing. npm now supports signed publishing, but a package that has never been signed can still be republished without a signature without breaking most consumers. The historical absence of provenance becomes the attacker's foothold.
Account hygiene is uneven. The maintainer of a forgotten package might be an ex employee whose 2FA was on a phone they no longer have, or whose recovery email is on a domain that has expired. These are the accounts attackers prefer.
Building a discovery process
Finding forgotten packages at scale requires combining several signals that are individually weak but together form a useful inventory.
Registry scope enumeration. If the company publishes under a scope, list every package in that scope. This is a single API call. Compare the list against the inventory of "active, supported" packages maintained by your platform team. Anything in the registry but not in the inventory is a candidate for review.
Maintainer email correlation. Search the registry for packages whose maintainer email is on the company domain, or on common ex employee personal domains where company work historically lived. Many forgotten packages were published from personal accounts because the engineer did not have publish rights on the org scope at the time.
SCM history mining. Search public repositories under the company organization for package.json files that were ever published, and cross reference against the registry. Packages that were published from a now archived or deleted repository are a strong signal of forgotten state.
Internal dependency graphs. Look at every internal service's dependency tree. Anything that resolves to a package whose name matches the company scope, or whose maintainer is or was an employee, is interesting. If the service depends on a package that nobody on the maintenance team recognizes, that gap is worth closing.
What to do once you find them
The instinct is to unpublish or transfer ownership immediately. Unpublishing is rarely the right move, because consumers downstream may break in ways that surface as customer incidents. Better options include:
Reclaiming the package under a sanctioned scope, transferring maintenance to a known team, and signing future releases.
Deprecating the package, leaving it installable but marking it as no longer maintained, with a pointer to a replacement when one exists.
Hardening the maintainer account. Enable strong 2FA. Move ownership to a service account or a team account that is monitored. Rotate credentials. Verify the email domain is one your organization controls.
Publishing a final signed release that contains a clear notice. This is sometimes called a tombstone release. It does not remove the package, but it gives consumers a strong signal during their next dependency review.
Make this a recurring program, not a one off audit
The hardest part of forgotten package discovery is keeping it from becoming a one time exercise. Without continuous monitoring, the inventory you build today is wrong six months from now. New packages get published, employees leave, and ownership decays.
A useful program runs the discovery on a schedule, alerts on new packages that appear under scopes or maintainers tied to the organization, and feeds the resulting findings into the same workflow your team uses for other supply chain risks. The goal is not to stop people from publishing. It is to make sure that nothing the organization owns falls outside the inventory.
How Safeguard Helps
Safeguard tracks public packages your organization publishes as first class assets, not as an afterthought. Continuous asset discovery enumerates registry scopes, maintainer correlations, and SCM history to build an inventory of every npm package linked to your organization or its current and former employees. Each package carries provenance, signature status, last release date, and ownership lineage, so forgotten packages surface as findings rather than hiding in registry obscurity.
The package inventory is wired into the AI-BOM and the broader software SBOM, so dependencies in your own services that resolve to your own forgotten packages are flagged automatically. The MCP registry extends the same model to tooling published for agents, ensuring that every public artifact your organization has ever shipped, software, AI, or MCP, is tracked, owned, and recoverable. Continuous discovery turns forgotten packages from an attacker's gift into a managed inventory line item.