Skip to main content

PEP, PDP, PIP and the Define, Enforce, Audit loop

Objective

Trace an authorization request through the enforcement point, decision point, and information point, and map the request to the Define, Enforce, Audit operating model.

Concept

Runtime authorization has three roles. They are worth learning by name because they show up in every policy discussion.

  • PEP, the Policy Enforcement Point. The place in your system that intercepts the request and asks for a decision, then enforces the answer. An API gateway, a service middleware, or a sidecar is a PEP. It does not decide; it asks and obeys.
  • PDP, the Policy Decision Point. The engine that evaluates policy against the request and returns allow or deny. In this course the PDP is OPA (open source) or Enterprise OPA. The PDP is what the lab policy runs on.
  • PIP, the Policy Information Point. The source of extra context the decision needs but the request does not carry: group membership, resource ownership, department, risk score. The PDP pulls from the PIP to fill in what input alone cannot answer.

The flow, in one line:

request -> PEP intercepts -> PEP asks PDP (with input + PIP context) -> PDP returns allow/deny -> PEP enforces
flowchart LR
C[Caller] -->|request| PEP[PEP: enforcement point]
PEP -->|input + context| PDP[PDP: OPA / Enterprise OPA]
PIP[PIP: context source] --> PDP
PDP -->|allow / deny| PEP
PEP -->|permit or block| C

Text version of the diagram: the caller sends a request to the PEP; the PEP forwards the request as input to the PDP along with context from the PIP; the PDP returns allow or deny; the PEP permits or blocks the caller.

EnforceAuth's operating model wraps this loop in three verbs:

  • Define — author the policy that the PDP will evaluate. That is the Rego in policy.rego.
  • Enforce — the PEP asks the PDP at runtime and applies the decision. Every real request runs the policy.
  • Audit — record what was decided so it can be reviewed and replayed. The control plane, Writ, captures signed decision logs and supports replay.

Define happens once (and on every change). Enforce happens on every request. Audit happens continuously so a decision can be explained after the fact.

Rego in a nutshell. Rego is the language OPA evaluates. Start with default allow := false so every request is denied unless a rule says otherwise. Each allow if { ... } rule grants access when all conditions in its body hold; multiple allow rules with the same name are OR-ed together, so you add one per case you want to permit. Conditions are plain comparisons like input.action == "delete", and x in {"a", "b"} tests membership. Tests use allow with input as { ... } to feed a synthetic request, and not allow with input as { ... } to assert a denial. That is enough to attempt this lab; for depth (helpers, comprehensions, bundles) see OPA & Enterprise OPA Fundamentals.

Hands-on lab

This is the Define step: you author the policy the PDP will evaluate. The lab under courses/foundations-authorization-gap/ in the cloned university-labs repo ships RED on purpose. policy.rego is a default-deny starter with a # TODO(learner) where the decision rules belong, so the three allow tests fail until you write them.

Open courses/foundations-authorization-gap/policy.rego in that clone and implement the three allow rules the TODO describes:

  1. Admins may delete any resource.
  2. Owners may delete a resource their department owns (subject.department == resource.owner).
  3. Members may read.

As you read the input, keep the three roles in mind. The input document is what a PEP would hand the PDP. The resource.owner field is context a real PIP would supply (which department owns the resource), because the raw request usually knows the resource id, not its owner.

Run the suite until it is green:

git clone https://github.com/EnforceAuth/university-labs.git
cd university-labs
opa test courses/foundations-authorization-gap -v

You start at PASS: 3/6 (the deny tests already hold against default-deny) and finish at PASS: 6/6 once your rules are correct. Each passing allow test is an "Enforce" step that would let the request through; each passing deny test is an "Enforce" step that would block it. The policy file you just authored is the "Define" artifact, and in production the decision each test asserts would also be written to an "Audit" log. Keep iterating until opa test is green.

Check for understanding

  1. Which component evaluates the policy and returns allow or deny: the PEP, the PDP, or the PIP?
  2. In the lab, resource.owner tells the policy which department owns the resource. Which of the three roles would supply that field in a real deployment, and why is it not always in the raw request?
  3. Match each verb to what happens per request: which of Define, Enforce, Audit runs on every request, and which is primarily an authoring-time activity?