OpsCanary
Back to daily brief
securitypolicyPractitioner

Securing Kubernetes with OPA Admission Control

5 min read OPA DocsApr 23, 2026
PractitionerHands-on experience recommended

Kubernetes admission controllers play a critical role in enforcing policies on objects during create, update, and delete operations. They act as gatekeepers, ensuring that only compliant resources are allowed into your cluster. This is where Open Policy Agent (OPA) comes into play, providing a powerful way to define and enforce policies that align with your security requirements.

The integration of OPA with Kubernetes is facilitated by OPA Gatekeeper. When an object like a Pod or Service is created, updated, or deleted, the Kubernetes API Server queries OPA for admission control decisions. The API Server sends the entire Kubernetes object in a webhook request to OPA, which evaluates the policies it has loaded using the admission review as input. For example, you can define a policy that denies any container image not starting with "hooli.com/". This is done with a simple Rego policy that checks the image of the containers in the request object.

In production, you must be mindful of how policies are structured and the potential performance implications of complex rules. Keep your policies straightforward to avoid unnecessary delays in admission decisions. Additionally, ensure that your policies are well-tested to prevent accidental denials of legitimate requests. Remember, the goal is to secure your cluster without hindering your development workflow.

Key takeaways

  • Understand how admission controllers enforce policies on Kubernetes objects.
  • Utilize OPA Gatekeeper for seamless integration with Kubernetes.
  • Define clear policies to prevent the use of non-compliant container images.
  • Test your policies thoroughly to avoid blocking legitimate resource requests.
  • Keep policies simple to maintain performance during admission control.

Why it matters

Implementing OPA for admission control can significantly enhance your Kubernetes security posture by preventing misconfigurations and ensuring compliance with organizational policies. This proactive approach reduces the risk of vulnerabilities in your deployments.

Code examples

prism-code
1package kubernetes.admission
2
3deny[reason] {
4  some container
5  input_containers[container]
6  not startswith(container.image, "hooli.com/")
7  reason := "container image refers to illegal registry (must be hooli.com)"
8}
9
10input_containers[container] {
11  container := input.request.object.spec.containers[_]
12}
13
14input_containers[container] {
15  container := input.request.object.spec.template.spec.containers[_]
16}
prism-code
{"kind":"AdmissionReview","apiVersion":"admission.k8s.io/v1","request":{"kind":{"group":"","version":"v1","kind":"Pod"},"resource":{"group":"","version":"v1","resource":"pods"},"namespace":"opa-test","operation":"CREATE","userInfo":{"username":"system:serviceaccount:kube-system:replicaset-controller","uid":"439dea65-3e4e-4fa8-b5f8-8fdc4bc7cf53","groups":["system:serviceaccounts","system:serviceaccounts:kube-system","system:authenticated"]},"object":{"apiVersion":"v1","kind":"Pod","metadata":{"creationTimestamp":"2019-08-13T16:01:54Z","generateName":"nginx-7bb7cd8db5-","labels":{"pod-template-hash":"7bb7cd8db5","run":"nginx"},"name":"nginx-7bb7cd8db5-dbplk","namespace":"opa-test","ownerReferences":[{"apiVersion":"apps/v1","blockOwnerDeletion":true,"controller":true,"kind":"ReplicaSet","name":"nginx-7bb7cd8db5","uid":"7b6a307f-d9b4-4b65-a916-5d0b96305e87"}],"uid":"266d2c8b-e43e-42d9-a19c-690bb6103900"},"spec":{"containers":[{"image":"nginx","imagePullPolicy":"Always","name":"nginx","resources":{},"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File","volumeMounts":[{"mountPath":"/var/run/secrets/kubernetes.io/serviceaccount","name":"default-token-6h4dn","readOnly":true}]}],"dnsPolicy":"ClusterFirst","enableServiceLinks":true,"priority":0,"restartPolicy":"Always","schedulerName":"default-scheduler","securityContext":{},"serviceAccount":"default","serviceAccountName":"default","terminationGracePeriodSeconds":30,"tolerations":[{"effect":"NoExecute","key":"node.kubernetes.io/not-ready","operator":"Exists","tolerationSeconds":300},{"effect":"NoExecute","key":"node.kubernetes.io/unreachable","operator":"Exists","tolerationSeconds":300}],"volumes":[{"name":"default-token-6h4dn","secret":{"secretName":"default-token-6h4dn"}}]}},"oldObject":null}}
prism-code
{"kind":"AdmissionReview","apiVersion":"admission.k8s.io/v1","response":{"allowed":false,"status":{"message":"container image refers to illegal registry (must be hooli.com)"}}}

When NOT to use this

The official docs don't call out specific anti-patterns here. Use your judgment based on your scale and requirements.

Want the complete reference?

Read official docs

Test what you just learned

Quiz questions written from this article

Take the quiz →

Get the daily digest

One email. 5 articles. Every morning.

No spam. Unsubscribe anytime.