The Cerbos API
| This documentation is for an as-yet unreleased version of Cerbos. Choose 0.48.0 from the version picker at the top right or navigate to https://docs.cerbos.dev for the latest version. |
The main API endpoint for making policy decisions is the /api/check/resources REST endpoint (cerbos.svc.v1.CerbosService/CheckResources RPC in the gRPC API). You can browse a static version of the Cerbos OpenAPI specification on this site. To interactively explore the API, launch a Cerbos instance and access the root directory of the HTTP endpoint using a browser.
docker run --rm --name cerbos -p 3592:3592 -p 3593:3593 ghcr.io/cerbos/cerbos:0.49.0-prerelease
Navigate to http://localhost:3592/ using your browser to explore the Cerbos API documentation.
Alternatively, you can explore the API using the following methods as well:
-
Using an OpenAPI-compatible software like Postman or Insomnia to explore the Cerbos OpenAPI spec available at http://localhost:3592/schema/swagger.json.
-
Using grpcurl or any other tool that supports gRPC server reflection API to explore the gRPC API exposed on port 3593.
Demos
| Demos are constantly being added or updated by the Cerbos team. Visit https://github.com/orgs/cerbos/repositories?language=&q=demo&sort=&type=all for the latest list. |
Request and response formats
CheckResources (/api/check/resources)
This is the main API entrypoint for checking permissions for a set of resources.
{
"requestId": "test", (1)
"principal": {
"id": "alice", (2)
"policyVersion": "20210210", (3)
"scope": "acme.corp", (4)
"roles": [ (5)
"employee"
],
"attr": { (6)
"department": "accounting",
"geography": "GB",
"team": "design"
}
},
"resources": [ (7)
{
"resource": {
"id": "XX125", (8)
"kind": "leave_request", (9)
"policyVersion": "20210210", (10)
"scope": "acme.corp", (11)
"attr": { (12)
"department": "accounting",
"geography": "GB",
"id": "XX125",
"owner": "john",
"team": "design"
}
},
"actions": [ (13)
"view:public",
"approve",
"create"
]
}
],
"auxData": { (14)
"jwt": {
"token": "xxx.yyy.zzz", (15)
"keySetId": "ks1" (16)
}
},
"includeMeta": true (17)
}
| 1 | Request ID is an optional, application-provided identifier useful for correlating logs. |
| 2 | ID of the principal whose permissions are being checked. This usually comes from the identity provider (IdP). |
| 3 | Principal policy version. Optional. The server falls back to the configured default version if this is not specified. |
| 4 | Principal policy scope. Optional. See Scoped policies. |
| 5 | The roles attached to this principal by the identity provider. |
| 6 | Free-form context data about this principal. Policy rule conditions are evaluated based on these values. |
| 7 | List of resources the principal is attempting to access. Up to 50 resources may be provided in a single request by default. This limit can be configured. |
| 8 | ID of the resource. |
| 9 | Resource kind. This is used to determine the resource policy that applies to this resource. |
| 10 | Resource policy version. Optional. The server falls back to the configured default version if this is not specified. |
| 11 | Resource policy scope. Optional. See Scoped policies. |
| 12 | Free-form context data about this resource. Policy rule conditions are evaluated based on these values. |
| 13 | List of actions being performed on the resource. Up to 50 actions per resource may be provided by default. This limit can be configured. |
| 14 | Optional section for providing auxiliary data. |
| 15 | JWT to use as an auxiliary data source. |
| 16 | ID of the keyset to use to verify the JWT. Optional if only a single keyset is configured. |
| 17 | Optional flag to receive metadata about request evaluation. |
{
"requestId": "test", (1)
"results": [ (2)
{
"resource": { (3)
"id": "XX125",
"kind": "leave_request",
"policyVersion": "20210210",
"scope": "acme.corp"
},
"actions": { (4)
"view:public": "EFFECT_ALLOW",
"approve": "EFFECT_DENY"
},
"outputs": [ (5)
{
"src": "resource.leave_request.v20210210/acme#rule-001", (6)
"val": "create_allowed:john" (7)
},
{
"src": "resource.leave_request.v20210210#public-view",
"val": {
"id": "john",
"keys": ["foo", "bar", "baz"]
}
}
],
"validationErrors": [ (8)
{
"path": "/department",
"message": "value must be one of \"marketing\", \"engineering\"",
"source": "SOURCE_PRINCIPAL"
},
{
"path": "/department",
"message": "value must be one of \"marketing\", \"engineering\"",
"source": "SOURCE_RESOURCE"
}
],
"meta": { (9)
"actions": {
"view:public": {
"matchedPolicy": "resource.leave_request.v20210210/acme.corp", (10)
"matchedScope": "acme" (11)
},
"approve": {
"matchedPolicy": "resource.leave_request.v20210210/acme.corp"
}
},
"effectiveDerivedRoles": [ (12)
"employee_that_owns_the_record",
"any_employee"
]
}
}
],
"cerbosCallId": "01HHENANTHFD5DV3HZGDKB87PJ" (13)
}
| 1 | Request ID that was sent with the request. |
| 2 | List of results. Items are in the same order as they were sent in the request. |
| 3 | Resource identifiers. |
| 4 | Access decisions for each of the actions. |
| 5 | List of outputs from policy evaluation, if there are any. See Outputs. |
| 6 | Name of the rule that produced the output. |
| 7 | Output value produced by the rule. |
| 8 | Validation errors, if schema enforcement is enabled and the request didn’t conform to the schema. |
| 9 | Metadata (if includeMeta was true in the request) |
| 10 | Name of the policy that produced the decision for this action. |
| 11 | Name of the scope that was active when the decision was made for the action. |
| 12 | List of derived roles that were activated. |
| 13 | The call ID generated by Cerbos and stored in the audit log for this request. |
PlanResources (/api/plan/resources)
Produces a query plan that can be used to obtain a list of resources that a principal is allowed to perform a particular action on.
{
"requestId": "test01", (1)
"action": "approve", (2)
"actions": ["approve", "view"], (3)
"resource": {
"policyVersion": "dev", (4)
"kind": "leave_request", (5)
"scope": "acme.corp", (6)
"attr": { (7)
"owner": "alicia"
}
},
"principal": {
"id": "alicia", (8)
"policyVersion": "dev", (9)
"scope": "acme.corp", (10)
"roles": ["user"], (11)
"attr": { (12)
"geography": "GB"
}
},
"includeMeta": true, (13)
"auxData": { (14)
"jwt": {
"token": "xxx.yyy.zzz", (15)
"keySetId": "ks-1" (16)
}
}
}
| 1 | Request ID can be anything that uniquely identifies a request. |
| 2 | Action being performed on the resource instances. Either <2> or <3> is required. |
| 3 | Actions being performed on the resource instances. The query plan is the logical AND of individual query plans for each action. Either <2> or <3> is required. |
| 4 | Resource policy version. Optional. The server falls back to the configured default version if this is not specified. |
| 5 | Resource kind. Required. This value is used to determine the resource policy to evaluate. |
| 6 | Resource scope. Optional. See Scoped policies. |
| 7 | Free-form context data about the resources under consideration. The object holds all attributes known about the resource at the time the request. Optional. Policy rule conditions will be (partially) evaluated based on these values. If an effective policy rule condition(s) requires a resource attribute not present in this object, then the response will contain the condition(s) abstract syntax tree. |
| 8 | ID of the principal performing the actions. Required. |
| 9 | Principal policy version. Optional. The server falls back to the configured default version if this is not specified. |
| 10 | Principal scope. Optional. See Scoped policies. |
| 11 | Static roles that are assigned to this principal by your identity management system. Required. |
| 12 | Free-form context data about this principal. Policy rule conditions are evaluated based on these values. |
| 13 | An optional flag to signal that the response should include metadata about evaluation. Useful for debugging. |
| 14 | Optional section for providing auxiliary data. |
| 15 | JWT to use as an auxiliary data source. |
| 16 | ID of the keyset to use to verify the JWT. Optional if only a single keyset is configured. |
{
"requestId": "test01",
"action": "approve",
"resourceKind": "leave_request",
"policyVersion": "dev",
"filter": {
"kind": "KIND_CONDITIONAL", (1)
"condition": { (2)
"expression": {
"operator": "eq",
"operands": [
{ "variable": "request.resource.attr.status" },
{ "value": "PENDING_APPROVAL" }
]
}
}
},
"meta": {
"filterDebug": "(request.resource.attr.status == \"PENDING_APPROVAL\")" (3)
},
"cerbosCallId": "01HHENANTHFD5DV3HZGDKB87PJ" (4)
}
| 1 | Filter kind can be KIND_ALWAYS_ALLOWED, KIND_ALWAYS_DENIED or KIND_CONDITIONAL. See below for description of what these values mean. |
| 2 | Populated only if kind is KIND_CONDITIONAL. Contains the abstract syntax tree (AST) of the condition that must be satisfied to allow the action. |
| 3 | Condition AST represented as a human readable string. Useful for debugging. |
| 4 | The call ID generated by Cerbos and stored in the audit log for this request. |
Structure of the filter block
The kind field defines the filter kind.
KIND_ALWAYS_ALLOWED-
The principal is unconditionally allowed to perform the action
KIND_ALWAYS_DENIED-
The principal is unconditionally not permitted to perfrom the action
KIND_CONDITIONAL-
The principal is allowed to perform the action if the condition is satisfied
The condition field holds the AST of the condition that must be satisfied. It is rooted in an expression that has an operator (e.g. equals, greater than) and operands (e.g. a constant value, a variable or another expression).
| Operator | Description |
|---|---|
|
Addition (+) |
|
Logical AND (&&) |
|
Division (/) |
|
Equality (==) |
|
Greater than or equal (>=) |
|
Greater than (>) |
|
List membership (in) |
|
Array or map index |
|
Anonymous function |
|
Less than or equal (⇐) |
|
List constructor |
|
Less than (<) |
|
Modulo (%) |
|
Multiplication (*) |
|
Not equal (!=) |
|
Logical NOT |
|
Logical OR |
|
Subtract (-) |
request.resource.attr.status == "PENDING_APPROVAL"{
"expression": {
"operator": "eq",
"operands": [
{
"variable": "request.resource.attr.status"
},
{
"value": "PENDING_APPROVAL"
}
]
}
}
(request.resource.attr.department == "marketing") && (request.resource.attr.team != "design"){
"expression": {
"operator": "and",
"operands": [
{
"expression": {
"operator": "eq",
"operands": [
{
"variable": "request.resource.attr.department"
},
{
"value": "marketing"
}
]
}
},
{
"expression": {
"operator": "ne",
"operands": [
{
"variable": "request.resource.attr.team"
},
{
"value": "design"
}
]
}
}
]
}
}
request.resource.attr.values.filter(t, t > 0){
"expression": {
"operator": "filter",
"operands": [
{
"variable": "request.resource.attr.values"
},
{
"expression": {
"operator": "lambda",
"operands": [
{
"variable": "t"
},
{
"expression": {
"operator": "gt",
"operands": [
{
"variable": "t"
},
{
"value": 0
}
]
}
}
]
}
}
]
}
}
Request and response formats (AuthZEN Authorization API)
Cerbos partially implements the OpenID AuthZEN Authorization API specification, providing a standardized way to make authorization decisions. The AuthZEN API uses a simplified entity model that maps to Cerbos’s native authorization model.
AuthZEN entity model mapping
The AuthZEN specification uses a simplified entity model with three core entities:
-
Subject: The principal requesting access (maps to Cerbos
principal) -
Resource: The target of the access request (maps to Cerbos
resource) -
Action: The operation being performed (maps to Cerbos
actions)
Mapping AuthZEN to Cerbos
AuthZEN entities are mapped to Cerbos CheckResources requests as follows:
Subject → Principal
| AuthZEN Field | Cerbos Field | Notes |
|---|---|---|
|
- |
Informational field describing the type of subject |
|
|
Unique identifier for the principal |
|
|
Array of role names assigned by the identity provider |
|
|
Policy version to use for the principal |
|
|
Policy scope for the principal |
|
|
All other properties become principal attributes |
Resource → Resource
| AuthZEN Field | Cerbos Field | Notes |
|---|---|---|
|
|
Type of resource (determines which policy applies) |
|
|
Unique identifier for the resource |
|
|
Policy version to use for the resource |
|
|
Policy scope for the resource |
|
|
All other properties become resource attributes |
Action → Actions
| AuthZEN Field | Cerbos Field | Notes |
|---|---|---|
|
|
Action name added as the first item in the actions array |
|
- |
Reserved for future use |
Context
| AuthZEN Field | Cerbos Field | Notes |
|---|---|---|
|
|
Application-provided correlation identifier |
|
|
Auxiliary data such as JWT tokens |
|
- |
Controls whether full Cerbos response is included in context |
Metadata (/.well-known/authzen-configuration)
Returns metadata about the Cerbos Policy Decision Point, including endpoint URLs for accessing the AuthZEN APIs.
This endpoint accepts GET requests with no body.
{
"policy_decision_point": "https://localhost:3592", (1)
"access_evaluation_endpoint": "https://localhost:3592/access/v1/evaluation", (2)
"access_evaluations_endpoint": "https://localhost:3592/access/v1/evaluations" (3)
}
| 1 | Base URL of the Policy Decision Point |
| 2 | Full URL for single access evaluation request |
| 3 | Full URL for multiple access evaluation requests |
Access Evaluation (/access/v1/evaluation)
Evaluates whether a subject can perform a single action on a single resource according to the AuthZEN specification.
{
"subject": { (1)
"type": "user", (2)
"id": "donald_duck", (3)
"properties": { (4)
"cerbos.policyVersion": "20210210",
"cerbos.roles": ["employee"],
"department": "marketing",
"geography": "GB",
"team": "design"
}
},
"resource": { (5)
"type": "leave_request", (6)
"id": "XX125", (7)
"properties": { (8)
"cerbos.policyVersion": "20210210",
"department": "marketing",
"geography": "GB",
"owner": "john",
"team": "design"
}
},
"action": { (9)
"name": "view:public", (10)
"properties": {} (11)
},
"context": { (12)
"cerbos.requestId": "test",
"cerbos.auxData": { (13)
"jwt": {
"token": "xxx.yyy.zzz"
}
},
"cerbos.includeMeta": true (14)
}
}
| 1 | Subject requesting access (maps to Cerbos principal) |
| 2 | Type of the subject (informational field) |
| 3 | Unique identifier for the subject |
| 4 | Properties about the subject. Special cerbos.* properties are mapped to Cerbos-specific fields, others become attributes |
| 5 | Resource being accessed (maps to Cerbos resource) |
| 6 | Type of the resource (maps to Cerbos resource.kind) |
| 7 | Unique identifier for the resource |
| 8 | Properties about the resource. Special cerbos.* properties are mapped to Cerbos-specific fields, others become attributes |
| 9 | Action being performed |
| 10 | Name of the action to check |
| 11 | Optional properties about the action (currently unused) |
| 12 | Environmental/contextual data |
| 13 | Auxiliary data such as JWT tokens. See CheckResources (/api/check/resources) for details |
| 14 | Include metadata about evaluation in the response (Cerbos extension) |
{
"decision": true, (1)
"context": { (2)
"cerbos.response": { (3)
"requestId": "test",
"results": [
{
"resource": {
"id": "XX125",
"kind": "leave_request",
"policyVersion": "20210210"
},
"actions": {
"view:public": "EFFECT_ALLOW"
},
"meta": {
"actions": {
"view:public": {
"matchedPolicy": "resource.leave_request.v20210210"
}
},
"effectiveDerivedRoles": [
"employee_that_owns_the_record"
]
}
}
],
"cerbosCallId": "01HHENANTHFD5DV3HZGDKB87PJ"
}
}
}
| 1 | Boolean decision: true for allow, false for deny |
| 2 | Additional context about the evaluation |
| 3 | Full Cerbos CheckResources response (included when cerbos.includeMeta is true). See CheckResources (/api/check/resources) for response structure details |
Access Evaluations (/access/v1/evaluations)
Evaluates multiple access requests in a single call. This endpoint supports default values that can be overridden for individual evaluations, and evaluation semantics that control execution behavior.
{
"subject": { (1)
"type": "user",
"id": "donald_duck",
"properties": {
"cerbos.policyVersion": "20210210",
"cerbos.roles": ["employee"],
"department": "marketing",
"geography": "GB",
"team": "design"
}
},
"resource": { (2)
"type": "leave_request",
"id": "XX125",
"properties": {
"cerbos.policyVersion": "20210210",
"department": "marketing",
"geography": "GB",
"owner": "john",
"team": "design"
}
},
"context": { (3)
"cerbos.requestId": "test",
"cerbos.includeMeta": true
},
"evaluations": [ (4)
{
"action": { (5)
"name": "view:public",
"properties": {}
}
},
{
"action": {
"name": "approve",
"properties": {}
}
},
{
"resource": { (6)
"type": "leave_request",
"id": "XX150",
"properties": {
"cerbos.policyVersion": "20210210",
"department": "marketing",
"geography": "GB",
"owner": "mary",
"team": "design"
}
},
"action": {
"name": "create",
"properties": {}
}
}
],
"options": { (7)
"evaluations_semantic": "execute_all" (8)
}
}
| 1 | Default subject for all evaluations (can be overridden in individual evaluations) |
| 2 | Default resource for all evaluations (can be overridden in individual evaluations) |
| 3 | Default context for all evaluations (can be overridden in individual evaluations) |
| 4 | Array of evaluations to perform. Each can override the default subject, resource, action, or context |
| 5 | Evaluation using default subject and resource, specifying only the action |
| 6 | Evaluation overriding the default resource while using the default subject |
| 7 | Optional execution controls |
| 8 | Evaluation semantic: execute_all (default), deny_on_first_deny, or permit_on_first_permit |
Evaluation Semantics:
execute_all(default)-
Process all evaluations regardless of individual results
deny_on_first_deny-
Stop processing after the first denial
permit_on_first_permit-
Stop processing after the first permit
{
"evaluations": [ (1)
{
"decision": true, (2)
"context": {
"cerbos.response": { (3)
"requestId": "test",
"results": [
{
"resource": {
"id": "XX125",
"kind": "leave_request",
"policyVersion": "20210210"
},
"actions": {
"view:public": "EFFECT_ALLOW"
},
"meta": {
"actions": {
"view:public": {
"matchedPolicy": "resource.leave_request.v20210210"
}
}
}
}
],
"cerbosCallId": "01HHENANTHFD5DV3HZGDKB87PJ"
}
}
},
{
"decision": false,
"context": {
"cerbos.response": {
"requestId": "test",
"results": [
{
"resource": {
"id": "XX125",
"kind": "leave_request",
"policyVersion": "20210210"
},
"actions": {
"approve": "EFFECT_DENY"
}
}
],
"cerbosCallId": "01HHENANTHFD5DV3HZGDKB87PJ"
}
}
},
{
"decision": false,
"context": {
"cerbos.response": {
"requestId": "test",
"results": [
{
"resource": {
"id": "XX150",
"kind": "leave_request",
"policyVersion": "20210210"
},
"actions": {
"create": "EFFECT_DENY"
}
}
],
"cerbosCallId": "01HHENANTHFD5DV3HZGDKB87PJ"
}
}
}
]
}
| 1 | Array of evaluation responses, in the same order as the request |
| 2 | Boolean decision for this evaluation |
| 3 | Full Cerbos CheckResources response for this evaluation (included when cerbos.includeMeta is true) |
Accessing the API
Using curl to access the REST API
Cerbos API Examples
cat <<EOF | curl --silent "localhost:3592/api/check/resources?pretty" -d @-
{
"requestId": "test",
"principal": {
"id": "alice",
"roles": ["employee"],
"attr": {
"department": "accounting",
"geography": "GB",
"team": "design"
}
},
"resources": [
{
"resource": {
"id": "XX125",
"kind": "leave_request",
"attr": {
"department": "accounting",
"geography": "GB",
"id": "XX125",
"owner": "john",
"team": "design"
}
},
"actions": [
"view:public",
"approve",
"create"
]
}
]
}
EOF
AuthZEN API Examples
Metadata endpoint:
curl --silent "localhost:3592/.well-known/authzen-configuration?pretty"
Access Evaluation (single):
cat <<EOF | curl --silent "localhost:3592/access/v1/evaluation?pretty" -d @-
{
"subject": {
"type": "user",
"id": "alice",
"properties": {
"cerbos.roles": ["employee"],
"department": "accounting",
"geography": "GB",
"team": "design"
}
},
"resource": {
"type": "leave_request",
"id": "XX125",
"properties": {
"department": "accounting",
"geography": "GB",
"owner": "john",
"team": "design"
}
},
"action": {
"name": "view:public",
"properties": {}
},
"context": {
"cerbos.requestId": "test",
"cerbos.includeMeta": true
}
}
EOF
Access Evaluations (batch):
cat <<EOF | curl --silent "localhost:3592/access/v1/evaluations?pretty" -d @-
{
"subject": {
"type": "user",
"id": "alice",
"properties": {
"cerbos.roles": ["employee"],
"department": "accounting",
"geography": "GB",
"team": "design"
}
},
"resource": {
"type": "leave_request",
"id": "XX125",
"properties": {
"department": "accounting",
"geography": "GB",
"owner": "john",
"team": "design"
}
},
"context": {
"cerbos.requestId": "test",
"cerbos.includeMeta": true
},
"evaluations": [
{
"action": {
"name": "view:public",
"properties": {}
}
},
{
"action": {
"name": "approve",
"properties": {}
}
},
{
"action": {
"name": "create",
"properties": {}
}
}
]
}
EOF
Using grpcurl to access the gRPC API
cat <<EOF | grpcurl -plaintext -d @ localhost:3593 cerbos.svc.v1.CerbosService/CheckResources
{
"requestId": "test",
"principal": {
"id": "alice",
"roles": ["employee"],
"attr": {
"department": "accounting",
"geography": "GB",
"team": "design"
}
},
"resources": [
{
"resource": {
"id": "XX125",
"kind": "leave_request",
"attr": {
"department": "accounting",
"geography": "GB",
"id": "XX125",
"owner": "john",
"team": "design"
}
},
"actions": [
"view:public",
"approve",
"create"
]
}
]
}
EOF
Generating API clients
The Cerbos OpenAPI specification can be obtained from a running Cerbos instance by accessing http://localhost:3592/schema/swagger.json. Cerbos gRPC API definitions are published to the Buf schema registry (BSR) and can be easily added to your project if you use the Buf build system for protobufs.
REST
There are many tools available to generate clients from an OpenAPI specification. https://openapi.tools/#sdk is a good resource for finding a tool suitable for your preferred language.
Example: Generating a Java client using OpenAPI Generator
| OpenAPI Generator has support for many popular programming languages and frameworks. Please consult the documentation to find the client generation instructions for your favourite language. |
This is an example of using the popular OpenAPI Generator service to generate a Java client API.
-
Download the Cerbos OpenAPI specification
curl -Lo swagger.json http://localhost:3592/schema/swagger.json -
Run the OpenAPI Generator
docker run --rm -v $(pwd):/oas openapitools/openapi-generator-cli generate -i /oas/swagger.json -g java -o /oas/java
gRPC
Any language
You can access the Cerbos protobuf definitions from the Cerbos source tree. However, the easiest way to generate client code for your preferred language is to use the Buf build tool to obtain the published API definitions from the Buf schema registry (BSR).
-
Run
buf export buf.build/cerbos/cerbos-api -o prototo download the API definitions with dependencies to theprotodirectory. -
You can now use
buf generateorprotocto generate code using the protobufs available in theprotodirectory.
| BSR generated SDKs feature can be used to download pre-packaged, generated code for supported languages. |
Go
The Cerbos Go SDK uses the gRPC API to communicate with Cerbos. The generated gRPC and protobuf code is available under the github.com/cerbos/cerbos/api/genpb package.
go get github.com/cerbos/cerbos/api/genpb
You can also make use Buf generated SDKs to pull down the Cerbos gRPC API as a Go module:
go get buf.build/gen/go/cerbos/cerbos-api/grpc/go@latest