What You’ll Build
In this quickstart, you’ll:
- Start a Cerbos PDP instance
- Make an authorization check (it will fail - no policies yet!)
- Create policies for an album-sharing application
- See authorization decisions change as you add rules
By the end, you’ll understand how Cerbos evaluates policies and makes authorization decisions.
Step 1: Start Cerbos
Create a directory for your policies and start Cerbos:
# Create policy directory
mkdir -p cerbos-quickstart/policies
# Start Cerbos PDP
docker run --rm --name cerbos -d \
-v $(pwd)/cerbos-quickstart/policies:/policies \
-p 3592:3592 \
-p 3593:3593 \
ghcr.io/cerbos/cerbos:latest
API Browser: Open http://localhost:3592 in your browser to explore the Cerbos API with built-in documentation.
Step 2: Try an Authorization Check
Let’s check if bugs_bunny can view and comment on album resources:
cat <<EOF | curl --silent "http://localhost:3592/api/check/resources?pretty" -d @-
{
"requestId": "quickstart",
"principal": {
"id": "bugs_bunny",
"roles": ["user"],
"attr": {
"beta_tester": true
}
},
"resources": [
{
"actions": ["view:public", "comment"],
"resource": {
"kind": "album:object",
"id": "BUGS001",
"attr": {
"owner": "bugs_bunny",
"public": false,
"flagged": false
}
}
},
{
"actions": ["view:public", "comment"],
"resource": {
"kind": "album:object",
"id": "DAFFY002",
"attr": {
"owner": "daffy_duck",
"public": true,
"flagged": false
}
}
}
]
}
EOF
Response: Everything Denied
{
"requestId": "quickstart",
"results": [
{
"resource": {
"id": "BUGS001",
"kind": "album:object"
},
"actions": {
"comment": "EFFECT_DENY",
"view:public": "EFFECT_DENY"
}
},
{
"resource": {
"id": "DAFFY002",
"kind": "album:object"
},
"actions": {
"comment": "EFFECT_DENY",
"view:public": "EFFECT_DENY"
}
}
]
}
Bugs Bunny is denied access to everything - even his own album! This is because there are no policies defined yet. Cerbos denies by default.
Step 3: Create Derived Roles
Let’s define a derived role that assigns the owner role when a user owns a resource:
Create derived_roles_common.yaml
cat > cerbos-quickstart/policies/derived_roles_common.yaml <<EOF
---
apiVersion: "api.cerbos.dev/v1"
derivedRoles:
name: common_roles
definitions:
- name: owner
parentRoles: ["user"]
condition:
match:
expr: request.resource.attr.owner == request.principal.id
EOF
Derived Roles dynamically assign roles based on conditions. Here, users with the user role get the owner derived role when they own the resource.
Step 4: Create a Resource Policy
Now create a policy that gives owners full access to their albums:
Create resource_album.yaml
cat > cerbos-quickstart/policies/resource_album.yaml <<EOF
---
apiVersion: api.cerbos.dev/v1
resourcePolicy:
version: "default"
importDerivedRoles:
- common_roles
resource: "album:object"
rules:
- actions: ['*']
effect: EFFECT_ALLOW
derivedRoles:
- owner
EOF
Cerbos automatically detects the new policy files. Try the request again!
Response: Owner Access Granted
{
"requestId": "quickstart",
"results": [
{
"resource": {
"id": "BUGS001",
"kind": "album:object"
},
"actions": {
"comment": "EFFECT_ALLOW",
"view:public": "EFFECT_ALLOW"
}
},
{
"resource": {
"id": "DAFFY002",
"kind": "album:object"
},
"actions": {
"comment": "EFFECT_DENY",
"view:public": "EFFECT_DENY"
}
}
]
}
Success! Bugs Bunny can now access his own album (BUGS001) but not Daffy’s album (DAFFY002).
Step 5: Add Conditional Access
Let’s allow all users to view public albums by adding a conditional rule:
Update resource_album.yaml
cat > cerbos-quickstart/policies/resource_album.yaml <<EOF
---
apiVersion: api.cerbos.dev/v1
resourcePolicy:
version: "default"
importDerivedRoles:
- common_roles
resource: "album:object"
rules:
- actions: ['*']
effect: EFFECT_ALLOW
derivedRoles:
- owner
- actions: ['view:public']
effect: EFFECT_ALLOW
roles:
- user
condition:
match:
expr: request.resource.attr.public == true
EOF
Try the request one more time:
Response: Public Access Granted
{
"requestId": "quickstart",
"results": [
{
"resource": {
"id": "BUGS001",
"kind": "album:object"
},
"actions": {
"comment": "EFFECT_ALLOW",
"view:public": "EFFECT_ALLOW"
}
},
{
"resource": {
"id": "DAFFY002",
"kind": "album:object"
},
"actions": {
"comment": "EFFECT_DENY",
"view:public": "EFFECT_ALLOW"
}
}
]
}
Now Bugs Bunny can view Daffy’s public album, but still can’t comment on it!
Can you figure out how to update the policy to allow users to comment on public albums?
Add comment to the actions list in the public album rule:- actions: ['view:public', 'comment']
effect: EFFECT_ALLOW
roles:
- user
condition:
match:
expr: request.resource.attr.public == true
Clean Up
Stop the Cerbos server:
What You Learned
In this quickstart, you:
- ✅ Started a Cerbos Policy Decision Point
- ✅ Made authorization checks via the CheckResources API
- ✅ Created derived roles for dynamic role assignment
- ✅ Wrote resource policies with role-based and condition-based rules
- ✅ Saw how policies update in real-time without restarting Cerbos
Next Steps
Core Concepts
Understand Principals, Resources, Actions, and Policies in depth
Policy Types
Explore resource policies, derived roles, and principal policies
Deploy Cerbos
Learn deployment options for production environments
SDKs
Integrate Cerbos with Go, Python, JavaScript, Java, .NET, PHP, Ruby, or Rust