Access is not authority
A PDP permit says the subject may act in general. Decionis still decides whether this exact action, with this amount, target, risk, prior sequence and any required human approval, executes now.
Most institutions already have a policy decision point that answers the OpenID AuthZEN question: may this subject perform this action on this resource? Decionis does not replace it or re-ask it. Its answer travels into the authority request as a material signal, and Decionis answers the different question it owns: does this exact execution have authority now, under your policy, with proof afterwards.
AuthZEN is an input to authority, never the protocol core. The PDP is consulted in your process before the authority request; nothing calls out from inside evaluation.
Okta / Entra / SGNL / any AuthZEN PDP
│ access decision (POST /access/v1/evaluation → { decision })
▼
Decionis ← the answer arrives as signals.upstream_authorization
│ deterministic execution authority over policy + request + supplied facts
▼
ExecutionBinding → pre-commit claim → execution → signed dossierA PDP permit says the subject may act in general. Decionis still decides whether this exact action, with this amount, target, risk, prior sequence and any required human approval, executes now.
Decionis never overrides an upstream refusal. The starter policy turns a PDP deny into BLOCK before any other rule runs.
A missing, unreachable, unlisted or tampered PDP answer never becomes a permit. required_signals and signal_admission resolve it to ESCALATE (or BLOCK, if you say so).
createAuthZenEntitlementProvider calls the PDP over HTTPS at an allow-listed origin, parses the AuthZEN 1.0 response strictly, digests the exact request and response, and packs the answer into an upstream_authorization signal.
import { DecionisNodeSdk, createAuthZenEntitlementProvider } from "@decionis/sdk-node";
const pdp = createAuthZenEntitlementProvider({
pdpUrl: "https://pdp.example.com", // your AuthZEN policy decision point
headers: { authorization: `Bearer ${process.env.PDP_TOKEN}` },
});
// 1. Ask the PDP the AuthZEN question, in your process, before Decionis.
const { context, result } = await pdp.enrichContext(
{
subject: { type: "agent", id: "agent:treasury-bot" },
resource: { type: "account", id: "acct:ops-eur" },
action: { name: "payment.release" },
},
{ channel: "api" },
);
// result.ok === false → no signal was attached; the policy's fail-safe applies.
// 2. Ask Decionis the execution-authority question, with the answer as a fact.
const decision = await sdk.evaluateDecision({
decision_type: "payment.release",
amount: 25_000,
context,
});| Field | Meaning |
|---|---|
| kind | upstream_authorization — a built-in semantic signal kind |
| producer.provider | The PDP's identity (its origin by default); must appear in the policy's allowed_producers |
| producer.detector_version | authzen/1.0 |
| value.decision | The PDP's boolean answer |
| value.subject / resource / action | Exactly what was asked, without properties |
| value.request_digest / response_digest | RFC 8785 digests of the request and response bodies |
| evidence_digest | The response digest, so require_evidence_digest sees the PDP's own bytes |
| value_digest | Recomputed by the Protocol; a mismatch refuses the signal |
| material | true — the answer enters the execution binding and is revalidated at claim |
provider.discover() reads /.well-known/authzen-configuration and adopts the evaluation endpoint it names only when that endpoint's origin is allow-listed. A document that points elsewhere is ignored.
The answer is read like any other fact. buildAuthZenStarterPolicyBundle in @decionis/shared ships this shape, tested verbatim through the ingestion schema and the evaluator.
{
"required_signals": ["upstream_authorization"],
"metadata": {
"signal_admission": {
"allowed_producers": ["https://pdp.example.com"],
"allowed_detector_versions": ["authzen/1.0"],
"require_evidence_digest": true,
"minimum_confidence_basis_points": 10000,
"on_failure": "ESCALATE"
}
},
"rules": [
{
"rule_id": "authzen_block_upstream_deny",
"when": { "all": [{ "field": "signals.upstream_authorization.decision", "operator": "EQ", "value": false }] },
"then": { "action": "AUTO_REJECT", "severity": "urgent" },
"priority": 300
},
{
"rule_id": "authzen_escalate_permitted_over_desk_limit",
"when": { "all": [
{ "field": "signals.upstream_authorization.decision", "operator": "EQ", "value": true },
{ "field": "amount", "operator": "GT", "value": 1000 }
] },
"then": { "action": "ESCALATE", "severity": "elevated", "sla_minutes": 60 },
"priority": 200
}
]
}| Situation | Resolution |
|---|---|
| PDP said deny | BLOCK (authzen_block_upstream_deny) |
| PDP said permit, amount within the desk limit | ALLOW |
| PDP said permit, amount above the desk limit | ESCALATE — a named person decides |
| No PDP answer in the request | ESCALATE via required_signals (missing_required_signals) |
| Answer from a PDP not in allowed_producers | ESCALATE via signal_admission (producer_not_allowed) |
| Answer altered after the PDP returned it | ESCALATE — value_digest_mismatch; the signal is dropped |
Nothing new is added to the Decision Dossier for this. The envelope is recorded verbatim inside the signed inputs snapshot, so a verifier already sees which PDP said what, when, over which request.
inputs_snapshot.context.signals.upstream_authorization carries the full envelope; signal_provenance records producer, version, digests and whether it was admitted. The verdict replays offline from the dossier with no call to the PDP.
Because the signal is material, its id, version, observation time and digests are part of the execution binding. A different PDP answer at claim time is a stale-state rejection, not a silent re-permit.
What this integration is, and is not.
Decionis does not expose an AuthZEN evaluation endpoint. A boolean decision cannot carry ESCALATE, which is the outcome this product exists to produce.
The Protocol never fetches during evaluation. The PDP is consulted by your code, in your process, and the evaluator stays a deterministic function of policy, request and supplied facts.
Decionis is not a member of the OpenID Foundation. AuthZEN is referenced as the published Authorization API 1.0 (January 2026); Okta, Microsoft Entra and SGNL are named as examples of policy decision points, not as partners.