Skip to main content

Compliance Overview

The Compliance Overview API is the single endpoint that powers the dashboard's Compliance Posture card on the Overview page. It aggregates four runtime signals — Hash Chain status, Active Incidents, FRIA completeness, and a derived alerts band — into one rollup the dashboard renders without a second query. Tested against API version v1. Mounted at /api/v1/compliance-overview. JWT auth on the only endpoint; plan-gating happens inside the handler so plans below Governance receive 200 OK with data: null rather than 403 UPGRADE_REQUIRED.

The graceful-degradation posture exists deliberately: the Overview card calls this endpoint on every dashboard load, and a hard 403 would force the frontend to special-case lower-tier plans. Returning data: null lets the same UI render with a "Compliance posture available on Governance and above" prompt.

Endpoint

GET /api/v1/compliance-overview/posture

The legacy mount /api/compliance-overview/posture returns the same payload with a Deprecation header.

Request

curl
curl https://api.adjudon.com/api/v1/compliance-overview/posture \
-H "Authorization: Bearer $ADJUDON_JWT"

No query parameters. The handler reads the active org from the caller's JWT and aggregates synchronously across the four sections. Each section's contribution is plan-gated independently — an Enterprise plan with FRIA disabled receives the hashChain + incidents sections populated and fria: null.

Response shape

{
"success": true,
"data": {
"score": 88,
"status": "healthy",
"sections": {
"hashChain": {
"metric": 1247,
"label": "Verified entries",
"status": "healthy",
"detail": "Chain intact; last verified 12 minutes ago",
"href": "/dashboard/compliance/hash-chain"
},
"incidents": {
"metric": 2,
"label": "Active incidents",
"status": "warning",
"detail": "Next deadline in 3 h 14 min (DORA Art. 19 initial notification)",
"href": "/dashboard/incidents/65b1f2c4",
"nextDeadlineIncidentId": "65b1f2c4"
},
"fria": {
"metric": 5,
"label": "Approved FRIAs",
"status": "healthy",
"detail": "1 FRIA below 70% completeness",
"href": "/dashboard/fria",
"incompleteCount": 1
},
"alerts": [
{
"id": "fria-incomplete",
"status": "warning",
"kind": "fria_overdue",
"message": "1 FRIA assessment(s) below 70% completeness",
"href": "/dashboard/fria"
}
]
}
}
}

data: null is returned (with 200 OK) for orgs whose plan includes none of the contributing features (hashChainAudit, multiClockIncidents, friaWizard).

The four sections

SectionSourcePlan gate
hashChainhashChainService.getStatus(orgId) — verified count + last-verify timestamphashChainAudit (Governance+)
incidentsIncident.find({ status: $in active states }) — active count + next deadlinemultiClockIncidents (Governance+)
friafriaService.listForOrg() filtered to non-terminal states — counts + completeness check below 70% thresholdfriaWizard (Governance+)
alertsDerived band — one entry per overdue FRIA, breached incident clock, or stale hash-chain verify(computed; not separately gated)

Each section's status is one of healthy, warning, critical, or unknown. The top-level score is a 0-100 composite weighted across the populated sections; sections that returned null from a plan gate do not contribute to the score.

How score is computed

The composite is a weighted average across populated sections, with each section contributing in [0, 100]:

  • Hash Chain: 100 if intact, last verify within 1 h; drops linearly to 0 if a chain entry fails verify or last verify exceeded 24 h.
  • Incidents: 100 if no active incidents; minus 25 per incident in warning (next deadline < 24 h); minus 50 per incident in breached. Floor at 0.
  • FRIA: 100 if every active FRIA is ≥ 70% complete; minus 10 per FRIA below the threshold. Floor at 0.

The weights are equal (33 / 33 / 33) when all three sections are populated, and re-normalise when one or more sections are plan-gated to null. The numeric value is stable enough to trend over time on the CPI dashboard but should not be used as a threshold gate — switch on status instead.

Status semantics

StatusWhen the rollup returns it
healthyEvery populated section is healthy; no alerts band entries
warningAt least one section is warning (e.g. one incident's clock is < 24 h from deadline; FRIA below 70% completeness)
criticalAt least one section is critical (e.g. an incident clock is breached; a hash-chain entry failed verify)
unknownThe handler could not compute the section (downstream service unreachable; plan-gated to null)

The dashboard's Overview card colour-codes the rollup card off this enum directly. Programmatic consumers (an internal Slack bot, a custom CISO digest) should switch on status rather than parsing score thresholds — the score's weighting may evolve, but the four-state enum is stable.

Common gotchas

  • Plan-aware, not plan-gated. This endpoint deliberately returns 200 OK with data: null for plans below Governance. The Compliance Posture card on the dashboard renders an upgrade prompt when it sees data: null; do not treat null as an error.
  • Synchronous aggregation. The handler queries hash-chain, incidents, and FRIA in parallel. The 5-minute cache on the dashboard side absorbs repeated calls; backend-side, each section read is sub-100 ms.
  • alerts[] is bounded. The derived alerts band caps at five entries; consume the underlying APIs (Incidents, FRIA) for the full list.
  • Idempotency is irrelevant. Read-only endpoint; nothing to replay.
  • No write surface here. Compliance posture is a derived view. Mutations go to the underlying resources (Incidents, FRIA, policies attached via the Hash Chain trace path).

See also

  • Hash Chain API — the authoritative source for the hashChain section
  • Incidents API — the authoritative source for the incidents section
  • FRIA API — the authoritative source for the fria section
  • Plans & Features — the hashChainAudit, multiClockIncidents, and friaWizard feature gates
  • Error Codes — the broader error taxonomy