Skip to content

fix: enforce fail-closed Rekor verification and close STPA-Sec coverage gaps#52

Merged
avrabe merged 1 commit intomainfrom
feat/stpa-sec-findings-and-coverage
Mar 15, 2026
Merged

fix: enforce fail-closed Rekor verification and close STPA-Sec coverage gaps#52
avrabe merged 1 commit intomainfrom
feat/stpa-sec-findings-and-coverage

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented Mar 15, 2026

Summary

  • Security fix (AS-6): KeylessVerifier::verify() had a fail-open path where Rekor verification was silently skipped when the entry UUID was empty or "skipped". Now returns an error, enforcing DD-2 (fail-closed). This was discovered by the STPA-Sec analysis in PR feat: add Rivet STPA-Sec traceability and convert security docs #50.
  • Coverage: 91% → 98.4% — closed 22 of 27 traceability warnings

Security fix detail

Before (fail-open, line 441-448 of signer.rs):

if !keyless_sig.rekor_entry.uuid.is_empty() && keyless_sig.rekor_entry.uuid != "skipped" {
    verifier.verify_set(&keyless_sig.rekor_entry)?;
} else {
    log::warn!("Rekor verification skipped (no Rekor entry)");  // ← silently continues
}

After (fail-closed):

if keyless_sig.rekor_entry.uuid.is_empty() || keyless_sig.rekor_entry.uuid == "skipped" {
    return Err(WSError::RekorError(
        "Rekor transparency log entry is required for keyless verification".into(),
    ));
}
verifier.verify_set(&keyless_sig.rekor_entry)?;

STPA-Sec findings summary

Finding Severity Status
AS-6: Rekor fail-open High Fixed in this PR
UCA-12: OIDC issuer not validated on signing side Medium Tracked, needs expected_issuer field
AS-9: Trust bundle caching Under investigation Agent still analyzing

Coverage improvements

  • Added protects links from all 11 system constraints → security properties
  • Added AS-11, AS-12 attack scenarios for UCA-1 and UCA-12
  • Added CG-9 through CG-13 for 7 threat scenarios missing goals
  • Added CD-10 through CD-12 and CV-9 through CV-11 for CR-9/10/11
  • Added SP-9 (module hash integrity), SP-10 (cert pin integrity)

Test plan

  • cargo test — all tests pass (551 passed)
  • rivet validate — PASS (5 warnings remaining)
  • rivet coverage — 98.4% weighted traceability
  • CI: all checks should pass

🤖 Generated with Claude Code

Security fix (AS-6):
- KeylessVerifier::verify() had a fail-open path where Rekor verification
  was silently skipped when the Rekor entry UUID was empty or "skipped".
  This violated design decision DD-2 (fail-closed on Rekor unavailability).
  Now returns an error requiring valid Rekor transparency log entry for
  all keyless signature verification.

Coverage improvements (91% → 98.4%):
- Added protects links from all 11 system constraints to security properties
- Added AS-11 (unverified module loading) and AS-12 (OIDC misconfiguration)
- Added CG-9 through CG-13 for remaining threat scenarios
- Added CD-10 through CD-12 and CV-9 through CV-11 for CR-9/10/11
- Added SP-9 (module hash integrity) and SP-10 (cert pin integrity)

Fixes: SC-6
Refs: AS-6, DD-2, UCA-5

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@avrabe avrabe merged commit 7311c5d into main Mar 15, 2026
12 checks passed
@avrabe avrabe deleted the feat/stpa-sec-findings-and-coverage branch March 15, 2026 20:12
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