Skip to main content

The bundle as a versioned artifact

Objective

Treat an OPA policy bundle as a versioned, testable artifact, and gate its promotion on a passing opa test run.

Concept

A policy bundle is the unit the PDP loads: a set of .rego files (and optional data) packaged together. Because it decides who may do what, a bad bundle is a security incident, not a cosmetic bug. So it moves through the same discipline you already apply to application code: it lives in Git, every change is a commit, and nothing reaches production without passing its tests.

Three properties make a bundle safe to ship.

  • Versioned. Every state of the bundle is a commit. The identifier that matters downstream is the commit_sha: it names exactly which bytes the PDP is running. Promotion and rollback are both expressed as "run the bundle at this commit_sha."
  • Testable. The bundle carries its own *_test.rego suite. opa test runs it with no cluster, no network, and no PDP deployment. A default-deny policy with real deny tests is what catches a false allow before it ships.
  • Signed and governed. Writ, the control plane, signs the bundle into a signed bundle from Git and records which signed version is live in each environment. Writ governs the bundle; it is not the PDP that evaluates it. OPA or Enterprise OPA is still the engine on the request path.

The gate is simple and non-negotiable: a bundle may be promoted only if opa test passes for it. In the next lesson that gate becomes a step in a GitHub Actions workflow, run before deploy-action is allowed to deploy.

edit policy.rego -> commit (commit_sha) -> opa test -> [green] -> eligible to promote
\-> [red] -> blocked

Text version: you edit the bundle, commit it (producing a commit_sha), and run opa test; only a green result makes that commit_sha eligible for promotion, and a red result blocks it.

Hands-on lab

Open ../lab/policy.rego. This is the bundle the rest of the course promotes and rolls back, and it ships as a starter: it declares default allow := false plus a TODO(learner) block, so the bundle currently denies everything. Read the input shape at the top: a subject.role, an action of promote or rollback, a target.environment, and a change carrying approved and commit_sha. Note that commit_sha is a first-class field, because the pipeline identifies every deploy by it.

Run the gate exactly as CI would:

git clone https://github.com/EnforceAuth/university-labs.git
cd university-labs
opa test courses/policy-lifecycle-build-promote-rollback -v

Run it from the cloned university-labs repo. The starter reports FAIL: 3/7: the three allow tests fail because nothing is granted yet, while the four deny tests already pass because default-deny is correct-by-construction. Your exercise is to replace the TODO(learner) block with the incremental allow if { ... } rules described in ../lab/README.md — admin, dev promote, staging promote, prod promote, and prod rollback — re-running opa test until you see PASS: 7/7. Keep the deny tests passing as you go: if a rule you add lets a non-release-manager promote to prod, a deny test will fail loudly, which is exactly the gate refusing to promote a bundle that over-grants. Keep iterating until opa test is green.

Check for understanding

  1. What does a bundle's commit_sha identify, and why is it the value promotion and rollback are expressed in?
  2. Name the gate that must pass before a bundle is eligible to promote, and say why the deny tests specifically are what protect production.
  3. Writ signs and governs the bundle. Which component actually evaluates it and returns allow or deny on the request path?