Close the remaining PDP obligations: mechanical layer declaration check, registry-snapshot digest in provenance, explicit allow TTL, per-input-class freshness deadlines, and the published decision-record contract. Document the canonical request digest as the §6.4.2 replay test. Assistant: grok Assistant-Session: 01a06256-fb71-7102-b3a9-27e6734257d0
2.5 KiB
Decision-record contract
Status: published
Contract: flex-auth.decision-record.v1
Schema: ../schemas/decision_envelope.schema.json
Date: 2026-09-02
This is flex-auth's output artifact under the NetKingdom Security Layer Model v0.7 §17. Taxonomy holds only the shared field vocabulary. Consumers may rely on this schema.
A decision record is a DecisionEnvelope returned by POST /v1/check and the
CLI check / batch-check / list-allowed commands. Standalone evaluation
and every delegated adapter (Topaz, relationship, rule, Keycloak) emit the
same shape.
Required fields
| Field | Meaning |
|---|---|
id |
Deterministic decision identifier |
effect |
allow, deny, redact, audit_only, or not_applicable |
subject / resource |
Normalized refs the evaluator used |
provenance |
Who evaluated, over which policy and facts |
Contract fields consumers may rely on
| Field | Meaning |
|---|---|
contract_version |
flex-auth.decision-record.v1 |
binding |
Structured subject, action, resource, context, and request_digest |
lifetime |
Required on every allow. A TTL with not_before and expires_at |
provenance.policy_package / policy_version |
Named package pin |
provenance.policy_package_digest |
SHA-256 of package metadata plus compiled Rego |
provenance.registry_snapshot_digest |
SHA-256 of the canonical registry snapshot |
provenance.directory_etag |
Directory consistency token when a delegated directory was joined |
provenance.input_claim_digests |
SHA-256 per request-time claim class (context, caring_context) |
provenance.decision_time |
UTC timestamp used to compute lifetime |
reason, diagnostics, and CARING prose are not an authorization contract.
Allow lifetime
Every allow carries lifetime.kind = ttl. The duration comes from the policy
package allow_ttl field, or from the engine default of 15m when the package
omits it. A package that declares allow_ttl: none (or 0s) produces a deny
with reason allow_lifetime_unstated instead of a standing grant.
Replay is permitted only while lifetime.expires_at is still in the future.
See canonical-request-digest.md and
decision-input-freshness.md.
Versioning
This is contract version 1. Additive optional fields may appear. Removing or
redefining a required field requires a new contract_version value and a new
schema id.