bin/kc.[sh|bat] start --features=authzen
| This feature is experimental and may introduce breaking changes in future versions of Keycloak. Do not use this feature in production environments. |
The OpenID AuthZEN Authorization API 1.0 defines a standard protocol for communication between Policy Decision Points (PDPs) and Policy Enforcement Points (PEPs), enabling applications to request authorization decisions without being tightly coupled to the internal details of the authorization engine.
Keycloak is an AuthZEN compatible PDP that implements the Evaluation and Evaluations APIs.
AuthZEN is an experimental feature and must be explicitly enabled when starting Keycloak:
bin/kc.[sh|bat] start --features=authzen
AuthZEN exposes Keycloak’s existing authorization services. Before using AuthZEN, you must configure the following in your realm:
A client with authorization enabled-- The client whose access token is used to authenticate AuthZEN requests must have Authorization Enabled in its settings.
Resources — Define resources in the client’s Authorization → Resources section. The resource name maps to the resource.id in AuthZEN requests, and the resource type maps to resource.type.
Scopes — Define scopes in the client’s Authorization → Scopes section. Scope names map to the action.name in AuthZEN requests.
Policies and Permissions — Create policies and permissions that associate resources and scopes with authorization decisions.
When AuthZEN is enabled, Keycloak exposes a .well-known endpoint that allows PEPs to discover the available AuthZEN endpoints:
GET /realms/{realm}/.well-known/authzen-configuration
For example, a realm called myrealm will return the following metadata:
{
"policy_decision_point": "https://keycloak.example.com/realms/myrealm",
"access_evaluation_endpoint": "https://keycloak.example.com/realms/myrealm/authzen/access/v1/evaluation",
"access_evaluations_endpoint": "https://keycloak.example.com/realms/myrealm/authzen/access/v1/evaluations"
}
All AuthZEN endpoints require a valid bearer token in the Authorization header and the token must be issued for a
client that has authorization services enabled.
POST /realms/{realm}/authzen/access/v1/evaluation
Authorization: Bearer <access-token>
Content-Type: application/json
If no valid token is provided, the server returns a 401 Unauthorized response.
The Evaluation API is the core AuthZEN endpoint. It accepts a single authorization request and returns a boolean decision.
An evaluation request has three required fields and one optional field:
| Field | Required | Description |
|---|---|---|
|
Yes |
The entity requesting access. Contains |
|
Yes |
The resource being accessed. Contains |
|
Yes |
The action being performed. Contains |
|
No |
Additional context for policy evaluation as a map of key-value pairs. |
The subject object identifies who is requesting access:
| Field | Required | Description |
|---|---|---|
|
Yes |
Either |
|
Yes |
Identifies the subject. |
|
No |
Additional attributes to include in the evaluation context. |
The resource object identifies what is being accessed:
| Field | Required | Description |
|---|---|---|
|
Yes |
Must match the resource type configured in Keycloak’s authorization settings. |
|
Yes |
Must match the resource name configured in Keycloak’s authorization settings. |
|
No |
Additional attributes included in the evaluation context. |
{
"subject": {
"type": "user",
"id": "alice"
},
"resource": {
"type": "document",
"id": "quarterly-report"
},
"action": {
"name": "read"
}
}
The response contains a boolean decision field:
{
"decision": true
}
A decision of true means the subject is permitted to perform the action on the resource. A decision of false means the request is denied.
The response may also include a context map with additional information about the decision.
The Evaluations API allows PEPs to batch multiple authorization queries into a single request.
An Evaluations request supports top-level default values for subject, resource, action, and context.
Individual evaluation items in the evaluations array will override any of the specified defaults.
| Field | Required | Description |
|---|---|---|
|
No |
Default subject applied to evaluation items that do not specify their own. |
|
No |
Default resource applied to evaluation items that do not specify their own. |
|
No |
Default action applied to evaluation items that do not specify their own. |
|
No |
Default context applied to evaluation items that do not specify their own. |
|
No |
Controls evaluation semantics (see Evaluation semantics). |
|
No |
Array of individual evaluation items. If absent or empty, the request behaves as a single evaluation using the top-level fields. |
{
"subject": {
"type": "user",
"id": "alice"
},
"action": {
"name": "read"
},
"evaluations": [
{
"resource": {
"type": "document",
"id": "quarterly-report"
}
},
{
"resource": {
"type": "document",
"id": "annual-report"
}
},
{
"resource": {
"type": "image",
"id": "logo"
},
"action": {
"name": "write"
}
}
]
}
In this example, the first two items inherit the top-level subject and action. The third item inherits the subject but overrides the action.
The response contains an evaluations array with one decision per item, in the same order as the request:
{
"evaluations": [
{ "decision": true },
{ "decision": true },
{ "decision": false }
]
}
The options.evaluations_semantic field controls how Keycloak processes the batch. Three semantics are supported:
| Semantic | Behavior |
|---|---|
|
Evaluates all items and returns all decisions. This is the default. |
|
Stops processing on the first denied item. The response includes decisions up to and including the denial, with a
|
|
Stops processing on the first permitted item. The response includes decisions up to and including the permit. |
The example request below shows the expected response when deny_on_first_deny semantics are requested.
{
"subject": {
"type": "user",
"id": "alice"
},
"options": {
"evaluations_semantic": "deny_on_first_deny"
},
"evaluations": [
{
"resource": { "type": "document", "id": "public-doc" },
"action": { "name": "read" }
},
{
"resource": { "type": "document", "id": "restricted-doc" },
"action": { "name": "read" }
}
]
}
If the second item is denied, the response stops there:
{
"evaluations": [
{ "decision": true },
{ "decision": false, "context": { "reason": "deny_on_first_deny" } }
]
}
The subject.type can be one of two types:
user: Query if the specified user is authorized to perform an action on a resource
client: Query if the specified client is authorized to perform an action on a resource
If a subject.id does not resolve to an existing user or client, the evaluation returns {"decision": false} with an
HTTP 200 OK status.
When the subject.type is user, Keycloak supports several strategies for resolving the user identity from the
subject.id field.
When no namespace prefix is present, Keycloak defaults to the following lookup strategy:
If the subject.id value is a valid UUID, lookup up by Keycloak internal user ID.
Otherwise, attempt to lookup a user with the subject.id username.
Use a namespace prefix to explicitly specify the lookup strategy:
| Prefix | Lookup | Example |
|---|---|---|
|
By Keycloak internal user ID (UUID) |
|
|
By username |
|
|
By email address |
|
The email: namespace cannot be used when the realm is configured to allow duplicate emails as the lookup would
not be unique. Using the email: namespace with duplicate emails results in a 400 Bad Request response.
|
AuthZEN endpoints return standard HTTP error codes for invalid requests:
| Status Code | Condition |
|---|---|
|
The request body is missing a required field ( |
|
The request does not include a valid bearer token in the |
As recommended by the AuthZEN specification, Keycloak propagates the X-Request-ID header from requests to responses.
If a PEP includes an X-Request-ID header in its request, the same header and value will appear in the response.
This applies to all response status codes, including error responses.
POST /realms/myrealm/authzen/access/v1/evaluation
Authorization: Bearer <access-token>
Content-Type: application/json
X-Request-ID: req-abc-123
{
"subject": { "type": "user", "id": "alice" },
"resource": { "type": "document", "id": "report" },
"action": { "name": "read" }
}
The response includes the same header:
HTTP/1.1 200 OK
X-Request-ID: req-abc-123
Content-Type: application/json
{ "decision": true }
Both the resource.properties and the top-level context maps are merged into the evaluation context available to
Keycloak’s authorization policies. This allows policies to make decisions based on additional attributes beyond
the resource, scope, and subject identity.
For example, a policy could use the request context to enforce time-based or location-based access:
{
"subject": { "type": "user", "id": "alice" },
"resource": {
"type": "document",
"id": "quarterly-report",
"properties": {
"classification": "confidential"
}
},
"action": { "name": "read" },
"context": {
"ip_address": "192.168.1.100"
}
}
Subject properties specified in subject.properties are also merged into the subject’s identity attributes for policy evaluation.