
Policy-Based Access Control (PBAC)
What is policy-based access control (PBAC)?
Policy-based access control (PBAC) is an authorization model where access decisions are governed by declarative policies that live outside the application. Instead of checking roles or permissions inline with the code, every request is evaluated against a set of policies by a dedicated policy engine. The engine takes in the principal, the action, the resource, and any contextual data, then returns an allow or deny based on the rules defined in those policies.
The defining trait of PBAC is that the policy itself is a first-class artifact. It is authored, versioned, tested, and deployed independently of the application. That separation is what lets teams change access logic without redeploying services and what lets non-engineers reason about, audit, and contribute to access rules.
How PBAC works
At its core PBAC is about one thing. The access decision comes from a policy, not from logic hard-coded into each application. The policy is a declarative, standalone artifact that defines who can do what under which conditions, and every request is evaluated against it. The policy is the unit you author, version, test, and reason about.
How that policy gets evaluated at runtime is a separate question. Most externalized authorization setups answer it with three roles, a separation that the XACML model first described and that the OpenID AuthZEN spec has since modernized for application authorization.
The Policy Administration Point (PAP) is where policies are authored and managed. In a modern PBAC setup this looks like a Git repository, a policy authoring UI, or both, with versioning, testing, and deployment handled like any other code artifact.
The Policy Decision Point (PDP) is the engine that evaluates a request against the policies and returns a decision. It receives the request context, runs it through the policy logic, and produces an allow or deny. The PDP is stateless in well-designed implementations, which is what makes it possible to scale.
The Policy Enforcement Point (PEP) sits inside the application or service. It intercepts the request, packages up the context, asks the PDP for a decision, and enforces the answer. Cerbos provides PEP SDKs for all major languages, including JavaScript, Go, Python, Java, .NET, Rust, PHP, and Ruby so the integration is a single function call.
This separation is the foundation of externalized authorization management (EAM). It moves authorization out of the application into a dedicated layer that can be tested and evolved on its own. It is not unique to PBAC, the same architecture runs role-based and attribute-based rules just as well. What PBAC adds is the policy as the thing you manage.
How to implement PBAC with Cerbos
Cerbos is a purpose-built PBAC engine. Policies are written in YAML, conditions are expressed in Google's CEL, and the Cerbos PDP evaluates them against the request context at runtime. The PDP is stateless, runs anywhere (containers, Kubernetes, edge), and handles millions of checks per second.
Here's a working example. In this policy, a user is granted permission to view a resource only when both conditions are met. Their department attribute equals "IT" and the resource type attribute equals "confidential":
apiVersion: api.cerbos.dev/v1
resourcePolicy:
version: default
resource: pbacExample
rules:
- actions:
- VIEW
effect: EFFECT_ALLOW
roles:
- USER
condition:
match:
all:
of:
- expr: request.principal.attr.department == "IT"
- expr: request.resource.attr.type == "confidential"
The policy lives in Git. It is tested in CI like any other code, validated against schemas, and deployed to running PDPs without restarts via Cerbos Hub. When the access rules change, you update the policy, not the application.
For scenarios where the policy needs data that does not travel with the request, Cerbos Synapse enriches the call before it hits the engine. It can pull a user's department from your identity provider, a customer's subscription tier from your database, or a device's trust level from your MDM, so the policy can evaluate against complete context.
Key components of PBAC
Every PBAC implementation, regardless of vendor, has the same building blocks.
The policy language is how rules are expressed. Some systems use a domain-specific language like Rego. Cerbos uses YAML for structure and CEL for conditions. The language choice matters because it determines who can read, write, and audit policies. YAML and CEL are readable enough that product managers, security teams, and compliance reviewers can follow the logic without learning a new syntax.
The policy engine is the runtime that evaluates a request against the policies. Performance and isolation are the two things that matter here. Cerbos built a custom decision engine after hitting limitations with OPA's Rego model, and the result is up to 17x faster than the OPA-based predecessor it replaced.
Attributes and context feed the evaluation. A policy can reference attributes on the principal (role, department, tenant), the resource (owner, classification, status), the action, and the environment (time, region, device trust). The more context the engine has, the more nuanced the decisions can be.
The policy lifecycle covers authoring, testing, versioning, and distribution. Cerbos treats policies the same way a team treats application code, with Git-native workflows, CI validation, coverage reports, breaking-change detection, and audit logs of every decision. Cerbos Hub handles propagation to running PDPs without restarts.
Benefits of PBAC
The case for PBAC over simpler models rests on three things. Separation of concerns, expressiveness, and operational maturity.
-
Separation of concerns. Authorization logic lives outside the application. Engineers ship features, security and product teams own the rules, and the two can move independently. When a policy needs to change, you change the policy, not the codebase. One Cerbos customer, Human Managed, summed it up as "having to modify authorization is now a five-minute job."
-
Expressiveness. Roles alone cannot capture conditions like "users can read records they own", "managers can approve orders under $10K in their region", or "service accounts can only call this endpoint from inside the cluster". PBAC handles all of these with policy conditions instead of role explosion. That is the same thing ABAC promises, but PBAC frames it around the policy as the unit of management rather than the attributes themselves.
-
Operational maturity. Because policies are first-class artifacts, you get version control, code review, automated testing, and structured audit logs. For regulated industries this is the difference between an authorization layer you can explain to an auditor and one you cannot. Cerbos Hub produces structured audit logs that meet SOC 2, ISO 27001, HIPAA, PCI DSS, and GDPR requirements.
PBAC is back: why policy-based access control is trending again
When authorization is static, risk accumulates silently
PBAC vs RBAC, ABAC, and ReBAC
The lines between authorization models are blurrier in practice than the names suggest. The honest framing is that PBAC is less a competing model and more a pattern for managing whichever model you pick.
RBAC (role-based access control) grants access by assigning users to roles. It is the simplest model and the right starting point for most applications. It breaks down when access rules need context beyond the role, which is usually around the time a team finds itself adding roles like "manager_eu_finance_q3_2026_temp."
ABAC (attribute-based access control) evaluates attributes of the user, resource, action, and environment. It handles the nuance RBAC cannot, but the attribute-driven framing leaves the question of how policies are managed open.
ReBAC (relationship-based access control) models access through relationships between entities, like "users can read documents in folders they have access to." It suits systems where the permission structure mirrors a graph.
PBAC does not replace any of these. It is a pattern for managing access rules as policy artifacts, regardless of whether those rules are role-based, attribute-based, or relationship-based. In Cerbos, a single policy file can mix role checks, attribute conditions, and relationship logic, with the policy itself as the unit of governance.
When PBAC makes sense
A few patterns make PBAC clearly the right call.
Multi-tenant SaaS is the most common one. When the same user role means different things in different tenants, or when each customer needs slightly different access rules, embedding that logic in code creates a maintenance problem that gets worse with every new tenant. PBAC lets you express tenant-specific rules in policy and avoid duplicating the application per customer.
Regulated industries like fintech and healthcare have requirements that map directly to policy conditions. A doctor can read records only for patients currently under their care. A financial analyst can export data only for their own region. A contractor has access only during their contract period. These are all policy checks, and the structured audit trail is what makes them defensible to auditors.
Enterprise applications with complex org structures benefit from PBAC when permissions reflect reporting lines, cost centers, geographic units, or clearance levels. Encoding that into roles creates fragility. Encoding it into policies keeps it maintainable as the organization evolves.
Microservices and API authorization are a good fit because PBAC gives you a single, consistent authorization layer across services without coupling each service to its own access logic. The PDP runs as a sidecar or shared service, every microservice calls it the same way, and the policy logic lives in one place. AI agents and non-human identities are the newest category. We cover this in its own section below.
Multi-tenant SaaS authorization
Designing an authorization model for an enterprise
3 most common authorization designs for SaaS products
Challenges of PBAC and how Cerbos addresses them
The main objections teams raise are around complexity, performance, and operational burden. Each one has a concrete answer.
Policy complexity. A policy language is more powerful than role assignments, and that power can turn into sprawl if there is no discipline around it. Cerbos addresses this with YAML structure that is readable by non-engineers, schema validation that catches mistakes before they ship, a Playground for iterating on policies with execution traces, and CI integrations that run coverage reports and flag breaking changes on every commit.
Latency. A separate authorization service adds a network hop. The Cerbos decision engine evaluates policies in under a millisecond, the PDP runs locally as a sidecar so there is no cross-network call, and the engine itself is up to 17x faster than the OPA-based version it replaced. For most applications the overhead is well inside the normal noise of a request.
Operational overhead. Running a separate authorization service sounds like more work. In practice the alternative is authorization logic spread across every service in the system, which is harder to audit and harder to change. Cerbos Hub handles policy propagation across all running PDPs without restarts and produces a structured audit log of every decision, which is usually a net reduction in operational work, not an increase.
Migrating off existing code. Most teams come to PBAC with authorization already embedded in their application. The realistic path is to introduce the PDP behind a feature flag for one resource type, validate it against the existing logic, then expand. Customers like Salesroom describe the result as "I categorized [Cerbos] as just one of those things I don't have to think about."
Mapping business requirements to authorization policy
How to adopt externalized authorization
PBAC for AI agents and non-human identities
AI agents calling tools on behalf of users break the assumptions most authorization systems were built on. The agent has its own identity, but it is also acting for a human with their own permissions. A single misconfiguration affects every action the agent takes across every system it reaches.
PBAC is a natural fit because the policy can reason about both identities in the same check. The agent might have broad tool access, but the policy can restrict it based on the human's clearance, the sensitivity of the resource, the time of day, or any other contextual condition. The agent does not get standing privilege, and every action is evaluated against the policy at request time.
The same pattern works for service-to-service calls, CI/CD pipelines, and any other non-human caller. The combination of PBAC and Cerbos Synapse means the policy engine can pull the human's profile from the IdP, the agent's metadata from the platform, and any resource attributes from the source system, then evaluate them together in a single decision.
Zero-trust for AI: Securing MCP servers
Getting started with PBAC
The fastest way to see what a PBAC implementation looks like is to write a policy in the Cerbos Playground, where you can edit YAML, run test cases, and see execution traces in the browser. From there the quickstart walks through running the PDP locally and wiring up an SDK call, and Cerbos Hub handles policy management and distribution once you are ready to deploy.
Find out more
Features, benefits & use cases
Fit Cerbos seamlessly into your tech stack
Playground
Prototype policies in your browser right now
Cerbos Hub
Implement roles & permissions in your app
Speak to an engineer
Book an intro call and learn more
Subscribe to our newsletter
Join thousands of developers | Features and updates | 1x per month | No spam, just goodies.





















