Skip to content

fix: audit keyless — JWT alg, OIDC env, Rekor SET, zeroization#100

Merged
avrabe merged 1 commit into
mainfrom
fix/audit-keyless-hardening-2026-04-30
Apr 30, 2026
Merged

fix: audit keyless — JWT alg, OIDC env, Rekor SET, zeroization#100
avrabe merged 1 commit into
mainfrom
fix/audit-keyless-hardening-2026-04-30

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented Apr 29, 2026

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

  • C-6 / CRITICAL — JWT alg field 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. Rejects none, HS256/384/512,
    empty/missing alg. Closes the textbook algorithm-confusion footgun where an
    attacker could forge alg: "HS256", sign with a known string (e.g. the issuer URL),
    and have parse_issuer() / parse_identity() trust the claims.
  • H-4 — WSC_EXPECTED_OIDC_ISSUER env var 3-state cleanup (signer.rs).
    Empty env var no longer silently disables validation; explicit WSC_DISABLE_OIDC_ISSUER_CHECK=1 is now required to disable. Documented.
  • H-5 — Rekor SET cache poisoning prevention (rekor.rs).
    Rekor entries with empty signed_entry_timestamp or empty inclusion_proof are now rejected before any cache write. Subsequent verifications can no longer hit a cache populated by a partial / truncated Rekor response.
  • M-5 — OidcToken: Clone removed (oidc.rs).
    Honors the single-owner zeroize discipline used elsewhere for SecretKey / KeyPair. Call-site refactor was contained — no .clone() calls outside test code.
  • M-6 — JWT payload buffer zeroization (oidc.rs).
    payload_str and intermediate parsing buffers wrapped in Zeroizing<String> so they are zeroed on function return (including error paths).

What this PR does NOT do

Test plan

  • cargo build --workspace --release clean
  • cargo test --workspace --lib769 tests pass (751 + 18 + 0)
  • New unit tests cover: JWT alg-confusion rejection (C-6), OIDC env fallback (H-4), empty-SET Rekor rejection (H-5)
  • CI: integration tests under keyless_integration.rs continue to pass
  • CI: airgapped E2E continues to pass

Audit context: audit/2026-04-30/findings.md.

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>
@avrabe avrabe merged commit 786eee8 into main Apr 30, 2026
20 checks passed
@avrabe avrabe deleted the fix/audit-keyless-hardening-2026-04-30 branch April 30, 2026 05:14
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
Copy link
Copy Markdown

codecov Bot commented Apr 30, 2026

Codecov Report

❌ Patch coverage is 93.84615% with 24 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/lib/src/signature/keyless/signer.rs 78.87% 15 Missing ⚠️
src/lib/src/signature/keyless/rekor.rs 97.01% 6 Missing ⚠️
src/lib/src/signature/keyless/oidc.rs 97.45% 3 Missing ⚠️

📢 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>
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