Cerbos Python SDK
The Cerbos Python SDK (current version 0.15.1) provides a client library for interacting with the Cerbos Policy Decision Point (PDP). It enables Python applications to perform authorization checks, manage policies, and integrate with the open-core Cerbos authorization solution. Releases generally follow the main Cerbos project, with independent patch versions for the SDK.
Common errors
-
ModuleNotFoundError: No module named 'cerbos.sdk'
cause The `cerbos` library is not installed or the Python environment is incorrect.fixEnsure `cerbos` is installed in your active Python environment: `pip install cerbos`. -
grpc.aio._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with: status = StatusCode.UNAVAILABLE, details = "Connect Failed", debug_error_string = "{"created":"@1678881234.567890","description":"Failed to connect to remote host: Connection refused","file":"src/core/lib/transport/error_utils.cc","file_line":166,"grpc_status":14}">cause The Cerbos Policy Decision Point (PDP) server is not running or is inaccessible at the configured address and port.fixStart your Cerbos PDP server. Verify that the `CERBOS_PDP_ADDR` environment variable or the address passed to `CerbosClient` (default `localhost:3593`) matches the PDP's listening address. Check firewall settings. -
grpc.aio._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with: status = StatusCode.FAILED_PRECONDITION, details = "policy compilation failed: ...", debug_error_string = "...">
cause The Cerbos PDP encountered an error during policy evaluation, typically due to malformed policies, invalid schema definitions, or issues with the request structure that violate policy constraints.fixExamine the `details` field in the error message for specific policy compilation failures. Review your Cerbos policies (`.yaml` files) and schema definitions. Ensure your `Principal` and `Resource` inputs conform to any defined schemas. -
AttributeError: 'dict' object has no attribute 'with_attributes'
cause You are attempting to use a method like `with_attributes()` (which belongs to `cerbos.sdk.model.Principal` or `Resource` objects) on a plain Python dictionary.fixAlways instantiate `Principal` and `Resource` objects from `cerbos.sdk.model` when you intend to use their object-oriented methods. For example: `principal = Principal(id='user').with_attributes(...)`.
Warnings
- gotcha The default `CerbosClient` is synchronous. For applications requiring non-blocking I/O (e.g., FastAPI, Sanic, Django with async views), you must explicitly use `AsyncCerbosClient` and `await` its methods.
- gotcha While `is_allowed` generally accepts plain dictionaries for principal and resource inputs, using `cerbos.sdk.model.Principal` and `cerbos.sdk.model.Resource` objects is recommended. These objects provide type-safety, better validation, and expose helpful methods (e.g., `with_attributes`).
- gotcha The `is_allowed` method is for checking a single action on a single resource. For performing multiple checks efficiently in a single round trip to the Cerbos PDP, use the `check` method (which takes a list of `CheckInput` objects) or `plan_resources` for resource-based access decisions.
- gotcha Connecting to the Cerbos PDP requires the server to be running and accessible at the specified address. Network issues or an inactive PDP will result in connection errors.
Install
-
pip install cerbos
Imports
- CerbosClient
from cerbos.sdk.client import CerbosClient
- AsyncCerbosClient
from cerbos.sdk.client import AsyncCerbosClient
- Principal
from cerbos.sdk.model import Principal
- Resource
from cerbos.sdk.model import Resource
- Attribute
from cerbos.sdk.model import Attribute
Quickstart
from cerbos.sdk.client import CerbosClient
from cerbos.sdk.model import Principal, Resource
import os
# Configure Cerbos PDP address (e.g., local server or Cerbos Cloud)
# For local development, Cerbos usually runs on localhost:3593
CERBOS_PDP_ADDR = os.environ.get('CERBOS_PDP_ADDR', 'localhost:3593')
def run_check():
client = CerbosClient(CERBOS_PDP_ADDR)
# Define the principal (user) making the request
principal = Principal(
id="john.doe",
roles=["employee"],
attributes={
"department": "marketing",
"geography": "EU"
}
)
# Define the resource being accessed
resource = Resource(
id="leave_request_123",
kind="leave_request",
attributes={
"owner": "john.doe",
"status": "pending",
"geography": "EU"
}
)
# Perform an authorization check
if client.is_allowed("view", principal, resource):
print(f"Principal '{principal.id}' IS ALLOWED to 'view' resource '{resource.id}'.")
else:
print(f"Principal '{principal.id}' IS NOT ALLOWED to 'view' resource '{resource.id}'.")
# Example of a batch check
# You can also use client.check(inputs) for multiple checks at once
check_result = client.check(
inputs=[
client.check_input("view", principal, resource),
client.check_input("edit", principal, resource)
]
)
print(f"\nBatch check results: {check_result.resource_instances['leave_request_123'].actions}")
if __name__ == '__main__':
print(f"Attempting to connect to Cerbos PDP at: {CERBOS_PDP_ADDR}")
try:
run_check()
except Exception as e:
print(f"An error occurred. Is the Cerbos PDP running at {CERBOS_PDP_ADDR}? Error: {e}")