Enforce trust anchor for non-sideloaded installs#23
Merged
Conversation
scanInstalled ran only VerifySignature on the catalogue (non-sideloaded) path, so a manifest self-signed by any key was accepted and spawned. Signature validity is integrity, not trust: a non-sideloaded install must also pass VerifyTrustAnchor against the trusted-publishers list. Sideloading remains the explicit local opt-out of this chain. Add a regression test: a validly self-signed manifest from an untrusted publisher, with no .sideloaded marker, is refused.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Alexgodoroja
pushed a commit
that referenced
this pull request
Jun 23, 2026
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
scanInstalledran onlyVerifySignatureon the catalogue (non-sideloaded) path. Signature validity proves integrity, not trust: a manifest self-signed by any key passed the check and was spawned. The trust regime was effectively backwards — a non-sideloaded (catalogue) app should get the FULL trust-anchor check, while sideloading is the explicit local opt-out.Fix
The non-sideloaded branch now also calls
VerifyTrustAnchor()against the trusted-publishers list. Sideloaded apps (.sideloadedmarker) keep skipping the publisher chain and instead satisfy the sideload allow-list, unchanged.Test
TestScanInstalled_UntrustedPublisherWithoutMarkerRejected: a manifest with a valid self-signature from a fresh untrusted key, no.sideloadedmarker, is refused. Confirmed it fails without the fix and passes with it.Test helpers now sign with a fixed publisher key pinned into
TrustedPublishersviaTestMain(set once, never mutated — race-free under-race), so existing catalogue-path lifecycle tests still represent legitimate trusted apps.Validation
GOWORK=off go build/vet ./...clean;go test -race ./...green.