Calling Cerbos

The policies for this section can be found on GitHub.

Now that you know the policies are valid, it is time to make your first call to Cerbos to make an authorization check.

Starting Cerbos

To start you need to launch the server:

# Using Container
docker run --rm --name cerbos -t \
  -v /tutorial:/tutorial \
  -p 3592:3592 ghcr.io/cerbos/cerbos:latest server --config=/tutorial/.cerbos.yaml

# Using Binary
./cerbos server --config=/tutorial/.cerbos.yaml

Once Cerbos has started up you should see an output confirming that there are 3 policies loaded and ready to start processing authorization checks:

2024-12-28T13:55:57.043+0600    INFO    cerbos.server   maxprocs: Leaving GOMAXPROCS=8: CPU quota undefined
2024-12-28T13:55:57.044+0600    INFO    cerbos.server   Loading configuration from .cerbos.yaml
2024-12-28T13:55:57.045+0600    WARN    cerbos.otel     Disabling OTLP traces because neither OTEL_EXPORTER_OTLP_ENDPOINT nor OTEL_EXPORTER_OTLP_TRACES_ENDPOINT is defined
2024-12-28T13:55:57.046+0600    INFO    cerbos.disk.store       Initializing disk store from /Users/username/tutorial/policies
2024-12-28T13:55:57.048+0600    INFO    cerbos.index    Found 3 executable policies
2024-12-28T13:55:57.048+0600    INFO    cerbos.telemetry        Telemetry disabled
2024-12-28T13:55:57.048+0600    INFO    cerbos.grpc     Starting gRPC server at :3593
2024-12-28T13:55:57.050+0600    INFO    cerbos.http     Starting HTTP server at :3592

At this point how you make a request to the Cerbos instance is down to your preference - a simple cURL command or using a GUI such as Postman also works.

Cerbos check call

A call to Cerbos contains 3 key bits of information:

  1. The Principal - who is making the request

  2. The Resources - a map of entities of a resource kind that are they requesting access too

  3. The Actions - what actions are they trying to perform on the entities

The request payload to the /api/check/resources endpoint takes these 3 bits of information as JSON:

{
  "principal": {
    "id": "user_1",     // the user ID
    "roles": ["user"],  // list of roles from user's profile
    "attr": {}          // a map of attributes about the user - not used yet
  },
  "resources": [        // an array of resources being accessed
    {
      "actions": ["read"],  // the list of actions to be performed on the resource
      "resource": {         // details about the resource
        "kind": "contact",  // the type of the resource
        "id": "contact_1",  // the ID of the specific resource instance
        "attr": {}          // a map of attributes about the resource - not used yet
      }
    }
  ]
}

To make the actual call as a cURL with the default server config:

curl --location --request POST 'http://localhost:3592/api/check/resources' \
    --header 'Content-Type: application/json' \
    --data-raw '{
      "principal": {
        "id": "user_1",
        "roles": ["user"],
        "attr": {}
      },
      "resources": [
          {
              "actions": ["read"],
              "resource": {
                  "kind": "contact",
                  "id": "contact_1",
                  "attr": {}
              }
          }
      ]
    }'

The response object looks as follows where for each instance of the resource the authorization decision for each action is either EFFECT_ALLOW or EFFECT_DENY depending on the policies:

{
    "results": [
        {
            "resource": {
                "id": "contact_1",
                "kind": "contact"
            },
            "actions": {
                "read": "EFFECT_ALLOW"
            }
        }
    ],
    "cerbosCallId": "49KQ6456PRBLWYMXYDBKZM1F6H"
}

You can find the Swagger definition of the Cerbos API via going to the root of the Cerbos instance - for example http://localhost:3592 if running on the default port.

Conclusion

Now that you have made the first call to Cerbos you can move on to a way of checking policy logic without having to make individual calls each time by writing unit tests.