ADR-0036: The ADL is the authoritative record of authorization decisions¶
- Status: accepted
- Date: 2026-11-02
- Satisfies: P-12, S09, S05
- Deliberation: REQ-71, F-53, F-63, F-72, and demo PR #337, PR #373 (#332)
- Implemented in:
- docker-compose.yml: the ADL is required in every profile.
- adl-reader.sql: the SELECT-only reader.
- authz.rego: what the record carries.
- dev-portal-backend/adl.go: the lookup by transaction ID.
Context and problem statement¶
The PDP produces two decision logs:
- The Authorization Decision Log (ADL), which OpenFTV writes to Postgres.
- The console decision log of the embedded OPA, which goes to Loki.
The design did not say which log is the audit source (F-53). The Logius standards family has three records with three roles (F-63):
- The ADL for decisions.
- LDV for processings (ADR-0026).
- FSC-Logging for transport.
A PDP decision is not a processing, so it is not an LDV record.
Decision¶
The decision has four parts:
- An ADL record holds every PDP decision. OpenFTV writes the record to
the Postgres database
ftv_adl. The PDP does not start without this database, so the ADL runs in every deployment profile. - The ADL record is the audit source for authorization decisions. Contract-acceptance decisions are ADL records too.
- The console decision log of the engine is observability. Nobody cites it as the record of a decision.
- A reader gets a SELECT-only database role (
adl_reader).
Considered options¶
- The ADL as audit source (chosen). It is a standard record with an access model.
- The console decision log as audit source. Not chosen: it is a log pipeline that can lose or sample lines, and it has no access model (F-53).
- Per-field detail in the reason of the record. Not chosen: the Inway returns the reason to the consumer (F-72).
Consequences¶
- The record carries only
{allow, reason}. On a deny, the reason is the code for the consumer (FIELD_NOT_PERMITTED,ACCESS_DENIED,COVERAGE_UNVERIFIABLE <subcode>, and more). The per-field rule codes and the step trace are only in the console log (REQ-06). - The record has these known gaps:
- The record does not name the policy version (
policies: 0, REQ-59). - The record does not hold the consent-status answer
(
adl.core.information) or the configuration (F-72). - Behind the FSC Inway, the record does not hold the trace ID or
adl.fsc.transaction_id(#369, ADR-0035). The dev portal finds the record through the stored request headers. - No pointer leads from the ADL record to the logbook of the consent register (toestemmingsregister) (Q-25).
- In the EUDI and ASI routes, the record holds the plain BSN (REQ-60, ADR-0043).
- The record does not name the policy version (
- A replay of a decision from (input, policy, data) is not possible, because the policy fetches the consent status during the evaluation (ADR-0032). A replay needs the non-deterministic built-in cache of OPA, and OpenFTV does not enable this cache.
- Retention, read access, and tamper evidence are not set (REQ-32, Q-08).