100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
DevSecOps & Security Automation
25 minadvanced

Policy-as-code gates with OPA/Conftest in pipelines

Policy-as-code expresses organisational rules — what a secure configuration must and must not contain — as versioned, testable code rather than wiki pages and human memory. Open Policy Agent, or OPA, is the leading engine for this, using a declarative language called Rego to evaluate structured inputs against rules. This lesson shows how OPA and its command-line companion Conftest turn security policies into automated pipeline gates that block non-compliant changes consistently and without argument.

Analogy🏏Cricket
💼 Think of it like business: a company that keeps its compliance rules in one person's head loses them the day that person leaves, applying it differently in every meeting. A mature firm writes policy into a signed, versioned handbook every deal must pass, no exceptions. Policy-as-code is that handbook for infrastructure: organisational rules about what a secure configuration must and must not contain, expressed as testable code instead of wiki pages and memory. Open Policy Agent evaluates structured inputs against rules written in a language called Rego, and its companion Conftest turns those rules into automated pipeline gates. This reveals codified policy as a rulebook no reviewer can forget or bend.

The value of encoding policy as code is uniformity and auditability. A rule written once in Rego applies identically to every pull request, every environment, and every engineer, removing the drift and inconsistency of manual review. Because the policies live in version control, changes to them are themselves reviewed, tested, and traceable. A new requirement, such as forbidding privileged containers, becomes a single reviewed commit that instantly governs the whole organisation's future changes.

Analogy🏏Cricket
💰 Think of it like finance: an accounting standard applied identically to every transaction, in every branch, by every clerk is what makes the books auditable — the moment each office interprets the rule its own way, the numbers drift and no auditor can trust them. A Rego policy written once applies the same way to every pull request, every environment, and every engineer, removing exactly that drift. Because the policies live in version control, changes to them are themselves reviewed, tested, and traceable. A new requirement, such as forbidding privileged containers, is a single reviewed commit that instantly governs every change. This reveals the real payoff as uniformity you can audit, not just automation.

Under the hood, OPA evaluates any JSON or YAML input against Rego rules that return violations. Conftest wraps OPA for the command line, letting a pipeline test configuration files — Kubernetes manifests, Terraform plans, Dockerfiles — against a policy bundle and fail the build when a rule is broken. Because the engine is generic, one policy language and tool can guard many different configuration formats, giving security teams a single place to define and version their guardrails.

Analogy🏏Cricket
🍳 Think of it like cooking: one master thermometer checks a safe internal temperature whether roasting chicken, baking bread, or tempering chocolate — the probe does not care what dish it is, it just reads the number against the safe threshold. OPA is that universal probe: it evaluates any JSON or YAML input against Rego rules that return violations. Conftest wraps it for the command line, so a pipeline can test Kubernetes manifests, Terraform plans, or Dockerfiles against one policy bundle and fail the build when a rule breaks. Because the engine is format-agnostic, one language and tool guards many configurations. This reveals one policy engine as a single place to define guardrails for everything you ship.
rego
# Rego policy: deny privileged containers; run as a Conftest gate
package main

deny[msg] {
  input.spec.containers[i].securityContext.privileged == true
  msg := sprintf("container '%s' must not run privileged", [input.spec.containers[i].name])
}

# In CI:  conftest test deploy.yaml --policy ./policies
#   -> non-zero exit (build fails) if any deny rule matches
Analogy🏏Cricket
♟️ Think of it like chess: the laws of the game are printed and identical in every tournament, and a decisive position is judged by an arbiter against those written rules — with the move record available to review afterward — not by a local player ruling from memory and mood. Policy-as-code is that printed rulebook wired into the pipeline: one written standard, applied the same way in every match, for every engineer, with a clear log of every decision. OPA is the impartial arbiter enforcing it automatically, with no bias and no forgotten clause. This reveals codified policy as neutral, reviewable enforcement replacing inconsistent human judgement.

Best practice keeps policies in version control beside the code they govern, tests the policies themselves with example inputs so a broken rule cannot silently pass everything, and rolls new rules out in warn-only mode before switching them to hard failures. Group policies into reusable bundles, give each violation a clear message pointing at the fix, and reserve blocking enforcement for genuine security requirements so the gate stays trusted rather than resented.

Analogy🏏Cricket
⚽ Think of it like sports: a league does not enforce a brand-new rule mid-final without warning — it trials the rule in friendlies first, checks the referees apply it against sample situations, then makes it binding once everyone trusts it. Roll out policies the same way: keep them in version control beside the code they govern, test the policies themselves with example inputs so a broken rule cannot silently pass everything, and run new rules in warn-only mode before switching them to hard failures. Group them into reusable bundles, give each violation a message pointing at the fix, and reserve blocking for real security needs. This reveals a trusted gate as one introduced carefully, not sprung on players.

In the real world, a platform team might codify a dozen guardrails — no privileged containers, no public storage buckets, required resource limits — as a Conftest bundle that every deployment pipeline runs. A developer who accidentally requests a public bucket sees the build fail immediately with a message naming the offending line and the policy that forbids it, learning the rule in seconds instead of discovering it in a quarterly audit or a breach.

Analogy🏏Cricket
💪 Think of it like fitness: a good gym posts clear form rules on every machine — no ego-lifting, always use a spotter — and a trainer stops you the instant your back rounds under the bar, telling you exactly which cue you broke. A platform team codifies a dozen guardrails the same way: no privileged containers, no public storage buckets, required resource limits, all as a Conftest bundle every deployment runs. A developer who accidentally requests a public bucket sees the build fail immediately, with a message naming the offending line and the policy that forbids it. They learn the rule in seconds, not in a quarterly audit. This reveals fast, specific feedback as how guardrails actually teach.
  • Policy-as-code encodes security rules as versioned, testable Rego rather than prose.
  • One rule applies uniformly to every change, removing manual-review drift.
  • OPA evaluates JSON/YAML inputs; Conftest wraps it as a CLI pipeline gate.
  • Roll new policies out warn-only first, then switch to blocking once trusted.
  • Give each violation a clear message pointing developers straight at the fix.
Lesson 10 of 35
0% complete