Skip to main content

Policy-Based Access Control (PBAC)

Summary

Policy-Based Access Control (PBAC) is an authorization model that composes multiple policies into a single, unified access decision. Instead of defining its own evaluation logic, a PBAC policy references other policies — RBAC, ABAC, ReBAC, RADAC, or even other PBAC policies — and combines their results using a configurable decision strategy. This enables layered authorization where different models contribute to the same access decision, and the strategy determines how conflicting results are resolved.

Why It Exists

Real-world authorization requirements rarely fit a single model. Consider these examples:

  • "Grant access if the user has the editor role AND the request is during business hours" — This combines RBAC (role check) with ABAC (time-based condition).
  • "Grant access if the user is a team member of the project OR the user has the admin role" — This combines ReBAC (team membership) with RBAC (admin role).
  • "Grant access only if the user has the correct role AND the relationship exists AND the risk score is within the acceptable range" — This combines three different models.

Without PBAC, organizations would need to implement these combinations in application code, leading to scattered, inconsistent enforcement. PBAC centralizes multi-model composition in the policy layer, where it can be managed, audited, and modified without code changes.

This approach provides:

  • Multi-model composition — Combine RBAC, ABAC, ReBAC, RADAC, and Dynamic policies in a single decision
  • Configurable resolution — Choose how conflicting sub-policy results are resolved: any-grant, all-must-grant, or majority-decides
  • Layered security — Stack multiple authorization checks for defense in depth without coupling them in application logic
  • Centralized management — Modify the composition structure through the Admin Console or API without redeploying applications

Where It Fits in Keymate

PBAC sits on top of the other authorization models in Keymate. It does not replace them — it orchestrates them. A PBAC policy acts as a container that references existing policies and applies a decision strategy to their combined results.

Policy authoring: Administrators create PBAC policies through the Admin Console or the Policy Engine REST API. Each PBAC policy references one or more sub-policies by ID and specifies a decision strategy.

Runtime evaluation: When the Authorization Decision Provider evaluates a PBAC policy, it evaluates each referenced sub-policy independently and then applies the decision strategy to produce the final result.

Boundaries

What PBAC covers:

  • Composing multiple policies of any type into a single access decision
  • Applying decision strategies to resolve conflicting sub-policy results
  • Nesting PBAC policies for multi-level composition
  • Referencing sub-policies across all supported authorization models

What PBAC does not cover:

  • Direct role checking — handled by the RBAC sub-policy
  • Direct attribute evaluation — handled by the ABAC sub-policy
  • Direct relationship queries — handled by the ReBAC sub-policy
  • The evaluation mechanics of each sub-policy — PBAC orchestrates results, it does not modify how individual models evaluate

How It Works

Decision Strategies

The decision strategy determines how the results of sub-policies are combined into a final decision. Keymate supports three strategies:

StrategyBehaviorUse Case
AFFIRMATIVEAt least one sub-policy must produce a positive result (logical OR)Additive access — grant access if any qualifying condition is met
UNANIMOUSAll sub-policies must produce a positive result (logical AND)Defense in depth — require multiple independent checks to agree
CONSENSUSA majority of sub-policies must produce a positive resultBalanced evaluation — the majority opinion decides

Policy Structure

A PBAC policy contains these key elements:

ElementDescription
Sub-policiesA list of references to existing policies. Each reference includes the sub-policy's ID, name, and type (RBAC, ABAC, ReBAC, RADAC, Dynamic, or PBAC).
Decision strategyThe strategy used to combine sub-policy results: AFFIRMATIVE, UNANIMOUS, or CONSENSUS.

A PBAC policy does not contain its own conditions, roles, attributes, or expressions. Its entire evaluation logic comes from the sub-policies it references and the strategy it applies.

Evaluation Logic

When the Authorization Decision Provider evaluates a PBAC policy:

  1. Sub-policy resolution — The platform loads each referenced sub-policy by ID.
  2. Independent evaluation — The platform evaluates each sub-policy independently against the current permission request context. RBAC sub-policies check roles, ABAC sub-policies check attributes, ReBAC sub-policies query the FGA Engine, and so on.
  3. Result collection — The platform collects the individual result (positive or negative) from each sub-policy.
  4. Strategy application — The decision strategy combines the results:
    • AFFIRMATIVE: If any sub-policy produced a positive result → GRANT
    • UNANIMOUS: If all sub-policies produced a positive result → GRANT; otherwise → DENY
    • CONSENSUS: If more than half produced a positive result → GRANT; otherwise → DENY
  5. Final decision — The strategy result becomes the PBAC policy's overall result, which feeds into the policy evaluation model.

Composition Patterns

PBAC supports several common composition patterns:

RBAC + ABAC (UNANIMOUS) — "User must have the right role AND the request must meet attribute conditions." This is the most common pattern for adding contextual restrictions to role-based access.

RBAC + ReBAC (AFFIRMATIVE) — "User has the admin role OR user is the resource owner." This allows multiple qualifying paths to access.

Multi-level nesting — A PBAC policy can reference another PBAC policy as a sub-policy, enabling complex composition hierarchies. For example, a top-level PBAC might combine a "role and attribute check" PBAC with a separate "relationship check" ReBAC policy.

Diagram

Example Scenario

Scenario

A financial application requires that invoice modification is allowed only if the user has the finance-manager role AND the request originates during business hours. An administrator creates a PBAC policy with UNANIMOUS strategy that references an RBAC sub-policy (role check) and an ABAC sub-policy (time check).

Input

  • Actor: Authenticated user (user@example.com) with the finance-manager role
  • Resource: invoices with scope write
  • Action: Permission evaluation via the Authorization Decision Provider
  • Context: clientId: acme-portal, time: 14:30 (within business hours)

Expected Outcome

  • Decision: GRANT
  • Why: The RBAC sub-policy checks the user's roles and finds finance-manager → positive result. The ABAC sub-policy checks the time attribute and finds it within business hours → positive result. The UNANIMOUS strategy requires all sub-policies to agree — both are positive, so the PBAC policy produces an overall GRANT.

Common Misunderstandings

  • "PBAC is a separate authorization model" — PBAC does not define its own access logic. It is a composition layer that orchestrates other models. A PBAC policy without sub-policies makes no access decisions.

  • "AFFIRMATIVE strategy is less secure than UNANIMOUS" — Not inherently. AFFIRMATIVE is appropriate when multiple qualifying paths to access exist (e.g., admin role OR resource owner). UNANIMOUS is appropriate when multiple independent checks must all pass. Choose the strategy based on the authorization requirement, not a general security preference.

  • "PBAC sub-policies must all be the same type" — A single PBAC policy can reference RBAC, ABAC, ReBAC, RADAC, and Dynamic sub-policies in any combination. This is the primary value of PBAC.

  • "Modifying a sub-policy requires updating the PBAC policy" — No. PBAC policies reference sub-policies by ID. When a sub-policy's conditions change, the PBAC policy automatically uses the updated version at evaluation time.

warning

A PBAC policy with UNANIMOUS strategy fails the entire decision if any single sub-policy denies access. Ensure that all referenced sub-policies are correctly configured and that the user can realistically satisfy all of them for the intended use case.

Design Notes / Best Practices

  • Use UNANIMOUS for defense-in-depth scenarios where multiple independent checks must all pass. For example, requiring both a role check (RBAC) and a contextual condition (ABAC) before granting access to sensitive resources.

  • Use AFFIRMATIVE for multiple qualifying paths where any one of several mechanisms can grant access. For example, granting access if the user is an admin (RBAC) OR if the user is the resource owner (ReBAC).

  • Place fast-evaluating sub-policies first. While evaluation order does not affect the final result, RBAC checks are typically faster than ABAC attribute evaluations or ReBAC graph queries. Listing RBAC sub-policies first can improve perceived responsiveness when the decision strategy allows early termination.

  • Avoid deep nesting. While PBAC policies can reference other PBAC policies, deeply nested compositions become difficult to reason about and debug. Prefer flat compositions with two to four sub-policies per PBAC.

tip

When a PBAC policy produces an unexpected DENY, check the individual sub-policy results. The per-sub-policy breakdown reveals which specific check failed, making it straightforward to diagnose whether the issue is a missing role, a failed attribute condition, or a missing relationship.

  • Combining role-based access with time-based or location-based restrictions
  • Implementing "owner OR admin" access patterns across organizational hierarchies
  • Adding risk-adaptive checks (RADAC) on top of existing RBAC policies for sensitive operations
  • Building tiered authorization where different resource sensitivity levels require different combinations of checks