← blog

Using OPA Rego to enforce Helm conventions across teams

2026-02-22 · Dana Kimura

OPA and Rego are underused for Helm validation. Here's the pattern I've settled on for enforcing conventions without blocking legitimate variation.

The problem with helm lint

helm lint catches schema errors and some obvious problems. It doesn't know anything about your organisation's conventions — required labels, disallowed image registries, mandatory resource limits, namespace naming rules.

You can add these checks to a CI script as a series of kubectl and jq commands, but the result is brittle and hard to audit. Rego policies are declarative, testable, and composable in a way that ad hoc shell scripts aren't.

Structure of a CrestHelm policy

Policies receive the rendered Kubernetes manifests (from helm template) as input. A policy that requires CPU limits on all containers looks like:

package cresthelm.limits
deny[msg] {
  container := input.spec.containers[_]
  not container.resources.limits.cpu
  msg := sprintf("container %s has no CPU limit", [container.name])
}

CrestHelm collects all deny results across all loaded policies and reports them in the same format as helm lint output, so they slot into existing CI pipelines without changes.

Testing policies

Rego's built-in unit test framework (opa test) works directly with CrestHelm policy bundles. The repository's starter bundle has tests for every included policy; adding tests to custom policies is a prerequisite for merging them, enforced by CrestHelm's own CI pipeline.


Also: CrestHelm 0.3: drift detection and policy bundles