Repoint the trust anchor at the catalogue pin (keep VerifyTrustAnchor)#25
Conversation
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
…anchor) (#320) daemon: drop PILOT_TRUSTED_PUBLISHERS wiring; bump app-store (trust anchor removed) The per-publisher trust anchor is removed in app-store (the release-signed catalogue is the source of truth). So the env-var wiring added in #318 is no longer needed — a fresh node installs and runs catalogue apps with zero config. - remove the PILOT_TRUSTED_PUBLISHERS env block + the now-unused manifest import - bump github.com/pilot-protocol/app-store to the trust-anchor-removal commit - keep PILOT_APPSTORE_ROOT honoring Depends on pilot-protocol/app-store#25; re-pin go.mod to the merged app-store commit before this lands. Verified: a fresh node with NO env installs io.pilot.smolmachines from the real catalogue and boots a microVM. Co-authored-by: Alex Godoroja <alex@vulturelabs.io> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
This conflicts directly with the trust-anchor enforcement added in #23 (merged 2026-06-22). #23 made catalogue (non-sideloaded) installs fail-closed: a manifest must verify against a trusted-publisher anchor, not just carry a valid self-signature. This PR removes "Catalogue is the source of truth" is reasonable, but the trust decision still has to be anchored to something the installer pins — otherwise a compromised or typo-squatted catalogue entry installs arbitrary code. If we move to catalogue-pin-only, the enforced anchor should become the catalogue signature/pin (ideally keep Recommendation: hold until we agree the trust model. As written this is a security regression against #23. |
fe1efad to
e23f668
Compare
…tatic list) Addresses review on #25: keep the anchor mechanism, but anchor it to the release-signed catalogue (the root of trust) instead of a static, env-populated publisher allow-list that nothing populated (so #23 enforcement skipped every catalogue app). - Manifest.VerifyTrustAnchor(cataloguePublisher string): confirms Store.Publisher equals the publisher key the catalogue pins for the app. Empty/unpinned => fail-closed. (Symbol kept, repointed — no silent self-signed acceptance.) - Remove the unused package-global manifest.TrustedPublishers. - Config.CataloguePublisher(appID) (pub string, pinned bool): the daemon supplies this from the catalogue it has signature-verified with CatalogPubkey. - Supervisor catalogue path: VerifySignature + VerifyTrustAnchor(cataloguePin). nil provider or unpinned app => fail-closed (not spawned). Sideload unchanged. Tests: full accept/mismatch/unpinned/nil-provider matrix (-race green), plus the repointed manifest unit tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Repoint the trust anchor at the catalogue pin (keep the mechanism)
Reworked per review. The previous version dropped
VerifyTrustAnchorentirely,which was a regression against #23 (any self-signed manifest in the install root
would pass). This version keeps the anchor and repoints it at the catalogue,
which is the actual root of trust.
What changed
Manifest.VerifyTrustAnchor(cataloguePublisher string)— kept as themechanism, but now confirms
Store.Publisherequals the publisher key therelease-signed catalogue pins for the app. Empty/unpinned ⇒ fail-closed.
TrustedPublishers(nothing populated it; anempty list made Enforce trust anchor for non-sideloaded installs #23 enforcement skip every catalogue app). The catalogue pin
replaces it.
Config.CataloguePublisher(appID) (pub string, pinned bool)— the daemonsupplies this from the catalogue it has signature-verified with
CatalogPubkey.VerifySignature+VerifyTrustAnchor(pin). Anil provider or an unpinned app ⇒ fail-closed (not spawned). Sideload unchanged
(still clamped to the safe grant subset).
Why this satisfies the trust requirement
Trust is anchored to something the installer pins: the catalogue is signed by the
embedded release key and pins each app; the supervisor re-confirms on every launch
that the installed manifest is published by the catalogue-declared key. A
typo-squatted or compromised entry can't install arbitrary code without being in
the release-signed catalogue. No static list, no env var.
Tests (
-race, full app-store suite green)CataloguePinnedAppAccepted— pinned + matching publisher ⇒ acceptedUntrustedPublisherWithoutMarkerRejected— pinned, publisher ≠ pin ⇒ rejectedAppNotPinnedByCatalogueRejected— valid self-sig but not in catalogue ⇒ rejectedNilCataloguePublisherFailsClosed— no provider wired ⇒ rejectedManifest.VerifyTrustAnchorunit testsMust land with its companions (or the daemon fail-closes)
CataloguePublisher(id → publisher) to
appstore.Config.publishered25519 key (the pin).🤖 Generated with Claude Code