# Policy as Code — DevSecOps

Source: https://www.skillbyai.com/en/devsecops/dso-policy-as-code

> Express security rules as versioned, testable code with OPA, Conftest or Kyverno and enforce them in CI and at admission.

## Rules that run, not rules that are read

A security policy written in a document depends on people remembering it. **Policy as code** writes rules in a machine-checkable language, stores them in Git, reviews them like code and runs them automatically. **Open Policy Agent (OPA)** is a general-purpose engine; its language **Rego** evaluates structured input such as Kubernetes manifests, Terraform plans or API requests and produces decisions. **Conftest** runs Rego policies against configuration files in CI. Inside Kubernetes, **admission controllers** enforce policies at the moment a resource is created: **OPA Gatekeeper** uses Rego, while **Kyverno** uses policies written in YAML, which many teams find easier to start with. The same rule can therefore block a bad manifest in a pull request and again at the cluster door. Start policies in **audit** or warn mode, fix existing violations, then switch to enforce, so you do not break every deployment on day one.

## A Conftest policy in Rego

Denies Deployments whose pod `securityContext` does not set `runAsNonRoot: true`, or whose containers use the mutable `latest` tag. The `import rego.v1` line lets the `contains`/`if` syntax work on older OPA and Conftest versions too. Run with `conftest test deploy.yaml`.

```rego
package main

import rego.v1

deny contains msg if {
  input.kind == "Deployment"
  not input.spec.template.spec.securityContext.runAsNonRoot
  msg := sprintf("%s: set securityContext.runAsNonRoot: true", [input.metadata.name])
}

deny contains msg if {
  input.kind == "Deployment"
  some c in input.spec.template.spec.containers
  endswith(c.image, ":latest")
  msg := sprintf("%s: container %s uses the latest tag", [input.metadata.name, c.name])
}
```

## Test your policies

Policies are code, so they have bugs. Rego supports unit tests (`opa test`), and a policy that silently allows everything is worse than none because it creates false confidence.

**Quiz:** Why roll out a new admission policy in audit mode first?

- [ ] Audit mode is faster
- [ ] Enforce mode is not supported by Kubernetes
- [ ] Audit mode encrypts violations
- [x] To find and fix existing violations before blocking deployments

*Answer:* To find and fix existing violations before blocking deployments. Audit mode reports what would be blocked, letting teams fix issues before enforcement breaks releases.
