You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit ce2a9b6
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: src/content/articles/opa-conftest-policy-as-code-infrastructure-guardrails/index.mdx
+71-30Lines changed: 71 additions & 30 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,14 +15,14 @@ featured: true
15
15
16
16
A developer opens a pull request for a Terraform change. Sixteen hours later, a security review rejects it: the S3 bucket lacks encryption. The developer fixes it, waits another day for re-review. This cycle — write, wait, reject, fix, wait — drains velocity and breeds resentment toward security processes.
17
17
18
-
Shift-left advocates say to check policies earlier. But "earlier" often means CI, which still means waiting for pipelines after pushing code. Real shift-left means __before the commit__ — policy checks that run in seconds during `git commit`, catching violations while the context is fresh and the fix is trivial.
19
-
20
-
OPA (Open Policy Agent) and Conftest make this possible. OPA is a general-purpose policy engine that evaluates structured data against policies written in Rego. Conftest wraps OPA with ergonomic defaults for infrastructure files — it parses Terraform, Kubernetes YAML, and Dockerfiles into JSON that OPA can evaluate. Together, they provide fast, local policy enforcement that doesn't require cloud credentials or pipeline execution.
18
+
Shift-left advocates say to check policies earlier. But "earlier" often means CI, which still means waiting for pipelines after pushing code. Real shift-left means _before the commit_ — policy checks that run in seconds during `git commit`, catching violations while the context is fresh and the fix is trivial.
21
19
22
20
<Callouttype="warning">
23
21
Policy adoption paradox: comprehensive policies with slow feedback get disabled. Minimal policies with fast feedback get expanded. Start with five critical policies — encryption enabled, no public access, resource limits, no privileged containers, no `:latest` tags — that run in under two seconds. Get adoption first, then add coverage.
24
22
</Callout>
25
23
24
+
OPA (Open Policy Agent) and Conftest make this possible. OPA is a general-purpose policy engine that evaluates structured data against policies written in Rego. Conftest wraps OPA with ergonomic defaults for infrastructure files — it parses Terraform, Kubernetes YAML, and Dockerfiles into JSON that OPA can evaluate. Together, they provide fast, local policy enforcement that doesn't require cloud credentials or pipeline execution.
25
+
26
26
## Pre-commit Hooks for Instant Feedback
27
27
28
28
Pre-commit is where shift-left becomes real. Conftest integrates with the pre-commit framework to run policies against staged files before they're committed. The key is speed — pre-commit hooks that take more than a few seconds get disabled.
@@ -57,32 +57,33 @@ Pre-commit only runs against staged files by default, which keeps evaluation fas
57
57
The pre-commit framework shown above is language-agnostic, but each ecosystem has its canonical approach:
@@ -95,15 +96,18 @@ Speed is non-negotiable: if policy checks take more than a few seconds, develope
95
96
Four principles separate policies that get adopted from policies that get bypassed:
96
97
97
98
<List
98
-
variant="check-icons-list"
99
+
variant="timeline-list"
100
+
classes={{
101
+
wrapper: "sm:ml-6 sm:mr-12 mb-6",
102
+
}}
99
103
items={[
100
104
{
101
105
lead: 'Single responsibility.',
102
-
text: 'Each rule should check one thing. A 50-line rule that validates images, resources, and labels produces confusing violations and resists modification. Split concerns into separate rules: `deny_unauthorized_image`, `deny_missing_resources`, `deny_missing_labels`. When a violation fires, developers know exactly what to fix.',
106
+
text: 'Each rule should check one thing. A 50-line rule that validates images, resources, and labels produces confusing violations and resists modification. Split concerns into separate rules: <span class="font-mono">deny_unauthorized_image</span>, <span class="font-mono">deny_missing_resources</span>, <span class="font-mono">deny_missing_labels</span>. When a violation fires, developers know exactly what to fix.',
103
107
},
104
108
{
105
109
lead: 'Actionable messages.',
106
-
text: '"Policy violation" tells the developer nothing. "Container missing resource limits" is better. "Container \'nginx\' missing resource limits. Add `spec.containers[].resources.limits.cpu` and `memory`" is what they actually need. Include the resource name, the violation, and the fix path.',
110
+
text: '"Policy violation" tells the developer nothing. "Container missing resource limits" is better. "Container \'nginx\' missing resource limits. Add <span class="font-mono">spec.containers[].resources.limits.cpu</span> and <span class="font-mono">memory</span>" is what they actually need. Include the resource name, the violation, and the fix path.',
Conftest uses the `--namespace` flag to selectively evaluate policies. Run only Kubernetes policies on YAML files with `conftest test deployment.yaml --namespace kubernetes`. Run only Terraform AWS policies with `conftest test tfplan.json --namespace terraform.aws`. This is how namespace organization pays off — you can run subsets of policies based on context.
0 commit comments