CKS — OPA & Gatekeeper Introduction

6 minute read

OPA & Gatekeeper Introduction

CKS Exam Domain: Minimize Microservice Vulnerabilities (20%)

Open Policy Agent (OPA) is the de facto standard for policy enforcement across the cloud-native stack. Gatekeeper is the Kubernetes-native integration that turns OPA into an admission controller. If a resource violates a policy, Gatekeeper rejects the API request before the object reaches etcd.


What Is Open Policy Agent (OPA)?

OPA is a general-purpose policy engine that decouples policy decisions from application logic. It evaluates structured data (JSON) against policies written in Rego — a declarative query language.

OPA is not Kubernetes-specific. It enforces policies for:

  • Kubernetes admission control
  • Terraform plans
  • API authorization
  • CI/CD pipelines
  • Microservice communication

The key idea: policy as code — version-controlled, testable, auditable.

OPA Architecture (Standalone)

┌─────────────┐       JSON Query       ┌───────────┐
│  Application │ ───────────────────▶  │    OPA    │
│  (any system)│ ◀──────────────────── │  Engine   │
└─────────────┘    allow / deny         └───────────┘
                                             │
                                        Rego Policies
                                        + Data (JSON)

OPA receives a query (structured JSON), evaluates it against loaded Rego policies and optional data, and returns a decision.


What Is Gatekeeper?

Gatekeeper is the Kubernetes-native wrapper around OPA. It registers itself as a ValidatingAdmissionWebhook so the Kubernetes API server sends every relevant admission request to Gatekeeper for evaluation.

Gatekeeper vs Standalone OPA

Aspect Standalone OPA Gatekeeper
Deployment Sidecar or daemon Kubernetes Deployment + webhook
Policy format Raw Rego files ConstraintTemplate CRDs
Data sync Manual or custom Automatic (replicates resources)
Kubernetes integration Requires custom glue code Native: CRDs, audit, status
CKS exam relevance Background understanding Directly tested

Admission Controller Architecture

Gatekeeper hooks into the Kubernetes admission control chain:

    kubectl apply -f pod.yaml
            │
            ▼
   ┌─────────────────────┐
   │   API Server         │
   │                      │
   │  1. Authentication   │
   │  2. Authorization    │
   │  3. Mutating Webhooks│
   │  4. Schema Validation│
   │  5. Validating       │◀─── Gatekeeper sits here
   │     Webhooks         │
   │  6. etcd write       │
   └─────────────────────┘

Flow

  1. User submits a resource (kubectl apply).
  2. API server authenticates and authorizes the request.
  3. Mutating admission webhooks modify the resource (if configured).
  4. Object schema validation runs.
  5. Validating admission webhooks — Gatekeeper evaluates the request against all matching Constraints.
  6. If Gatekeeper returns allowed, the object is persisted to etcd. If denied, the API server returns an error with the violation message.

ValidatingWebhookConfiguration

Gatekeeper creates this automatically on install:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: gatekeeper-validating-webhook-configuration
webhooks:
- name: validation.gatekeeper.sh
  rules:
  - apiGroups: ["*"]
    apiVersions: ["*"]
    operations: ["CREATE", "UPDATE"]
    resources: ["*"]
  failurePolicy: Ignore   # or Fail — controls behaviour when Gatekeeper is unavailable
  sideEffects: None
  admissionReviewVersions: ["v1", "v1beta1"]

Security note: Setting failurePolicy: Fail is more secure — it rejects requests when Gatekeeper is unreachable. Ignore is safer for availability but allows unvalidated resources through.


Installing Gatekeeper

Method 1: kubectl apply (exam-friendly)

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

Method 2: Helm

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

helm install gatekeeper gatekeeper/gatekeeper \
  --namespace gatekeeper-system \
  --create-namespace

Verify installation

# Check namespace
kubectl get ns gatekeeper-system

# Check pods
kubectl get pods -n gatekeeper-system

Expected output:

NAME                                            READY   STATUS    RESTARTS   AGE
gatekeeper-audit-6f8b6f6b7c-x2j4k              1/1     Running   0          30s
gatekeeper-controller-manager-d4c7b8f5d-abc12   1/1     Running   0          30s
gatekeeper-controller-manager-d4c7b8f5d-def34   1/1     Running   0          30s
gatekeeper-controller-manager-d4c7b8f5d-ghi56   1/1     Running   0          30s

Gatekeeper Components

Controller Manager

  • Runs as a Deployment with 3 replicas (high availability).
  • Registers and manages the ValidatingAdmissionWebhook.
  • Receives admission requests from the API server.
  • Evaluates requests against loaded ConstraintTemplates and Constraints.
  • Returns allow/deny decisions.
kubectl get deploy -n gatekeeper-system
NAME                            READY   UP-TO-DATE   AVAILABLE   AGE
gatekeeper-audit                1/1     1            1           2m
gatekeeper-controller-manager   3/3     3            3           2m

Audit Controller

  • Runs as a separate Deployment (1 replica by default).
  • Periodically scans all existing resources in the cluster against active Constraints.
  • Populates status.violations on each Constraint resource.
  • Audit interval is configurable (default: 60 seconds).

This is critical: Gatekeeper does not only enforce at admission time — it continuously audits the cluster for drift.

# Check audit results on a constraint
kubectl get constraint <constraint-name> -o yaml | grep -A 20 violations

CRDs Installed by Gatekeeper

kubectl get crd | grep gatekeeper
assign.mutations.gatekeeper.sh
assignmetadata.mutations.gatekeeper.sh
configs.config.gatekeeper.sh
constraintpodstatuses.status.gatekeeper.sh
constrainttemplatepodstatuses.status.gatekeeper.sh
constrainttemplates.templates.gatekeeper.sh
expansiontemplate.expansion.gatekeeper.sh
modifyset.mutations.gatekeeper.sh
providers.externaldata.gatekeeper.sh

The most important CRD for the exam: constrainttemplates.templates.gatekeeper.sh


OPA vs Kyverno — Comparison

Both are Kubernetes policy engines. The CKS exam primarily focuses on OPA Gatekeeper, but Kyverno awareness is increasingly useful.

Feature OPA Gatekeeper Kyverno
Policy language Rego (dedicated language) YAML (native Kubernetes)
Learning curve Steeper (Rego syntax) Lower (familiar YAML)
CRD model ConstraintTemplate + Constraint ClusterPolicy / Policy
Mutation support Yes (via Assign/AssignMetadata) Yes (built-in, simpler)
Generation No Yes (auto-create resources)
Audit Built-in audit controller Built-in policy reports
CNCF status Graduated Incubating
CKS exam Primary focus May appear
Community Large (OPA ecosystem) Growing rapidly
Debugging opa eval, opa test kyverno apply, kyverno test

Exam tip: Focus your preparation on OPA Gatekeeper. Be aware of Kyverno’s existence and high-level differences.


Why Policy Enforcement Matters

Without admission policies:

Risk Example
Privileged containers A developer deploys a container with securityContext.privileged: true — full host access
Untrusted images A Pod pulls from docker.io/random-user/malicious:latest
Missing resource limits A container without limits consumes all node resources (noisy neighbour)
Missing labels Workloads without app or team labels are untrackable
Host path mounts A Pod mounts /etc/shadow via hostPath

Policy enforcement shifts security left — blocking misconfigurations before they become incidents.

Defence in Depth

Gatekeeper is one layer. Combine it with:

  • RBAC — who can create resources
  • NetworkPolicies — what can talk to what
  • PodSecurity Standards — baseline/restricted profiles
  • Image signing — verify image provenance
  • Runtime security — Falco, Seccomp, AppArmor

Gatekeeper Configuration

The Config resource controls which resources Gatekeeper syncs for audit:

apiVersion: config.gatekeeper.sh/v1alpha1
kind: Config
metadata:
  name: config
  namespace: gatekeeper-system
spec:
  sync:
    syncOnly:
    - group: ""
      version: "v1"
      kind: "Namespace"
    - group: ""
      version: "v1"
      kind: "Pod"
    - group: "apps"
      version: "v1"
      kind: "Deployment"

This tells the audit controller which resource types to cache and scan. Without this, audit may not find violations in resources it hasn’t synced.


Useful Commands for CKS

# List all ConstraintTemplates
kubectl get constrainttemplates

# List all Constraints (across all template types)
kubectl get constraints

# Describe a specific constraint to see violations
kubectl describe <constraint-kind> <constraint-name>

# Check Gatekeeper logs
kubectl logs -n gatekeeper-system -l control-plane=controller-manager --tail=50

# Check audit logs
kubectl logs -n gatekeeper-system -l control-plane=audit-controller --tail=50

# Check webhook configuration
kubectl get validatingwebhookconfiguration | grep gatekeeper

# Test by creating a non-compliant resource
kubectl apply -f bad-pod.yaml
# Expected: Error from server (Forbidden): admission webhook "validation.gatekeeper.sh" denied the request: ...

Practice Questions

Question 1

What type of admission controller does OPA Gatekeeper register as?

Show Answer

Gatekeeper registers as a ValidatingAdmissionWebhook. It evaluates admission requests after mutating webhooks and schema validation, and returns allow or deny decisions. It does not modify the resource — it only validates.

kubectl get validatingwebhookconfiguration | grep gatekeeper

Question 2

What happens to an admission request when Gatekeeper is unavailable and failurePolicy is set to Ignore?

Show Answer

When failurePolicy: Ignore is set, the API server allows the request through without policy evaluation. This prioritises availability over security.

With failurePolicy: Fail, the request would be rejected if Gatekeeper is unreachable — more secure but can block all resource creation if Gatekeeper is down.


Question 3

Name the two main Gatekeeper components and their responsibilities.

Show Answer
  1. Controller Manager (3 replicas) — handles real-time admission requests via the webhook. Evaluates incoming resources against active Constraints.

  2. Audit Controller (1 replica) — periodically scans existing cluster resources against Constraints and reports violations in the Constraint’s status.violations field.

kubectl get deploy -n gatekeeper-system

Question 4

Install OPA Gatekeeper using kubectl apply and verify all Pods are running.

Show Answer
# Install Gatekeeper
kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/v3.15.0/deploy/gatekeeper.yaml

# Verify pods
kubectl get pods -n gatekeeper-system

# Expected: 1 audit pod + 3 controller-manager pods, all Running

Also verify the CRDs are installed:

kubectl get crd | grep gatekeeper
# Should see constrainttemplates.templates.gatekeeper.sh among others

Question 5

How does OPA Gatekeeper differ from PodSecurity Standards (PSS) for policy enforcement?

Show Answer
Aspect OPA Gatekeeper PodSecurity Standards
Scope Any Kubernetes resource Pods only
Flexibility Custom policies via Rego Three fixed profiles (privileged, baseline, restricted)
Customization Fully customizable rules No custom rules
Enforcement Per-resource, per-namespace, label selectors Per-namespace labels
Audit Built-in audit controller warn mode only
CRDs ConstraintTemplate + Constraint None (built-in to API server)

Gatekeeper is far more flexible — it can enforce policies on any resource type with arbitrary logic. PSS is simpler but limited to Pod security profiles.


Previous Next
← OPA Gatekeeper Overview Constraint Templates →

Updated: