skip to content

A publish token for your package registry leaked publicly — why isn't revoking it enough?

level: juniorimportance: must knowfreq 72%

answer

  1. revocation is forward-only
  2. published versions do not vanish
  3. check for added maintainers, not just tokens
  4. compare registry log with your own release records
  5. caches, mirrors and lockfiles keep it alive

basics

~20 s

Revoking stops future publishes but changes nothing about what already went out. Anything published while the token was valid sits in consumers' caches and lockfiles, released under your name. You still have to find those versions, distrust them, and tell users.

solid answer

~50 s

Revocation is a forward-only control: it stops the next publish and does nothing about the ones already made. Treat it as step one of three. First, evict the attacker properly — revoke every credential in that scope, not just the leaked one, and check the account for added maintainers, extra tokens or changed recovery details, or the thief simply mints a new credential. Second, enumerate: list every version published during the exposure window with its timestamp, and compare that list against your own release records (build runs, tags, approvals), which the stolen credential could not forge. Third, deal with what shipped: publish a clean higher version, mark the suspect ones so install-time tooling surfaces them, and get an entry into the advisory feed that consumers' tooling polls. What is already pulled lives on in caches, mirrors and lockfiles, and a signature made with the stolen credential still verifies.

go deeper

for a junior

Be ready to say plainly that revocation only stops future publishes, and to name the three follow-on steps: evict fully, enumerate what was published, and warn users.

for a middle

Explain why the published artifact survives revocation — append-only registries, mirrors, proxy and CI caches, lockfile pins — and why a signature made during the window still verifies.

for a senior

Show the eviction sweep you would actually run: every publishing identity in the namespace, account recovery settings, and a comparison of registry publish records against your own build records.

for a principal

Own the structural question: how many identities can publish into your namespaces at all, who reviews that list, and whether offboarding and CI credential lifetimes make this class of leak survivable.

## What a publishing credential actually buys an attacker A publish token, registry API key or release-job credential authorises exactly one thing: writing new versions into a namespace that other people already trust **by name**. That is why it is valuable. The attacker does not need access to your laptop or your source control; they need the right to speak as you to everyone downstream. The moment a version lands under your name, every consumer's resolver treats it as a normal release, every mirror caches it, and every install that floats within a version range picks it up. ## Revocation is forward-only Revoking the credential closes the door for the next publish. It does four things it is often assumed to do, and does none of them: 1. **It does not remove what was published.** Most registries are append-only by design, because deleting a version breaks everyone who already depends on it. Even where deletion exists it is usually time-limited or requires an operator request. 2. **It does not un-cache.** The artifact is now in proxy caches, CI caches, mirrors, vendored directories, container base images and lockfiles. Those copies do not consult the registry again. 3. **It does not invalidate signatures.** A signature made while a thief held the key is cryptographically valid forever. Verification answers *who vouched for this*, and during the exposure window the answer was legitimately "the holder of your credential". Verification cannot tell you the holder was not you. 4. **It does not notify anybody.** Nothing about revoking a token reaches a downstream consumer. ## Evicting the attacker, not just the token A common half-fix is to rotate the one credential that leaked and stop. Someone who had publish rights usually also had account-level rights: they may have added a second token, added themselves or a sock-puppet as a maintainer, changed the recovery email, or altered second-factor settings. Rotating one token while a collaborator they added still has publish rights leaves them fully in place. Enumerate everything that can publish into the namespace — human accounts, machine accounts, CI-held credentials, delegated automation — and cut them all, then re-establish them deliberately. ## Establishing what went out Build two lists and compare them: - **What the registry says was published**: every version in the exposure window, with timestamps and the identity that published it. - **What you meant to publish**: your build system's run records, git tags, changelog entries, release approvals — evidence the stolen credential could not create. A version present in the first list and absent from the second is almost certainly the attacker's. The reverse case matters too: a legitimate release republished by the attacker with different content will appear in both, so timestamps and content digests, not version numbers, are what you compare on. ## The exposure window You rarely know when the credential was first used, only when you noticed. The honest boundary runs from the last release you can independently corroborate through to the moment revocation took effect, and everything inside it is suspect until something outside the credential's reach clears it. ## Giving consumers somewhere to go Distrusting a version without providing a replacement pushes consumers into bad choices: pinning to something older that may also be inside the window, forking, or ignoring you. Publish a clean higher version early, from a rebuild you control, so the fix is an upgrade rather than a research project. Then get the affected range into the machine-readable advisory feed the ecosystem uses, because that is the only notification channel that reaches automation rather than humans. ## Keep the direction of the claims straight Three different artifacts answer three different questions, and this incident only breaks one of them. A **signature** says *who vouches for this artifact*. An **SBOM** says *what is inside it*. A **provenance statement** says *how it was built*. A stolen publish credential lets an attacker produce something that looks correct on the first axis, and possibly on the second and third if the attacker generated those documents too. "It verifies" is therefore not evidence of anything during this incident — it is exactly what you would expect the attacker's release to do. What consumers then have to do on their own machines — deciding what an installed malicious version could have reached — is the other half of the incident and belongs to the consumer side of the response.

  • The leaked credential belonged to a release engineer who left the company two months ago. What changes?
    The window widens to everything since their last legitimate release, because nobody was watching that identity. It also turns into a process finding: offboarding covered the corporate directory but not the registry account, so publishing rights outlived employment. Fix the incident, then fix the join/leave checklist so registry identities are enumerated and cut with everything else.
  • Why is the registry's own publish log not sufficient evidence on its own?
    If the account or the publishing service is what was compromised, its records sit inside the blast radius — an attacker with account control may be able to influence what they show. Corroborate with evidence from outside that trust boundary: your build system's run history, signed tags, approval records, or a rebuild whose output matches the published artifact.
  • Should you delete the malicious version outright if the registry allows it?
    Usually not immediately. The artifact is evidence — you and your consumers need to hash it, inspect it and prove what shipped. Prefer marking it so install-time tooling warns, keep a copy for forensics, and request removal afterwards if the ecosystem's norms support it.

It is a stolen letterhead. Getting the print shop to stop making more sheets does nothing about the letters already in the post.

saying these in an interview costs you the question

  • Rotates the token and treats the incident as closed
  • Assumes unpublishing removes the version everywhere
  • Trusts a version because its signature verifies
  • Revokes the leaked token but leaves added collaborators
  • Says nothing to users until a full root cause exists

context