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 thiscommit_sha." - Testable. The bundle carries its own
*_test.regosuite.opa testruns 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
- What does a bundle's
commit_shaidentify, and why is it the value promotion and rollback are expressed in? - Name the gate that must pass before a bundle is eligible to promote, and say why the deny tests specifically are what protect production.
- Writ signs and governs the bundle. Which component actually evaluates it and returns allow or deny on the request path?