Skip to content

fix(sigstore): retry GitHub attestations with TUF root - #10695

Merged
jdx merged 1 commit into
mainfrom
codex/github-tuf-root-retry
Jul 1, 2026
Merged

jdx merged 1 commit into
mainfrom
codex/github-tuf-root-retry

Conversation

@jdx

@jdx jdx commented Jul 1, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • keep the embedded GitHub trusted root as the fast path
  • retry GitHub-internal bundle verification with GitHub's TUF trusted root after an embedded-root verification failure
  • cache embedded and TUF roots per verification call, and avoid TUF retry for signer workflow mismatches

Testing

  • cargo test -p mise-sigstore
  • git diff --check

This PR was generated by an AI coding assistant.


Note

Medium Risk
Changes attestation trust-root selection and retry logic on a security-sensitive path; behavior is narrowed (workflow mismatches no longer masked by TUF retry) but incorrect retry rules could still accept or reject valid bundles.

Overview
GitHub-internal Sigstore bundles no longer pick a single trust root up front. Verification goes through verify_bundle_with_trust_roots, which still uses the production Sigstore root for non-GitHub certs, but for GitHub, Inc. leaf certs tries the embedded GitHub root first and only fetches GitHub’s TUF root when that attempt fails.

Signer workflow checks now return a dedicated AttestationError::WorkflowMismatch instead of a generic verification error. That mismatch is treated as non-retryable—a failed embedded check for workflow reasons does not trigger a TUF retry (and a TUF retry that also mismatches returns the workflow error, not a combined verification message).

TrustRoots caches github_embedded and github_tuf separately (lazy TUF load). Cosign, SLSA bundle, and GitHub attestation paths are wired through the same helper. Unit tests cover embedded-only loading, TUF retry after embedded crypto failure, and no retry on workflow mismatch.

Reviewed by Cursor Bugbot for commit cea9397. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • Bug Fixes
    • Improved signature, provenance, and attestation bundle verification by unifying trust-root handling across verification flows.
    • Enhanced GitHub bundle verification with a safer fallback/retry strategy when the first attempt fails.
    • Reduced unnecessary retries by treating signer workflow mismatches as non-retryable, including clearer error reporting.
  • Tests
    • Added coverage to ensure embedded GitHub root verification does not load the GitHub TUF root.
    • Added coverage to confirm workflow mismatches do not trigger GitHub TUF retry.

@coderabbitai

coderabbitai Bot commented Jul 1, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: b6c32021-0c5c-464a-82b0-9874dd30f8f6

📥 Commits

Reviewing files that changed from the base of the PR and between 0b74eb9 and cea9397.

📒 Files selected for processing (1)
  • crates/mise-sigstore/src/lib.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/mise-sigstore/src/lib.rs

📝 Walkthrough

Walkthrough

This PR centralizes Sigstore bundle verification around shared trust-root caching, adds GitHub embedded/TUF retry handling, changes workflow-mismatch errors to a distinct non-retryable variant, updates verification call sites, and adds tests for cache and retry behavior.

Changes

Sigstore Trust-Root Verification Refactor

Layer / File(s) Summary
Trust-root cache and dispatch logic
crates/mise-sigstore/src/lib.rs
TrustRoots now caches separate embedded and TUF GitHub roots, verify_bundle_with_trust_roots routes GitHub bundles through embedded-first verification with optional TUF retry, and verify_signer_workflow_identity emits WorkflowMismatch for missing or mismatched workflow identity.
Call sites use shared trust-root verification
crates/mise-sigstore/src/lib.rs
verify_cosign_signature, verify_slsa_provenance_artifacts, verify_attestation_bundles, and verify_bundle_for_any_artifact now verify bundles through the shared mutable TrustRoots path instead of preselecting a single trusted root.
Trust-root caching and retry tests
crates/mise-sigstore/src/lib.rs
New tests cover embedded-root caching, GitHub TUF retry behavior, and suppression of TUF retry when workflow-mismatch errors are returned.

Estimated code review effort: 4 (Complex) | ~45 minutes

Poem

A bunny hopped through roots and trust,
Embedded first, then TUF if must.
Workflow mismatches stop the chase,
So bundles land in one clean place. 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: retrying GitHub attestation verification with the TUF root.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jul 1, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes GitHub attestation verification by adding a TUF-root retry path when the embedded GitHub root fails, while correctly blocking retries for signer-workflow mismatches. A new WorkflowMismatch error variant replaces the previous string-prefix coupling, so the guard is now type-safe.

  • verify_bundle_with_trust_roots replaces direct trust_roots.for_bundle() calls across cosign, SLSA, and attestation paths, routing GitHub-internal bundles through the embedded-root-first/TUF-retry logic.
  • TrustRoots is extended with a separate github_tuf field so the TUF root is only fetched lazily on a retry, never on a successful embedded-root verification.
  • Three new unit tests validate that: (1) embedded-root loading does not eagerly fetch TUF, (2) TUF retry fires and can succeed after an embedded-root failure, and (3) WorkflowMismatch errors are not retried.

Confidence Score: 5/5

Safe to merge — the retry logic is well-guarded and the previously flagged string-prefix coupling has been replaced with a proper error variant.

The change unifies three previously divergent trust-root selection paths, correctly gates TUF retries behind a typed WorkflowMismatch check rather than a fragile string prefix, and caches both roots lazily. The new unit tests cover every branch of the retry logic. No incorrect retry logic or trust-boundary widening was found.

No files require special attention.

Important Files Changed

Filename Overview
crates/mise-sigstore/src/lib.rs Adds WorkflowMismatch error variant, unifies GitHub bundle verification through verify_bundle_with_trust_roots, and implements TUF fallback retry with correct non-retryable guard for workflow mismatches; prior coupling concern resolved; unit tests cover all new logic branches.

Reviews (2): Last reviewed commit: "fix(sigstore): retry GitHub attestations..." | Re-trigger Greptile

Comment thread crates/mise-sigstore/src/lib.rs Resolved
@jdx
jdx force-pushed the codex/github-tuf-root-retry branch from 5e8985e to 0b74eb9 Compare July 1, 2026 21:40

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0b74eb9. Configure here.

Comment thread crates/mise-sigstore/src/lib.rs Resolved
@jdx
jdx force-pushed the codex/github-tuf-root-retry branch from 0b74eb9 to cea9397 Compare July 1, 2026 21:43
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.6.14 x -- echo 19.5 ± 2.5 17.4 35.6 1.00
mise x -- echo 20.0 ± 1.6 18.0 46.4 1.03 ± 0.15

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.6.14 env 18.9 ± 0.9 17.2 22.8 1.00
mise env 19.8 ± 0.8 18.0 23.7 1.04 ± 0.06

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.6.14 hook-env 19.7 ± 0.9 17.9 23.3 1.00
mise hook-env 20.4 ± 0.9 18.7 23.5 1.04 ± 0.06

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.6.14 ls 16.3 ± 0.8 14.8 21.3 1.00
mise ls 17.0 ± 0.8 15.4 20.5 1.05 ± 0.07

xtasks/test/perf

Command mise-2026.6.14 mise Variance
install (cached) 134ms 135ms +0%
ls (cached) 60ms 61ms -1%
bin-paths (cached) 64ms 66ms -3%
task-ls (cached) 124ms 126ms -1%

@jdx
jdx enabled auto-merge (squash) July 1, 2026 22:02
@jdx
jdx merged commit 50d6f34 into main Jul 1, 2026
33 of 34 checks passed
@jdx
jdx deleted the codex/github-tuf-root-retry branch July 1, 2026 22:05
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.

1 participant