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
- Use existing templates - Leverage community ConstraintTemplates
- Test Rego policies - Use OPA’s test framework
- Start with audit mode - Enable
enforcementAction: dryrunfirst - Document policies - Explain what each constraint does
- Monitor violations - Track constraint violations
See Also
- Policy Enforcement - Overview of policy enforcement
- Kyverno - Kubernetes-native alternative
- Policy Patterns - Common policy patterns