Skip to content

Compliance Library — coverage & tiering

Logrite’s compliance engine is a per-line / per-prompt token+regex matcher emitting block | notify | allow. It evidences controls that leave an artifact in a log line or an AI prompt. It is not an auditor: it cannot read your policies, inspect your contracts, verify staff training, or perform the statistical arithmetic a bias audit requires.

So a coverage percentage is only meaningful against a stated denominator. Every framework carries a coverage manifest — an enumerated list of its obligations, each classified one of three ways:

ClassMeaningHow it is satisfiedCount
DETECTABLEa log line or prompt can carry evidencea seeded rule matches172
ATTESTABLEreal obligation, no runtime artifactthe workspace records evidence89
OUT_OF_SCOPEnobody the operator controls can evidence itexcluded from the denominator4
detection coverage = satisfied_detectable / detectable
attested coverage = current_attestations / attestable

The two are reported separately and never averaged. “A rule fires on this” and “somebody signed a statement about this” are different strengths of evidence; merging them would produce the most flattering and least honest number on the page.

An unexplained exclusion is impossible to express — the manifest record rejects it at construction, and an ATTESTABLE obligation with no evidence type is rejected the same way.

ComplianceCoverageService.computeCoverage() resolves “satisfied” against the live snapshot’s rule ids, never against the manifest’s own claim. A manifest entry naming a rule nobody wrote counts as a gap, not as credit.

ComplianceCoverageManifestTest enforces this in CI. It fails the build when:

  • a manifest entry credits a rule the seeder never declares, or
  • any framework drops below 99% of its detectable surface.

Adding an obligation therefore lowers the number until someone writes the rule. Coverage cannot rot silently as regulations change.

Terminal window
GET /api/v1/warden/library/coverage

Returns per framework: coveragePct, detectable, satisfied, outOfScope and the named gaps, plus attestable, attested, attestedPct, notApplicable and pendingAttestations. Frameworks with no manifest report measured: false rather than a fabricated 100%.

TierFrameworksIn pickerCoverage
Core — USHIPAA · PCI DSS v4.0.1 · SOC 2 · CCPA/CPRA · OMB M-26-14 · AI-Data-Gov · OWASP-LLMyes100%
Core — EUGDPR · EU AI Actyes100%
OperationalOPS (system-health signals, not a compliance framework)hiddenn/a
CatalogueGLBA, SOX, FedRAMP, CMMC, CJIS, NERC-CIP, FERPA, COPPA, BIPA, US-State-Privacy, DORA, NIS2, ISO 27001/27701/42001, NIST-AI-RMF, Colorado-AI, TRAIGA, NYC-LL144, GENhidden100%

Promotion is one flag in ComplianceLibraryService.CORE_FRAMEWORKS, or an ops-side override with no code change at all:

Terminal window
COMPLIANCE_VISIBLE_FRAMEWORKS=hipaa,pci,soc2,gdpr,glba

One library, two consumers — the analyzer no longer keeps its own list

Section titled “One library, two consumers — the analyzer no longer keeps its own list”

The compliance library is seeded by ComplianceLibrarySeeder; the analyzer runs off rows in AnalyzerRulesConfig. Until 2026-08-14 those were two hand-maintained lists, and only the frameworks someone remembered to add a literal for in LogLeakRulesSeeder reached the analyzer — 24 of the 29 seeded frameworks never got that treatment. A workspace could bind ISO 27001 in the Warden, where it blocked and notified correctly, then run a code scan that had never heard of it: same product, same customer, two different answers about the same regulation.

ComplianceAnalyzerRulesSeeder removes the second list. It reads the live compliance-library snapshot — which already enumerates every rule with its category, severity, citation and remediation hint — and derives the analyzer rows from it at ApplicationReadyEvent. So:

  • seeding a new framework in ComplianceLibrarySeeder makes it scannable automatically; there is no second place to remember and therefore no second place to forget;
  • a rule disabled or removed upstream simply stops appearing. Existing rows are left alone rather than deleted, so a workspace’s own edits survive a redeploy;
  • ComplianceFrameworkVisibilityTest pins the invariant — a framework in the library that the analyzer cannot see fails the build.

Leak rules vs coverage signals — inverted semantics

Section titled “Leak rules vs coverage signals — inverted semantics”

Two rule shapes, and the difference matters when reading a finding:

ShapeA match meansActionRuns on
Leak (valuePatterns / tokens)sensitive data is present — a violationblock / notifyrelay hot path + analyzer
Coverage (crSig signature)this event type is being logged — evidence a control operatesnotify onlyanalyzer log scan (relayApplicable=false)

A false positive on a leak rule blocks a real request, so leak patterns are context-gated: they require the labelling field name, not just a shape. A bare five-digit number is not a ZIP code and a bare date is not a date of birth.

Coverage signals are deliberately excluded from the relay hot path so posture telemetry never adds notify-noise to live AI traffic. Three rules are documented exceptions — m2614_log_management, sox_audit_log_tamper and sox_privileged_access carry a coverage category but have leak semantics (a match is the bad thing), so they legitimately run inline. The list is pinned by a test, so a new coverage rule cannot drift onto the hot path unnoticed.

A regex match is a candidate, not a finding. The PAN patterns are prefix-and-length only, so any 16-digit number beginning with 4 matched them — including ordinary order and trace ids. Because pci_log_leak_payment is a block rule, that was enough to reject live traffic.

matchPattern therefore Luhn-checks (ISO/IEC 7812) any match that is card-shaped — a run of 13–19 digits separated by nothing but spaces or hyphens. Everything else is passed through untouched, so the gate can never suppress a non-card finding: an SSN is nine digits, a phone number at most eleven, and a labelled account id carries its label inside the match.

The scan also walks every match rather than stopping at the first, so a rejected near-miss earlier in a line cannot shadow a real PAN later in it.

FrameworkStatus
HIPAASecurity Rule NPRM still proposed; OMB final action slipped to July 2027. MFA/encryption are therefore not treated as required. Safe Harbor 45 CFR 164.514(b)(2) unchanged — all 18 identifiers are addressed individually.
PCI DSSv4.0.1 only (v4.0 retired 2024-12-31); all 51 future-dated requirements mandatory since 2025-03-31. PCI SSC ran an RFC through 2026-07-20 — a v4.x revision is in motion.
SOC 2TSC 2017 + 2022 revised points of focus; unchanged in 2026.
CCPA/CPRACPPA regs effective 2026-01-01. Risk assessments live now; ADMT 2027-01-01; cyber-audit certifications phased 2028-04-01 → 2030-04-01.
OMB M-26-14Issued 2026-05-22, rescinds M-21-31. CISA’s Logging Reference Architecture is due ~2026-08-20 and is not yet published — deliberately unmodelled rather than guessed.
EU AI ActDigital Omnibus in force 2026-07-27. Annex III high-risk deferred to 2027-12-02, Annex I to 2028-08-02. Art.50 transparency applicable since 2026-08-02; Art.51-56 GPAI running since 2025-08-02.
COPPA2025 amendments in full effect since 2026-04-22 — personal information now includes biometric and government-issued identifiers.

The relay loads its rules from the backend snapshot. If that fetch fails it falls back to a bundled copy. That bundle used to be hand-maintained and had drifted to 68 of 221 seeded rules — so a database outage silently downgraded PCI to a token-only rule that missed a bare PAN.

It is now generated from the seeder, for both the relay and the analyzer’s vendored copy:

Terminal window
npm run gen:catalogue # regenerate both targets
npm run check:catalogue # CI guard — fails if the checked-in bundle is stale

The seeder is the single source of truth; the generator never invents a rule.

Attestations — the 89 obligations no scanner can see

Section titled “Attestations — the 89 obligations no scanner can see”

An executed BAA, a penetration-test report, an ISO certificate, a physical access review: every framework requires things that leave no log line. Reporting those as “out of scope” told a user we could not see them, but not what to do about it. Each is now a first-class obligation with the specific evidence to produce.

Terminal window
GET /api/v1/warden/library/attestations?libraryKey=hipaa # the checklist + current answers
POST /api/v1/warden/library/attestations # record evidence
DELETE /api/v1/warden/library/attestations?libraryKey=…&obligationId=…

Each obligation declares an evidence type — POLICY, CONTRACT, TRAINING, PERSONNEL, CERTIFICATION, ASSESSMENT, PHYSICAL, CONFIGURATION, PUBLISHED_NOTICE, REGULATORY_FILING or GOVERNANCE — which decides what the UI asks for and whether an expiry is mandatory.

Expiry is derived, never stored. An attestation stops counting on the day it lapses, evaluated against the request date — no sweep job, no cron, no stale certificate quietly propping up a number. GET /library/coverage returns attestable, attested, attestedPct and the named pendingAttestations alongside the detection figures.

NOT_APPLICABLE removes an obligation from that tenant’s denominator rather than counting it as satisfied — a workspace with no physical premises should not be marked compliant with a physical control, only excused from it.

Only four obligations are genuinely outside the model — everything else that a scanner cannot see is now ATTESTABLE rather than excluded:

FrameworkObligationWhy it stays out
HIPAA2025 Security Rule NPRMproposed only; OMB final action slipped to July 2027
M-26-14CISA Logging Reference Architecturenot yet published — unmodelled rather than guessed
TRAIGAproving intentliability turns on a legal state of mind
TRAIGAAG enforcement / 60-day curethe regulator’s action, not the operator’s control

The distinction is whether the operator can hold evidence for it. Policy documents, BAAs, physical safeguards, training records, penetration tests, certification engagements and the NYC LL144 bias audit all can be — so they are attestable, not excused.