OPA/Gatekeeper

Open Policy Agent (OPA) is a general-purpose policy engine, and Gatekeeper is its Kubernetes-specific implementation. Together, they provide powerful policy enforcement using the Rego policy language.

What is OPA?

OPA is a policy engine that decouples policy decisions from application logic. It uses Rego, a declarative language designed for policy authoring.

What is Gatekeeper?

Gatekeeper is a Kubernetes admission controller that uses OPA to enforce policies. It provides:

  • ConstraintTemplates - Define policy templates
  • Constraints - Instantiate templates with parameters
  • Validation - Reject non-compliant resources
  • Mutation - Modify resources to be compliant

Installing Gatekeeper

kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/release-3.14/deploy/gatekeeper.yaml

Or using Helm:

helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts
helm install gatekeeper gatekeeper/gatekeeper

ConstraintTemplates

ConstraintTemplates define reusable policy templates using Rego:

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8srequiredlabels
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredLabels
      validation:
        openAPIV3Schema:
          type: object
          properties:
            labels:
              type: array
              items:
                type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequiredlabels
        violation[{"msg": msg}] {
          required := input.parameters.labels
          provided := input.review.object.metadata.labels
          missing := required[_]
          not provided[missing]
          msg := sprintf("Missing required label: %v", [missing])
        }

Constraints

Constraints instantiate ConstraintTemplates:

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: must-have-team
spec:
  match:
    kinds:
      - apiGroups: ["apps"]
        kinds: ["Deployment"]
  parameters:
    labels: ["team"]

This constraint requires all Deployments to have a team label.

Common Policies

Require Non-Root Containers

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8srequirednonroot
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredNonRoot
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequirednonroot
        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          not container.securityContext.runAsNonRoot
          msg := sprintf("Container %v must run as non-root", [container.name])
        }
---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredNonRoot
metadata:
  name: containers-must-be-non-root
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]

Block Privileged Containers

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8sblockprivileged
spec:
  crd:
    spec:
      names:
        kind: K8sBlockPrivileged
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8sblockprivileged
        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          container.securityContext.privileged == true
          msg := sprintf("Container %v cannot be privileged", [container.name])
        }

Require Resource Limits

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8srequiredlimits
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredLimits
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequiredlimits
        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          not container.resources.limits
          msg := sprintf("Container %v must have resource limits", [container.name])
        }

Best Practices

  1. Use existing templates - Leverage community ConstraintTemplates
  2. Test Rego policies - Use OPA’s test framework
  3. Start with audit mode - Enable enforcementAction: dryrun first
  4. Document policies - Explain what each constraint does
  5. Monitor violations - Track constraint violations

See Also