Advanced

Policy engines and policy as code

Separate authorization decisions from application code with decision points, enforcement points, and versioned policy.

As authorization rules grow, scattering if statements across services makes them hard to review, test, and change consistently. Externalized authorization moves the decision into a dedicated component while the application keeps enforcing it.

The reference roles

RoleResponsibilityExample
PEP — policy enforcement pointIntercepts the request, asks for a decision, and enforces it.API middleware or a gateway plugin.
PDP — policy decision pointEvaluates policy and returns permit or deny.A policy engine service or library.
PIP — policy information pointSupplies attributes the PDP needs.Directory, HR data, resource metadata.
PAP — policy administration pointWhere policy is written, reviewed, and published.A Git repository and CI pipeline.

These roles come from the XACML architecture and remain a useful vocabulary even when XACML itself is not used.

Client ──> PEP (API) ── "may alice approve expense 204?" ──> PDP
               │                                            │
               │<───────────── permit / deny ──────────────┘
               │                                            │
           enforce                                   PIP (attributes)

What a decision request contains

A decision request generally describes four things: the subject (who), the action (what operation), the resource (which object), and the context (time, device, risk). The OpenID AuthZEN working group defines a standard Authorization API in exactly these terms so that enforcement points and decision engines from different vendors can interoperate.

Common engines and languages

OptionCharacter
XACML 3.0OASIS XML standard with a complete attribute-based model; verbose but precise.
Open Policy Agent (Rego)General-purpose policy engine, widely used for APIs, Kubernetes, and infrastructure.
CedarPolicy language designed for application authorization, with analyzable semantics.
Relationship-based systemsZanzibar-inspired services storing relationship tuples and answering “check” queries.

The choice depends on the model you need (attributes, relationships, or both), latency requirements, and who will write and review policies.

Treat policy as code

Policy that grants access deserves the same discipline as application code:

  • Keep it in version control with review and approval.
  • Write tests with positive and negative cases, including edge cases such as missing attributes.
  • Deploy through a pipeline with the ability to roll back.
  • Log the policy version used for each decision, so an audit can reproduce it.

Design considerations

Latency and availability. A remote PDP adds a network call to every protected request. Options include sidecars, embedded libraries, and caching of decisions. Decide explicitly what happens if the PDP is unreachable; for sensitive writes, fail closed.

Data freshness. The PDP is only as current as its attributes. A cached role that was removed an hour ago may still grant access.

Filtering lists. “Which documents may Alice see?” is harder than “may Alice see document 7?”. Some engines support partial evaluation or list queries; otherwise the application must filter results.

Enforcement still lives in the application. A PDP decides; if the application forgets to ask, nothing is enforced.

Keep learning

Combine this with RBAC, ABAC, and relationships and authorization in APIs.

References

Knowledge is better when it is shared.Improve this page

Type to search the entire handbook.