Compliance API
The pluggable compliance-policy engine (ADR-018) and the Compliance
dashboard region's aggregation endpoints (DES-002 §2 Region C+E, Issue
#706). This is a real, shipped engine that continuously evaluates
policy-pack controls against the live audit log and generates
JSON/PDF evidence reports on demand — distinct from the regulatory-posture
narrative docs in docs/compliance/, which
describe what Hoziron claims to satisfy; this page documents the
mechanism that produces the evidence for those claims.
Endpoints
| Method | Path | Action | Description |
|---|---|---|---|
| GET | /compliance/packs | ComplianceRead | List every loaded policy pack |
| GET | /compliance/packs/{id}/report | ComplianceRead | Generate an evidence report for one pack (JSON or PDF) |
| GET | /compliance/pii-coverage | SecurityRead | PII tokenise/hydrate coverage, all-time |
| GET | /compliance/forced-local-routing | SecurityRead | Forced-local PII routing over PII-bearing traffic, all-time |
GET /compliance/packs
Lists every loaded compliance policy pack — the built-in POPIA pack plus
any carrier-supplied packs from $HOZIRON_HOME/compliance/packs/ (the
compliance_pack_dir config field — see
config-toml.md).
curl -H "Api-Version: v1" -H "Authorization: Bearer hzn_sk_..." \
http://localhost:4200/compliance/packs
Response (200)
{
"packs": [
{
"id": "popia",
"name": "Protection of Personal Information Act",
"version": "1.0.0",
"jurisdiction": "ZA",
"control_count": 12
}
]
}
GET /compliance/packs/{id}/report
Generates an evidence report for one policy pack. Each control's cached status is kept fresh as relevant audit events occur (continuous evaluation), so this is a fast read of already-current state, not a from-scratch scan of the audit log on every call.
curl -H "Api-Version: v1" -H "Authorization: Bearer hzn_sk_..." \
http://localhost:4200/compliance/packs/popia/report
Query Parameters
| Param | Description | Default |
|---|---|---|
format | json or pdf (Issue #190) | json |
Response (200, format=json)
{
"framework_id": "popia",
"framework_name": "Protection of Personal Information Act",
"framework_version": "1.0.0",
"jurisdiction": "ZA",
"generated_at": "2026-07-13T12:00:00Z",
"controls": [
{
"control_id": "popia-19",
"requirement": "Security safeguards for the integrity and confidentiality of personal information",
"platform_controls": ["pii-tokenisation", "audit-log-hash-chain"],
"status": "Satisfied",
"evidence_description": "PII tokenised at ingress; audit log hash-chained and continuously verified.",
"evaluated_at": "2026-07-13T11:58:02Z"
}
],
"satisfied_count": 11,
"unsatisfied_count": 0,
"unknown_count": 1
}
status is one of Satisfied, Unsatisfied, or Unknown (no audit store
attached yet, or the control has never been evaluated — evaluated_at is
null in that case).
Response (200, format=pdf)
Returns application/pdf with a Content-Disposition: attachment; filename="compliance-report-<framework_id>.pdf" header — a rendered PDF
of the same report, not a wrapped JSON body.
Error (404 — unknown pack)
{"error": {"category": "NotFound", "message": "No compliance policy pack 'unknown-pack' is loaded"}}
Error (400 — unsupported format)
{"error": {"category": "ValidationError", "message": "Unsupported format 'xml': expected 'json' or 'pdf'"}}
GET /compliance/pii-coverage
PII tokenise/hydrate coverage for the Compliance dashboard region. All-time,
not window-scoped. Derived from the audit log's pii:pii.tokenize /
pii:pii.hydrate entries, not a separate metrics store.
curl -H "Api-Version: v1" -H "Authorization: Bearer hzn_sk_..." \
http://localhost:4200/compliance/pii-coverage
Response (200)
{
"coverage_pct": 100.0,
"tokenised": 1204,
"hydrated": 1204
}
coverage_pct is hydrated / tokenised * 100, or 100.0 if nothing has
been tokenised yet (nothing to fail to hydrate). If no audit store is
attached, the response is instead {"coverage_pct": null, "tokenised": 0, "hydrated": 0, "status": "disabled"}.
GET /compliance/forced-local-routing
Forced-local PII routing over PII-bearing traffic — the share of
PII-bearing requests the ADR-049 local_only policy path routed to a
local model, versus the total PII-bearing traffic. All-time, not
window-scoped.
curl -H "Api-Version: v1" -H "Authorization: Bearer hzn_sk_..." \
http://localhost:4200/compliance/forced-local-routing
Response (200)
{
"forced_local": 340,
"local_eligible": 388,
"pct_of_local_eligible": 87.6,
"target_pct": 85.0
}
local_eligible— all routing decisions (local + regional + cloud) where the request carried at least one detected PII type; a cloud- or region-permitted PII type still counts hereforced_local— the subset specifically forced local by the ADR-049local_onlypolicy path (reasonprefixpii:local_only(adr-049))target_pct— a fixed 85.0 display constant from the DES-002 spec's own example target, not sourced from any ADR-defined numeric threshold- Routing events recorded before this metric shipped have no
detected_pii_typesmetadata key and are excluded from both sides of the calculation, not counted as non-PII — this keeps the all-time metric from being permanently skewed on an environment with pre-existing audit history
If no audit store is attached, the response is instead {"forced_local": 0, "local_eligible": 0, "pct_of_local_eligible": null, "target_pct": 85.0, "status": "disabled"}.
Related
- security.md — audit trail, security status, and the RBAC roles gating these routes
- ../../compliance/README.md — regulatory-framework posture narrative (GDPR, POPIA, SOC 2)
- ../config/config-toml.md —
compliance_pack_dirconfig field