Skip to content

Repoint the trust anchor at the catalogue pin (keep VerifyTrustAnchor)#25

Merged
TeoSlayer merged 1 commit into
mainfrom
remove-redundant-trust-anchor
Jun 23, 2026
Merged

Repoint the trust anchor at the catalogue pin (keep VerifyTrustAnchor)#25
TeoSlayer merged 1 commit into
mainfrom
remove-redundant-trust-anchor

Conversation

@Alexgodoroja

@Alexgodoroja Alexgodoroja commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

Repoint the trust anchor at the catalogue pin (keep the mechanism)

Reworked per review. The previous version dropped VerifyTrustAnchor entirely,
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 the
    mechanism, but now confirms Store.Publisher equals the publisher key the
    release-signed catalogue pins for the app. Empty/unpinned ⇒ fail-closed.
  • Removed the unused package-global TrustedPublishers (nothing populated it; an
    empty 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 daemon
    supplies this from the catalogue it has signature-verified with CatalogPubkey.
  • Supervisor catalogue path: VerifySignature + VerifyTrustAnchor(pin). A
    nil 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 ⇒ accepted
  • UntrustedPublisherWithoutMarkerRejected — pinned, publisher ≠ pin ⇒ rejected
  • AppNotPinnedByCatalogueRejected — valid self-sig but not in catalogue ⇒ rejected
  • NilCataloguePublisherFailsClosed — no provider wired ⇒ rejected
  • repointed Manifest.VerifyTrustAnchor unit tests

Must land with its companions (or the daemon fail-closes)

  1. daemon: load + signature-verify the catalogue and supply CataloguePublisher
    (id → publisher) to appstore.Config.
  2. catalogue: each entry declares its publisher ed25519 key (the pin).

🤖 Generated with Claude Code

@codecov

codecov Bot commented Jun 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.30435% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
pkg/manifest/manifest.go 89.47% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

TeoSlayer pushed a commit to pilot-protocol/pilotprotocol that referenced this pull request Jun 23, 2026
…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>
@TeoSlayer

Copy link
Copy Markdown
Contributor

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 manifest.TrustedPublishers and Manifest.VerifyTrustAnchor, which (a) breaks external callers of those exported symbols, and (b) re-opens the hole — scanInstalled would again accept an app self-signed by any key as long as it appears in the catalogue.

"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 VerifyTrustAnchor as the mechanism, repointed at the catalogue key) rather than dropping anchor verification entirely.

Recommendation: hold until we agree the trust model. As written this is a security regression against #23.

@Alexgodoroja Alexgodoroja force-pushed the remove-redundant-trust-anchor branch from fe1efad to e23f668 Compare June 23, 2026 19:21
…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>
@Alexgodoroja Alexgodoroja changed the title Remove redundant per-publisher trust anchor (catalogue is the source of truth) Repoint the trust anchor at the catalogue pin (keep VerifyTrustAnchor) Jun 23, 2026
@TeoSlayer TeoSlayer merged commit cecb842 into main Jun 23, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants