skip to content

A version published under your stolen registry credential is already installed downstream — how do you reach those installers?

level: middleimportance: should knowfreq 45%

answer

  1. counts, not identities
  2. which channel reaches machines?
  3. advisory feed the tooling already polls
  4. yank metadata warns at install time
  5. ship a clean higher version to upgrade into

basics

~20 s

There is no consumer list to reach — a registry gives download counts, not identities. The only channel that reaches machines is the ecosystem's advisory feed, which flows into the scanners and update bots consumers already run. Everything else reaches humans who happen to be watching.

solid answer

~50 s

Accept first that you cannot enumerate them: a registry hands you download counts, which size the incident but cannot target a notice. So rank channels by whether they reach automation or people. The one that reaches automation is the ecosystem advisory feed — an entry naming the package and the affected version range propagates into the vulnerability scanners and dependency-update bots consumers already run, whether or not anyone reads your announcement. Back it with install-time metadata: mark or yank the bad versions so a resolver warns at install, and ship a clean higher version, because most consumers move when a bot opens the upgrade pull request. Human channels — a pinned notice on the project page, an announce list, social posts — reach the minority who are watching; use them for the narrative, the timeline and the handful of large consumers you can contact by name.

go deeper

for a junior

Know that you cannot get a list of who installed your package, and that a notice has to travel through channels consumers already consume rather than one you invent.

for a middle

Explain how an advisory feed entry reaches automation, how yank or deprecation metadata behaves differently from deletion, and why a clean higher version is part of the notification.

for a senior

Sequence the response under time pressure: preliminary advisory early, replacement version, repackagers and large consumers contacted directly, and download counts watched for convergence.

for a principal

Own the reach question before an incident: whether your project is in the ecosystem advisory database at all, who is authorised to file, and which downstream repackagers you can call within the hour.

## The uncomfortable starting point Publishing is a one-way broadcast. You know how many times a version was downloaded and roughly from where; you do not know who runs it, in what product, or whether they even know the dependency exists — most consumers pulled it transitively and have never heard your project's name. Revocation and distrust are only half of the response; the other half is notification, and notification against an unenumerable audience is a reach problem, not a writing problem. ## Rank channels by what they reach **Machine channels (high reach, low effort for the consumer).** Every mainstream ecosystem has an advisory database, and the entries are consumed automatically: scanners match installed versions against affected ranges, update bots open pull requests, and platform dashboards light up. An entry keyed to the package name and the affected version range is the single highest-leverage notification you can produce, because it arrives inside the consumer's existing workflow, at the moment they build, without them having subscribed to anything. Ecosystem advisory feeds are also aggregated into cross-ecosystem formats, so one accurate entry travels further than a dozen posts. Authoring the advisory document itself — identifier assignment, wording, severity — is a separate discipline; what matters here is that the entry exists and that the affected range is right. **Install-time metadata (medium reach).** Registries generally provide a way to mark a version as unwanted without deleting it — deprecation, yanking, or an equivalent flag. Semantics differ, but the shape is consistent: the version stays resolvable for anyone who already pinned it, so you do not break existing builds, while new resolutions skip it and the client prints a warning. That warning lands in front of an engineer who is actively working, which beats an email nobody opened. Deleting outright is the aggressive alternative and it costs you: it breaks reproducibility for everyone who pinned it, and it destroys the artifact your consumers need in order to hash and inspect what they actually ran. **Human channels (low reach, high narrative value).** The project page, the release notes, an announce list, a status page, social posts. These reach people already paying attention, which after a compromise is a small and self-selected group. They are still worth doing, for three reasons: they carry the timeline and the honest account that machine channels cannot; journalists, aggregators and downstream packagers read them and re-broadcast; and consumers who discover the problem late need a canonical page to land on months from now. **Direct contact (tiny reach, disproportionate value).** You usually know a handful of large consumers — enterprise users, distro packagers, platform vendors who repackage you. Each of those is a multiplier: a distribution maintainer who acts reaches every one of their users. ## Give them a destination A notice that says "stop using version X" without saying what to use instead produces pinning, forking and inaction. Publish a clean higher version first, from content you rebuilt and control, so the machine channels have an upgrade target and the bot's pull request is mergeable. If the fix requires a major-version jump or a namespace change, say so explicitly, because automation will not cross that boundary by itself and those consumers need a human decision. ## Use download counts for sizing, not targeting Counts tell you order of magnitude: whether this is dozens of installs or millions, whether it went out to mirrors, whether pulls continued after you acted. Continued pulls after the advisory is the useful signal — it usually means caches, mirrors, vendored copies or air-gapped consumers, and it tells you the notification has not converged. What counts never tell you is identity, so any plan that begins "we will email the affected users" is built on something you do not have. ## Say it early and revise Waiting for a complete root cause before saying anything maximises the number of people who install the bad version in the meantime. Publish what you know, mark it as preliminary, give the affected range as your best current estimate, and update. If the range later widens, a second notification is cheap; a month of silent exposure is not.

  • Why publish a fixed higher version before you have a full root cause?
    Because a warning without a destination is ignored. Automation can only act if there is a version to move to, and consumers who have nowhere to go will pin, fork or do nothing. Ship a clean rebuild early, mark the advisory range as preliminary, and widen it later if the investigation says so.
  • What does yanking a version do that deleting it does not?
    Yanking or deprecating keeps the artifact resolvable for builds that already pin it while excluding it from new resolutions and warning at install. Deleting breaks every pinned build, destroys reproducibility for anyone auditing history, and removes the artifact your consumers need in order to hash and inspect what they actually ran.
  • Pulls of the bad version continue for weeks after your advisory. What does that tell you?
    That the notification has not converged — usually mirrors, proxy caches, vendored copies, container base images or offline consumers that never re-query the registry. Treat it as a signal to push through repackagers and distributions rather than as evidence people are ignoring you.

saying these in an interview costs you the question

  • Assumes the registry can tell you who installed it
  • Relies on a blog post and an announce list alone
  • Deletes the version and notifies nobody
  • Waits for a complete root cause before saying anything
  • Treats download counts as an affected-user list

context