Skip to main content

Define, Enforce, Audit: one policy end to end

Objective

Trace one policy through Define, Enforce, and Audit, and explain what Writ's decision logs and replay give you at the Audit stage.

Concept

The whole point of a control plane is that one policy has a clean, reviewable life. EnforceAuth's operating model names three stages, and Writ owns the first and third while the PDP owns the middle.

  • Define. Author and version the policy. This is the Rego in the lab, reviewed in Git and built into a signed bundle. Define is where the tenant, org, system, and app isolation and the role rules are decided. Writ governs this stage: versioning, signing, and promotion (from the previous lesson) all live here.
  • Enforce. At runtime, the PEP asks the PDP, and the PDP evaluates the deployed bundle against the request input and returns allow or deny. Enforce runs on every single request. Writ is not on this path; OPA or Enterprise OPA is.
  • Audit. Writ captures a decision log for evaluations and supports replay. A decision log records what was asked and what was decided, so you can answer "did we allow this action, when, and under which policy version?" Replay lets you re-run recorded inputs against a policy version to confirm a change would have decided the same way (or intentionally differently) before you promote it.
Define (Writ: author, version, sign) -> Enforce (PDP: decide per request) -> Audit (Writ: decision logs + replay)

Text version of the diagram: Writ governs Define by authoring and signing the policy; the PDP handles Enforce by deciding on each request; Writ handles Audit by logging decisions and enabling replay. The loop closes because what Audit records feeds the next Define: replay a proposed change against real recorded inputs before promoting it.

Why replay is the payoff: without it, changing an authorization policy is a leap of faith. With decision logs plus replay, you can take yesterday's real requests, run them against a candidate policy version, and see exactly which decisions would flip. That turns a policy change from a guess into a verifiable step, which is the same discipline opa test gives you locally, extended to production traffic.

Hands-on lab

The lab policy is the Define artifact, and you author it. Open courses/getting-started-writ-control-plane/policy.rego in the cloned university-labs repo. The default-deny and the tenant, org, system, and app isolation helpers are provided; the four allow rules are a TODO(learner) stub, so the suite starts red. Implement the four rules (one per hierarchy level) until opa test reports PASS: 8/8. See ../lab/README.md for the exact rules and what each test checks.

Running the suite is a local stand-in for the Enforce and Audit stages: each test asserts one decision the PDP would return, the way a decision log would record it.

git clone https://github.com/EnforceAuth/university-labs.git
cd university-labs
opa test courses/getting-started-writ-control-plane -v

Map the run to the three stages:

  • Define: policy.rego is the authored, versioned policy. The default-deny plus the tenant, org, system, and app isolation and role rules are the decisions you committed to.
  • Enforce: each allow test is a request the PDP would permit; each deny test is one it would block. This is what runs per request in prod.
  • Audit: every test asserts a specific input-to-decision pairing, which is exactly the shape a decision log stores and replay re-runs. The four deny tests, one per hierarchy boundary, are the ones that would catch a false allow if a future edit broke isolation.

Check for understanding

  1. Which of Define, Enforce, and Audit does Writ own, and which does the PDP own?
  2. What does a decision log record, and what does replay let you do with those records before promoting a policy change?
  3. In the lab, which tests correspond to the Enforce stage, and why do the deny tests matter most when you later change the policy?