fix(sigstore): apply url_replacements to Sigstore TUF root fetch#10596
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Central YAML (base), Organization UI (inherited) Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThe PR adds a configurable Sigstore TUF URL override to the ChangesSigstore TUF URL Override and Routing
Sequence Diagram(s)sequenceDiagram
participant Caller
participant sigstore_rs as github/sigstore.rs
participant http as http::apply_url_replacements
participant mise_sigstore as mise_sigstore crate
Caller->>sigstore_rs: verify_attestation / verify_slsa_provenance / verify_cosign_signature
sigstore_rs->>http: apply_url_replacements(DEFAULT_TUF_URL)
http-->>sigstore_rs: replaced URL or unchanged
alt URL changed
sigstore_rs->>mise_sigstore: set_tuf_url(Some(replaced_url))
else no change
sigstore_rs->>mise_sigstore: set_tuf_url(None)
end
sigstore_rs->>mise_sigstore: verify_*()
mise_sigstore->>mise_sigstore: select_tuf_config() → TufConfig::custom or TufConfig::production
mise_sigstore->>mise_sigstore: TrustedRoot::from_tuf(config).await
mise_sigstore-->>sigstore_rs: verification result
sigstore_rs-->>Caller: result
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThis PR fixes a mirror/proxy bypass for the Sigstore TUF root fetch: the external
Confidence Score: 5/5Safe to merge — the change is narrowly scoped, the no-replacement path is byte-for-byte unchanged, and the security-sensitive mirror branch pins the embedded production root. Both changed files have clear, well-commented logic. The global TUF URL override is always set to the same deterministic value (derived from static settings) before any TUF fetch occurs, lock poisoning is handled explicitly, and the embedded production root is required for mirror bootstrapping to keep the TUF chain of trust intact. Previous review comments about lock-poisoning recovery and the missing debug log have both been addressed. Unit tests cover the replacement and no-replacement paths without network access. No files require special attention. Important Files Changed
Reviews (2): Last reviewed commit: "fix(sigstore): apply url_replacements to..." | Re-trigger Greptile |
fa24aa4 to
6146bfc
Compare
The Sigstore public-good TUF root fetch happens inside the sigstore-verify crate via `TrustedRoot::production()`, which hardcodes `https://tuf-repo-cdn.sigstore.dev` and uses its own HTTP client, bypassing mise's `settings.url_replacements`. In isolated/mirrored networks this breaks `mise install` of aqua cosign-verified tools (e.g. `cosign`). Route the TUF root fetch through the same mirror: the bridge computes the url-replaced TUF URL and pushes it into mise-sigstore via a process-global override, set before every TUF-fetching entry point (cosign, SLSA, attestation). The override still bootstraps from the embedded production root (`PRODUCTION_TUF_ROOT`), so a mirror cannot forge the chain of trust. With no replacement configured the behavior is unchanged. Resolves jdx#10437 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6146bfc to
ac33273
Compare
Summary
Fixes discussion #10437:
mise installof an aqua cosign-verified tool (e.g.cosign = "3.1.1") fails behind a mirror because the Sigstore TUF root fetch ignoressettings.url_replacements:Root cause
The Sigstore public-good TUF root is fetched inside the external
sigstore-verifycrate viaTrustedRoot::production()(crates/mise-sigstore/src/lib.rs), which hardcodeshttps://tuf-repo-cdn.sigstore.devand uses its own HTTP client. That bypasses mise'sapply_url_replacements, which only runs inside mise's own HTTP client.Fix
Route the TUF root fetch through the same mirror as the rest of mise's traffic:
src/github/sigstore.rs(the sole bridge): addrouted_tuf_url()(mirrors the existingrouted_api_url()), which appliesurl_replacementsto the canonical TUF URL and returns the replaced URL only when it actually changed. It is pushed into mise-sigstore viaset_tuf_url(...)at the start of every entry point that can trigger a TUF fetch: cosign (verify_cosign_signature,verify_cosign_signature_with_key), SLSA (verify_slsa_provenance,verify_slsa_provenance_artifacts), and attestations (verify_attestation,verify_attestation_with_predicate_type).crates/mise-sigstore/src/lib.rs: add a process-global override (set_tuf_url) read at the single chokepointproduction_trusted_root(). When an override is set it usesTufConfig::custom(mirror_url, PRODUCTION_TUF_ROOT)+TrustedRoot::from_tuf; otherwise it keeps the default (TufConfig::production()), which is identical to today'sTrustedRoot::production().Security
The mirror branch still bootstraps from the embedded production root (
PRODUCTION_TUF_ROOT). TUF verifies all fetched metadata against this pinned root, so a malicious or compromised mirror cannot forge the chain of trust — it can only mirror the identical content. The custom-root pin is required: the sigstore crate only falls back to its embedded root for the known canonical URL, so a mirror URL without the explicit root fails closed. A code comment documents this to prevent regressions.With no
url_replacementsconfigured, behavior is byte-for-byte unchanged.Testing
Pure, network-free unit tests (run by CI):
src/github/sigstore.rs:test_routed_tuf_url_applies_url_replacement,test_routed_tuf_url_none_without_replacement(model on the existingrouted_api_urltests, usingSettingsGuard).crates/mise-sigstore/src/lib.rs:select_tuf_config_default_uses_production_url,select_tuf_config_override_uses_mirror_url.rustfmt --edition 2024 --checkpasses on the changed files.Note
The authoring sandbox can't build mise (insufficient memory), so compilation/clippy/tests are left to CI. Manual end-to-end check for a maintainer: set
MISE_URL_REPLACEMENTSmappinghttps://tuf-repo-cdn.sigstore.devto a working mirror and runmise install cosign@3.1.1— the TUF fetch should hit the mirror and verification should still succeed; with no replacement it should still hit the default CDN.Known limitation
Custom (mirror) TUF URLs have no embedded offline-fallback targets in the sigstore crate, so
offline+ mirror is not supported (online mirror only). Not relevant to the reported use case.🤖 Generated with Claude Code
Summary by CodeRabbit