# The Cerbos API

The main API endpoint for making policy decisions is the [`/api/check/resources` REST endpoint](https://docs.cerbos.dev/cerbos/latest/api/index.html#check-resources) (`cerbos.svc.v1.CerbosService/CheckResources` RPC in the gRPC API). You can browse a [static version of the Cerbos OpenAPI specification on this site](https://docs.cerbos.dev/cerbos/latest/api/_attachments/cerbos-api). To interactively explore the API, launch a Cerbos instance and access the root directory of the HTTP endpoint using a browser.

```sh
docker run --rm --name cerbos -p 3592:3592 -p 3593:3593 ghcr.io/cerbos/cerbos:0.53.0
```

Navigate to [http://localhost:3592/](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](https://www.postman.com/) or [Insomnia](https://insomnia.rest/) to explore the Cerbos OpenAPI spec available at [http://localhost:3592/schema/swagger.json](http://localhost:3592/schema/swagger.json).

- Using [grpcurl](https://github.com/fullstorydev/grpcurl) or any other tool that supports [gRPC server reflection](https://github.com/grpc/grpc/blob/master/doc/server-reflection.md) API to explore the gRPC API exposed on port 3593.

## Client SDKs

-  [Go](https://pkg.go.dev/github.com/cerbos/cerbos-sdk-go/cerbos)

-  [Java](https://github.com/cerbos/cerbos-sdk-java)

-  [JavaScript](https://github.com/cerbos/cerbos-sdk-javascript)

-  [.NET](https://github.com/cerbos/cerbos-sdk-net)

-  [Laravel](https://github.com/cerbos/cerbos-sdk-laravel)

-  [PHP](https://github.com/cerbos/cerbos-sdk-php)

-  [Python](https://github.com/cerbos/cerbos-sdk-python)

-  [Ruby](https://github.com/cerbos/cerbos-sdk-ruby)

-  [Rust](https://github.com/cerbos/cerbos-sdk-rust)

Other languages coming soon

## 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](https://github.com/orgs/cerbos/repositories?language=&q=demo&sort=&type=all) for the latest list. |

- [Application (Python)](https://github.com/cerbos/demo-python)

- [GraphQL Service (NodeJS)](https://github.com/cerbos/demo-graphql)

- [REST Service (Go)](https://github.com/cerbos/demo-rest)

## Request and response formats

### `CheckResources` (`/api/check/resources`)

This is the main API entrypoint for checking permissions for a set of resources.

Request

```json
{
  "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)
}
```

Response

```json
{
  "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)
}
```

### `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.

Request

```json
{
  "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)
    }
  }
}
```

Response

```json
{
  "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)
}
```

### `ServerInfo` (`/api/server_info`)

Returns Cerbos server version.

Response

```json
{
  "version": "0.25.0",
  "commit": "6b5a051a160398a3c04370f742e6090fab2ed0b8",
  "buildDate": "2023-02-13T09:31:48Z"
}
```

### Request and response formats (AuthZEN Authorization API)

Cerbos partially implements the [OpenID AuthZEN Authorization API specification](https://openid.github.io/authzen/), 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 |
| --- | --- | --- |
| `subject.type` | - | Informational field describing the type of subject |
| `subject.id` | `principal.id` | Unique identifier for the principal |
| `subject.properties.cerbos.roles` | `principal.roles` | Array of role names assigned by the identity provider |
| `subject.properties.cerbos.policyVersion` | `principal.policyVersion` | Policy version to use for the principal |
| `subject.properties.cerbos.scope` | `principal.scope` | Policy scope for the principal |
| `subject.properties.*` | `principal.attr.*` | All other properties become principal attributes |

**Resource → Resource**

| AuthZEN Field | Cerbos Field | Notes |
| --- | --- | --- |
| `resource.type` | `resource.kind` | Type of resource (determines which policy applies) |
| `resource.id` | `resource.id` | Unique identifier for the resource |
| `resource.properties.cerbos.policyVersion` | `resource.policyVersion` | Policy version to use for the resource |
| `resource.properties.cerbos.scope` | `resource.scope` | Policy scope for the resource |
| `resource.properties.*` | `resource.attr.*` | All other properties become resource attributes |

**Action → Actions**

| AuthZEN Field | Cerbos Field | Notes |
| --- | --- | --- |
| `action.name` | `actions[0]` | Action name added as the first item in the actions array |
| `action.properties` | - | Reserved for future use |

**Context**

| AuthZEN Field | Cerbos Field | Notes |
| --- | --- | --- |
| `context.cerbos.requestId` | `requestId` | Application-provided correlation identifier |
| `context.cerbos.auxData` | `auxData` | Auxiliary data such as JWT tokens |
| `context.cerbos.includeMeta` | - | Controls whether full Cerbos response is included in context |

### `Access Evaluation` (`/access/v1/evaluation`)

Evaluates whether a subject can perform a single action on a single resource according to the AuthZEN specification.

Request

```json
{
  "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)
  }
}
```

Response

```json
{
  "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"
    }
  }
}
```

### `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.

Request

```json
{
  "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)
  }
}
```

Response

```json
{
  "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"\
        }\
      }
    }\
  ]
}
```

## Accessing the API

### Using curl to access the REST API

#### Cerbos API Examples

```sh
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:**

```sh
curl --silent "localhost:3592/.well-known/authzen-configuration?pretty"
```

**Access Evaluation (single):**

```sh
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):**

```sh
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

```sh
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](http://localhost:3592/schema/swagger.json). Cerbos gRPC API definitions are published to the [Buf schema registry (BSR)](https://buf.build/cerbos/cerbos-api) and can be easily added to your project if you use the [Buf build system for protobufs](https://docs.buf.build/).

### REST

There are many tools available to generate clients from an OpenAPI specification. [https://openapi.tools/#sdk](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](https://openapi-generator.tech/) has [support for many popular programming languages and frameworks](https://openapi-generator.tech/docs/generators#client-generators). Please consult the documentation to find the client generation instructions for your favourite language. |

This is an example of using the popular [OpenAPI Generator](https://openapi-generator.tech/) service to generate a Java client API.

- Download the Cerbos OpenAPI specification

```sh
curl -Lo swagger.json http://localhost:3592/schema/swagger.json
```

- Run the OpenAPI Generator

```sh
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](https://github.com/cerbos/cerbos/tree/main/api). However, the easiest way to generate client code for your preferred language is to use the [Buf build tool](https://docs.buf.build/) to obtain the published API definitions from the [Buf schema registry (BSR)](https://buf.build/cerbos/cerbos-api).

- Run `buf export buf.build/cerbos/cerbos-api -o proto` to download the API definitions with dependencies to the `proto` directory.

- You can now use [`buf generate`](https://docs.buf.build/generate-usage) or `protoc` to generate code using the protobufs available in the `proto` directory.

|     |     |
| --- | --- |
|  | [BSR generated SDKs](https://buf.build/cerbos/cerbos-api/sdks) feature can be used to download pre-packaged, generated code for supported languages. |

**Go**

The [Cerbos Go SDK](https://pkg.go.dev/github.com/cerbos/cerbos/client) 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.

```sh
go get github.com/cerbos/cerbos/api/genpb
```

You can also make use [Buf generated SDKs](https://buf.build/cerbos/cerbos-api) to pull down the Cerbos gRPC API as a Go module:

```sh
go get buf.build/gen/go/cerbos/cerbos-api/grpc/go@latest
```
