Closed bug report

Renamed packages fail signed installs: the seal binds the publish-time slug, resolve serves the current one

Colby Knox · 1mo ago ·closed by Colby Knox

Found while building the #153 pin arm; pre-existing, unrelated to pins except that the pin recovery path is the first flow that systematically installs renamed packages.

Mechanism

The Ed25519 seal is minted at publish over the payload:

adompkg-sig-v1
<owner>/<slug>@<version>
<integrity>

with the slug AS OF PUBLISH. repo rename moves the repo and release store to the new slug, and /api/packages/resolve then serves the CURRENT slug in resolved rows. The CLI reconstructs the payload from that row (crypto.rs sig_payload), so verification fails for every release published before the rename:

signature verification FAILED for kcknox/[email protected]: refusing to install

Reproduction (staging, throwaways now deleted)

  1. Publish kcknox/[email protected] (sealed fine, installed fine).
  2. adom-wiki repo rename kcknox/ztest-pin36h ztest-pin36h-moved.
  3. Fresh adom-wiki pkg install kcknox/ztest-pin36h-moved -> integrity passes, signature FAILS, install refused.

Blast radius: any page with signed releases that gets renamed loses fresh installability under its new name (fail-closed, so hard-refused; --allow-unsigned is the only escape). Existing installs keep working; it bites new installs and CI replays.

Suggested fixes (either closes it)

  1. Re-seal on rename: the seal is the registry's (server-held key, per-publisher signing is #85), so rename can re-sign each release row's payload with the new slug in the same transaction that moves the release store. Cleanest; nothing changes client-side.
  2. Serve the signed name: resolve rows (and the assets/manifest routes) carry signed_as: "/" and the CLI verifies against that instead. Needs a CLI release and keeps a growing alias surface, so option 1 seems strictly better.

CLI side: nothing shipped that depends on this; the DEPS_PIN_DIVERGED/MOVED recovery (pkg install pg_...) resolves the id to the current name client-side and then hits this wall for renamed targets, so option 1 also makes that recovery fully runnable.

1 Reply

Colby Knox · 1mo ago

Fixed on prod (tag 59edd46), option 1, plus the fleet was quietly carrying far more of this than the repro suggested.

The fix. Rename AND transfer (the seal binds <owner>/<slug>, so transfer breaks it identically) now run the existing anti-laundering re-seal, scoped to the moved page, right after the commit point: each release is re-signed under the new name only when its tarball still hashes to the stored integrity, so altered bytes can never be blessed by a move. The response reports releases_resealed, and a partial failure surfaces a RESEAL_INCOMPLETE warning naming the stuck releases and the admin sweep as recovery. Nothing changes client-side, as hoped.

Replayed your exact repro on staging: publish, repo rename, fresh pkg install under the new name. The rename response reported releases_resealed: 1 and the install that used to die with signature verification FAILED ... refusing to install completed clean. (Throwaways deleted.)

The backfill mattered more than expected. Running the existing fleet sweep (POST /api/admin/reseal-invalid-signatures) on prod after the deploy: 6432 releases checked, 735 re-sealed, zero integrity mismatches. Every one of those 735 was fail-closed un-installable under its current name until an hour ago: the adom-bridge 1.8.13x line, kicad-bridge, hydrogen-dev, the whole ntx-embedded octolux set, and more, all residue of past renames and transfers. Your pin-recovery flow was just the first thing to systematically walk into it. A re-run confirms convergence (0 re-sealed, 5386 valid).

Residue, for the record, both pre-existing and unrelated to this bug: 17 rows whose tarballs are gone entirely (1.0.0-era, pre-backup), and 1029 rows from the pre-integrity era with no hash to verify at all.

With this plus 1.7.11's pin arm, the DIVERGED/MOVED recovery (pkg install pg_...) is now fully runnable for renamed targets. Closing.

Log in to reply.