OneFineStarstuff.github.io
e8a2596d - feat(assurance): evidence freshness-SLA gate — catalog SLAs enforced against a digest-protected ledger (18th assurance check)

Commit
42 days ago
feat(assurance): evidence freshness-SLA gate — catalog SLAs enforced against a digest-protected ledger (18th assurance check) The OSCAL catalogs declare per-control freshness-sla props (env-01 PT5M, cry-02/rte-01 P1D, con-07 P7D, cry-05 P3M, con-04 P1D/P90D) but check C3 only validated their FORMAT — nothing recorded when evidence was produced and nothing failed when it went stale. The SLA was prose. This makes it enforced. New tool — governance_artifacts/check_evidence_freshness.py: - --run executes every control's mapped runnable assurance check using the SAME single-source-of-truth CONTROL_EVIDENCE map the regulator deliverable generators use (no parallel drift-prone map) and writes a freshness ledger (oscal/generated/evidence_freshness_ledger.json) recording pass/fail, the UTC instant evidence was produced, and duration. Entries are protected by a SHA-256 ledger digest over the canonical entries JSON. - --audit enforces each catalog-declared SLA against those instants with named, falsifiable checks: ledger-digest, evidence-recorded, evidence-passed, evidence-fresh. Per-control statuses: FRESH / STALE / FAILED / NOT-RECORDED / FUTURE-DATED / SLA-MISSING / SLA-MALFORMED / NOT-RUNNABLE. Exit 0 iff every runnable control is recorded, passed and fresh with an intact digest. - Honest semantics: organisational-evidence controls (env-02) are disclosed NOT-RUNNABLE, never counted fresh and never silently passed; a failed check is never fresh; future-dated evidence (forged timestamp/clock skew) fails; a missing ledger fails, never passes vacuously. Stated conversion convention (1M=30d, 1Y=365d; compound P1D/P90D enforces the first period) so audits are reproducible. The ledger digest detects casual edits, is NOT a signature — pair with the ML-DSA-65-signed bundle (checks 16/17) for signed provenance. --as-of enables reproducible point-in-time audits. Wiring: - run_runnable_assurance.sh: 17 -> 18 steps. Step 18 runs --run --audit --print and asserts PASS, intact digest, zero failing controls, all runnable controls FRESH, and >=1 organisational control disclosed. - RUNNABLE_ASSURANCE.md: row 18 documents the gate and its honesty limits. Tests (tests/governance/test_governance_artifacts.py — round 8, +7): - SLA parser conventions (PT5M=300s, P3M=90d, P1D/P90D first period; malformed P/PT/5M/P-1D/'' rejected). - Fresh synthetic ledger -> PASS with env-02 disclosed NOT-RUNNABLE. - Auditing 10 min later flips env-01 (PT5M) STALE and fails the gate while cry-05 (P3M) stays FRESH — SLA granularity actually matters. - Timestamp edit without re-digesting -> ledger-digest MISMATCH -> FAIL. - passed=false is never FRESH; future-dated evidence FAILs; a control missing from the ledger is NOT-RECORDED; missing ledger file FAILs. - Single-source-of-truth check: every runnable CONTROL_EVIDENCE control with a declared SLA is covered by the committed ledger. Full suite result: 18/18 runnable assurance checks PASS; 37/37 governance tests PASS.
Parents
Loading