fix: audit keyless — JWT alg, OIDC env, Rekor SET, zeroization#100
Merged
Conversation
Closes 5 findings from the 2026-04-30 14-perspective audit:
C-6 — validate JWT alg field against allowlist (RS/ES 256/384/512)
before any payload claim is parsed; rejects none/HS*
H-4 — clean up 3-state OIDC env var; explicit disable required
H-5 — reject Rekor entries with empty SET before caching
M-5 — drop Clone on OidcToken; honor single-owner zeroize discipline
M-6 — zeroize JWT payload_str via Zeroizing<String>
751 lib tests + 18 attestation tests pass. New unit tests cover the JWT
alg-confusion rejection, the OIDC env var fall-through, and the
empty-SET Rekor rejection.
Fixes: C-6, H-4, H-5, M-5, M-6
Verifies: CR-1, CR-6, CR-7
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 tasks
4 tasks
avrabe
added a commit
that referenced
this pull request
Apr 30, 2026
Bumps Cargo.toml, MODULE.bazel, src/cli/BUILD.bazel, and Cargo.lock to 0.8.1. Adds CHANGELOG.md (new file, repo did not have one) with the full release notes. This release closes 26 of 33 findings from the 2026-04-30 14-perspective audit. Specific fix-PRs are #96 (STPA-Sec / docs), #97 (hygiene), #98 (parser hardness), #99 (formal-verif honesty + CI), #100 (keyless / OIDC hardening). Two findings (cert-pinning enforcement, no_std verifier) are deferred to issue #95 and issue #79 respectively. Note on H-8 (version drift): MODULE.bazel and src/cli/BUILD.bazel were at 0.2.7 on main; this commit takes them straight to 0.8.1. PR #97 also bumps these to 0.8.0 as part of its H-8 fix; whichever PR merges last has a trivial conflict that resolves to 0.8.1. Trace: skip Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
avrabe
added a commit
that referenced
this pull request
May 1, 2026
Bumps Cargo.toml, MODULE.bazel, src/cli/BUILD.bazel, and Cargo.lock to 0.8.1. Adds CHANGELOG.md (new file, repo did not have one) with the full release notes. This release closes 26 of 33 findings from the 2026-04-30 14-perspective audit. Specific fix-PRs are #96 (STPA-Sec / docs), #97 (hygiene), #98 (parser hardness), #99 (formal-verif honesty + CI), #100 (keyless / OIDC hardening). Two findings (cert-pinning enforcement, no_std verifier) are deferred to issue #95 and issue #79 respectively. Note on H-8 (version drift): MODULE.bazel and src/cli/BUILD.bazel were at 0.2.7 on main; this commit takes them straight to 0.8.1. PR #97 also bumps these to 0.8.0 as part of its H-8 fix; whichever PR merges last has a trivial conflict that resolves to 0.8.1. Trace: skip Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
avrabe
added a commit
that referenced
this pull request
May 1, 2026
Bumps Cargo.toml, MODULE.bazel, src/cli/BUILD.bazel, and Cargo.lock to 0.8.1. Adds CHANGELOG.md (new file, repo did not have one) with the full release notes. This release closes 26 of 33 findings from the 2026-04-30 14-perspective audit. Specific fix-PRs are #96 (STPA-Sec / docs), #97 (hygiene), #98 (parser hardness), #99 (formal-verif honesty + CI), #100 (keyless / OIDC hardening). Two findings (cert-pinning enforcement, no_std verifier) are deferred to issue #95 and issue #79 respectively. Note on H-8 (version drift): MODULE.bazel and src/cli/BUILD.bazel were at 0.2.7 on main; this commit takes them straight to 0.8.1. PR #97 also bumps these to 0.8.0 as part of its H-8 fix; whichever PR merges last has a trivial conflict that resolves to 0.8.1. Trace: skip Co-authored-by: Claude Opus 4.7 (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.
Closes 5 findings from the 2026-04-30 14-perspective audit. The audit's red-team and cryptographer reviewers converged on multiple gaps in the keyless / OIDC path; this PR closes the ones tractable without an HTTP-client migration.
Findings closed
algfield not validated (src/lib/src/signature/keyless/oidc.rs).Adds
validate_jwt_alg()that runs before any payload claim is parsed. Allowlist:RS256 / RS384 / RS512 / ES256 / ES384 / ES512. Rejectsnone,HS256/384/512,empty/missing
alg. Closes the textbook algorithm-confusion footgun where anattacker could forge
alg: "HS256", sign with a known string (e.g. the issuer URL),and have
parse_issuer()/parse_identity()trust the claims.WSC_EXPECTED_OIDC_ISSUERenv var 3-state cleanup (signer.rs).Empty env var no longer silently disables validation; explicit
WSC_DISABLE_OIDC_ISSUER_CHECK=1is now required to disable. Documented.rekor.rs).Rekor entries with empty
signed_entry_timestampor emptyinclusion_proofare now rejected before any cache write. Subsequent verifications can no longer hit a cache populated by a partial / truncated Rekor response.OidcToken: Cloneremoved (oidc.rs).Honors the single-owner zeroize discipline used elsewhere for
SecretKey/KeyPair. Call-site refactor was contained — no.clone()calls outside test code.oidc.rs).payload_strand intermediate parsing buffers wrapped inZeroizing<String>so they are zeroed on function return (including error paths).What this PR does NOT do
ureqto a client that exposesrustls::ServerCertVerifier— tracked separately in issue [audit] Enforce SPKI cert pinning — migrate keyless HTTP from ureq to rustls #95 (audit finding C-4).OidcToken: !Clone.Test plan
cargo build --workspace --releasecleancargo test --workspace --lib— 769 tests pass (751 + 18 + 0)keyless_integration.rscontinue to passAudit context:
audit/2026-04-30/findings.md.