Metric

Admina Score

The Admina Score is the headline metric on the dashboard — a live-runtime composite (0–100) that answers a single question: right now, how well is this Admina instance actually governing the traffic it sees? It is not a marketing number and not a static checklist — it is recomputed on every read from the proxy's current state.

Live runtime 0–100 GET /api/dashboard/score Recomputed per request

What it measures

The Admina Score is a weighted sum of five independent governance signals. Each signal is a boolean or proportional check against the proxy's current runtime state — not a stored value, and not a promise about future behaviour. Since v0.15.0 a signal that does not apply — the EU AI Act component, when the latest assessment is NOT_APPLICABLE — is left out and the score is rescaled over the others.

87/100
Example live score
Data Residency +25
Interactions Audited +25
EU AI Act Coverage +25
No Recent Attacks +15
Forensic Chain Valid +10
Total 100

Formula

Implemented in admina/proxy/api/dashboard.py::_compute_governance_score.

# pseudocode
earned  = 25  # data residency (constant — always awarded)
earned += 25  # interactions audited (forensic box has events, chain not invalid)
earned += 15  # no blocked requests on any governed surface (cumulative counter)
earned += 10  # forensic chain past GENESIS, not invalid

latest = last EU AI Act assessment, or none
if latest is none:              eu = 0
elif latest.applicable:         eu = round(latest.compliance_score / 100 * 25)  # up to +25
else:                           eu = null  # NOT_APPLICABLE (since v0.15.0)

if eu is null:
    score = round(earned * 100 / 75)    # rescaled over the components that apply
else:
    score = earned + eu
# → 0 <= score <= 100

A component that does not apply is null in breakdown, named in not_applicable, and left out: the points earned are rescaled to 100 over the points of the components that apply (as the OISG evidence score treats not_applicable criteria). Today only the EU AI Act component can be null, so the divisor is 75 — every other component earned scores round(75 × 100 / 75) = 100; residency and audit alone, round(50 × 100 / 75) = 67.

The five components

Data Residency

+25
SignalThe governance proxy is running — this component is a constant, not a measurement
Formula+25 unconditionally, hard-coded in _compute_governance_score
How to improveNothing moves this one — it is a flat +25 for any running proxy. No admina.yaml key feeds it, and the ResidencyEnforcer class is never instantiated by the proxy pipeline. Runtime residency enforcement is an SDK feature instead — GovernedData(connector=..., residency_zone="eu") raises on ingest or query outside the allowed zones — but that enforcement does not feed this component.

Interactions Audited

+25
SignalForensic black box is active with at least one recorded event
Formula+25 when forensic_box.record_count > 0 and the chain status is not invalid (since v0.13.1), else 0
How to improveSend at least one request through /mcp, /api/v1/audit, or /v1/chat/completions to seed the chain — traffic is the only thing that moves this component. /api/v1/validate is counted as traffic but writes no forensic record, so it does not move this one. The proxy always has a forensic store (in-memory when no backend is set), so a persistent backend (filesystem or s3) is not what earns the points; it is what keeps the record count from dropping back to 0 on restart. A store that cannot record — a backend that could not be opened at startup in open fail mode, or (since v0.13.0) a chain reported invalid — adds no records; check forensic_writable and forensic_chain on /health.

EU AI Act Coverage

+25
SignalArticle 9–15 coverage of the latest EU AI Act assessment — or, since v0.15.0, left out of the score when that assessment is <code>NOT_APPLICABLE</code>
FormulaLatest assessment applicable: round(compliance_score / 100 × 25). No assessment recorded: 0. Latest assessment NOT_APPLICABLE (a limited or minimal system): null, listed in not_applicable, and the score is rescaled over the other 75 points
How to improveRun POST /api/compliance/gap-analysis with the risk_category of your system. For high or unacceptable the component follows the compliance_score of that gap analysis: close the gaps it surfaces (risk management, data governance, logging, transparency, human oversight, accuracy/robustness). Since v0.15.0 a limited or minimal system is recorded too, as NOT_APPLICABLE — Articles 9–15 do not apply to it — and the component becomes null instead of 0: it is not held against the score. A voluntary: true self-assessment of such a system is not counted either. Only the most recent assessment counts, whatever its system_name; without any, the component applies and stays at 0. (POST /api/compliance/report records one too: it classifies the description first, then runs the gap analysis for that category, passing voluntary on since v0.15.1.) Assessments are held in memory and reset on restart unless ADMINA_EU_AI_ACT_ASSESSMENTS_PATH names a file (since v0.15.0; the compose files set it on a volume), which keeps the last 100 across restarts (since v0.15.1 a malformed file is set aside as <name>.corrupt-<UTC time> and the store starts empty). The compliance surface must be enabled: with ADMINA_ENABLED_SURFACES leaving it out, /api/compliance/* answers 404.

No Recent Attacks

+15
SignalZero requests blocked on any governed surface since the process started
Formula+15 if metrics.requests_blocked == 0, else 0
How to improveA zero here is good — it means no request has been blocked since the proxy started. The counter is the requests_blocked of /api/stats (admina_requests_blocked_total on /metrics): BLOCK and CIRCUIT_BREAK decisions on /mcp, on the gateway (/v1/chat/completions, since v0.12.2) and on /api/v1/validate (since v0.13.0), plus — since v0.13.0 — /mcp responses blocked by a governance guard, and /mcp requests refused by the rate limiter (429) or the token-size guard (413), in every governance mode. Since v0.15.1 the same holds for a call to a sandboxed /mcp tool refused for invalid arguments (400, counted BLOCK, domain sandbox); one refused because the sandbox is unavailable or busy (503) is counted ERROR and leaves this component alone. It is cumulative for the process lifetime, so it resets on restart. In observe and dry-run mode a would-be governance block is recorded as allowed, so attacks alone leave this component at +15; only those 429 / 413 refusals and invalid sandbox calls still take it to 0. If the score dropped to 0, inspect the blocked-action events in the live feed.

Forensic Chain Valid

+10
SignalThe head of the SHA-256 hash chain has moved past GENESIS — at least one record has been chained — and the chain is not reported <code>invalid</code>
Formula+10 when forensic_box.chain_head != "GENESIS" and the chain status is not invalid (since v0.13.1), else 0
How to improveSend real governed traffic through the proxy so the forensic logger appends at least one record past GENESIS, and keep the chain intact. Since v0.13.1 a chain reported invalid earns neither these +10 nor the +25 of Interactions Audited (in 0.13.0 it kept both). The component still does not re-verify every record: for a full integrity check use admina forensic verify or GET /api/v1/forensic/verify, and forensic_chain on /health.

Admina Score vs OISG Score

Admina surfaces two 0–100 scores on the dashboard. The Admina Score (this page) is a live runtime composite. The OISG Score is a static capability assessment. They answer different questions and should be read together.

→ Full side-by-side comparison, a 2×2 interpretation matrix (high/low × high/low), and scenario-based guidance on which score to consult first: Admina Score vs OISG Adequacy.

API response

curl http://localhost:8080/api/dashboard/score \
  -H "X-API-Key: $ADMINA_API_KEY"
{
  "score": 87,
  "max_score": 100,
  "breakdown": {
    "data_residency": 25,
    "interactions_audited": 25,
    "eu_ai_act_coverage": 12,
    "no_recent_attacks": 15,
    "forensic_chain_valid": 10
  },
  "not_applicable": [],
  "computed_at": "2026-10-17T09:30:00+00:00"
}

With a NOT_APPLICABLE latest assessment (since v0.15.0) — here with one request blocked since the proxy started, so 60 of the 75 applicable points:

{
  "score": 80,
  "max_score": 100,
  "breakdown": {
    "data_residency": 25,
    "interactions_audited": 25,
    "eu_ai_act_coverage": null,
    "no_recent_attacks": 0,
    "forensic_chain_valid": 10
  },
  "not_applicable": ["eu_ai_act_coverage"],
  "computed_at": "2026-10-17T09:30:00+00:00"
}

The endpoint belongs to the dashboard surface: with ADMINA_ENABLED_SURFACES (since v0.13.0) leaving dashboard out, it is not mounted and answers 404. See Configuration.