A Policy Decision Point (PDP) evaluates access policy for a request. These enforcement points discover the PDP for each API from published metadata. They send the request and the API's access requirements to that PDP using OpenID AuthZEN, a standard API for authorisation decisions. OpenID Federation lets a trusted federation authority restrict which PDPs a member API uses.
The API's protected resource metadata names its PDP. The PDP's AuthZEN metadata identifies its evaluation endpoints. The gateway retrieves both documents.
The gateway forwards the API's metadata with the request details. The PDP uses that metadata to check the required scopes and authentication level. The route can also forward the access token.
Configure the API's resource identifier and the discovery security settings on the gateway. Discovery reads PDP addresses and access requirements from published metadata. The table compares this with configuring those values on each gateway.
| The gateway needs to know | Manual configuration | With discovery |
|---|---|---|
| Which API it is protecting | configured | configured - the resource identifier used for discovery |
| Which PDP decides for that API | configured (AUTHZEN_URL) | read from the API's metadata, or from the federation |
| Where the PDP's endpoints are | assumed (/access/v1/evaluation) | read from the PDP's metadata |
| Which scopes and authentication level the API requires | configured on the gateway, compared by the gateway | published by the API, enforced by the PDP |
| Who controls the published metadata | whoever edits the gateway | the federation's policy, when the API is a member |
The gateway first reads the resource's RFC 9728 document, then the PDP's AuthZEN metadata. It caches both documents. If the PDP publishes no metadata, it uses AuthZEN's default endpoint paths.
{
"resource": "https://api.bank-a.example",
"authzen_policy_set": { "combining": "deny-overrides", "members": [
"https://pdp.bank-a.example/tenants/bank-a"
] },
"scopes_supported": ["accounts:read", "payments:write"],
"acr_values_required": ["urn:idp:loa:mfa"]
}
{
"policy_decision_point":
"https://pdp.bank-a.example/tenants/bank-a",
"access_evaluation_endpoint":
"https://pdp.bank-a.example/tenants/bank-a/access/v1/evaluation",
"access_evaluations_endpoint":
"https://pdp.bank-a.example/tenants/bank-a/access/v1/evaluations"
}
AuthZEN metadata supplies the evaluation endpoint URLs. A PDP identifier can include a tenant path such as /tenants/bank-a. The authzen_policy_set field in resource metadata is a project extension. It is provisional pending a working-group profile.
The gateway forwards the API's metadata as context.resource_metadata and identifies its source. It includes the request method and path. The route can also forward the raw access token. The PDP evaluates these inputs against policy.
"context": {
"resource_metadata_source": "rfc9728",
"resource_metadata": {
"resource": "https://api.bank-a.example",
"scopes_supported": ["accounts:read", "payments:write"],
"acr_values_required": ["urn:idp:loa:mfa"],
"authzen_policy_set": { … }
},
"request": { "method": "POST", "path": "/payments" },
"access_token": "eyJ…"
}
{
"decision": false,
"context": {
"reason": "this resource requires acr [urn:idp:loa:mfa]
(per its rfc9728 metadata); the token was
authenticated at urn:idp:loa:password"
}
}
The PDP evaluates the API's access requirements. The gateway enforces the returned decision. In this example, the denial reason identifies the required authentication level and the metadata that supplied it.
An API can name a PDP that permits every request. TLS authenticates the host serving the metadata. OpenID Federation adds metadata policy from a verified trust chain. A trust anchor is a federation authority whose keys the operator configures as trusted.
The gateway can publish a signed entity configuration and RFC 9728 protected resource metadata for an API. The federation controller retrieves the entity configuration during enrolment. The gateway holds the signing key. The controller maintains metadata policy.
{
"iss": "https://api.bank-a.example",
"sub": "https://api.bank-a.example",
"jwks": { "keys": [ … ] },
"authority_hints": ["https://federation.example"],
"metadata": { "oauth_resource": {
"resource": "https://api.bank-a.example" } }
}
"metadata": { "oauth_resource": {
"authzen_policy_set": { "combining": "deny-overrides",
"members": ["https://pdp.bank-a.example/tenants/bank-a"] },
"scopes_supported": [ … ],
"acr_values_required": ["urn:idp:loa:mfa"]
} },
"metadata_policy": { … }
{
"resource": "https://api.bank-a.example",
"authzen_policy_set": { … },
"scopes_supported": [ … ],
"acr_values_required": ["urn:idp:loa:mfa"],
"signed_metadata": "eyJ…"
}
The gateway resolves its trust chain and republishes the resulting metadata as a signed RFC 9728 document. Clients can read that document through resource discovery. Before federation enrolment, the document is self-asserted and names the configured PDP.
authzen_policy_set can name several PDPs and how their answers combine. Federation policy can pin a set with an organisation-wide PDP first. Each layer must permit the request unless a configured fail-open setting skips an unavailable PDP. A response header identifies skipped layers.The Go service, coaz-pep, provides federation trust-chain resolution and the shared HTTP check API. Kong and PingAccess can perform resource and PDP discovery directly or delegate decisions to that service. The Node.js SDK provides enforcement within an application.
| Component | Enforces requests for | Finds the PDP | Federation | Metadata publication |
|---|---|---|---|---|
coaz-pep (Go) | Envoy, Istio, agentgateway, and the MCP routes of Kong and PingAccess | RFC 9728 and AuthZEN metadata | resolves trust chains to configured anchors | holds the key, republishes the resolved document |
| Kong plugin (Lua) | Kong routes | RFC 9728 and AuthZEN metadata, in Lua | delegated to coaz-pep | relayed from coaz-pep |
| PingAccess rule (Java) | PingAccess applications and resources | RFC 9728 and AuthZEN metadata, in Java | delegated to coaz-pep | relayed from coaz-pep |
| Node SDK (TypeScript) | Express, and MCP servers in process | RFC 9728 and AuthZEN metadata | custom resolver or delegation to coaz-pep | signs and serves its own, self-asserted |
The integrations share evaluation context and challenge conventions. The configuration reference describes each component's discovery support and failure responses.
The demo runs three instances of coaz-pep with different discovery modes. It includes a stub federation, PDPs for two banks, an estate PDP and a rogue one. The console shows the metadata each instance retrieves and the resulting decision.
member. Resource discovery uses the API's published requirements and the PDP permits the request. Federation discovery adds an MFA requirement through metadata policy and the PDP denies it.the gateway's own API and enrol it using the onboarding control. Select Discover again to see the resolved federation metadata.The demo's components and controls are described in the demo reference. The architecture is described in docs/architecture.md.
/.well-known/authzen-configuration./.well-known/oauth-protected-resource, including scopes_supported and signed_metadata. The PDP parameter is this project's own, provisional pending a working-group profile.oauth_resource is the entity type an API resolves as.