What it does. Deploys OPA Gatekeeper via Helm as a Kubernetes admission controller and writes ConstraintTemplates with Rego plus instantiated Constraints to validate, mutate, or deny resource requests at admission time. Use when enforcing custom policy-as-code at admission on Kubernetes v1.24+, blocking non-compliant workloads before scheduling, or expressing a rule that built-in controls cannot. Keywords: Gatekeeper, ConstraintTemplate, Constraint, Rego, admission webhook, audit, mutation. Do not use for the standard pod security profiles that Pod Security Admission already covers - use implementing-pod-security-admission-controller. Part of mukul975/Anthropic-Cybersecurity-Skills (817 security skills) (mukul975/Anthropic-Cybersecurity-Skills).
Install
npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill implementing-opa-gatekeeper-for-policy-enforcement, or copy the skill folder into ~/.claude/skills/implementing-opa-gatekeeper-for-policy-enforcement/.
Raw file: curl -sL https://raw.githubusercontent.com/mukul975/Anthropic-Cybersecurity-Skills/HEAD/skills/implementing-opa-gatekeeper-for-policy-enforcement/SKILL.md
SKILL.md (verbatim)
name: implementing-opa-gatekeeper-for-policy-enforcement
description: >-
Deploys OPA Gatekeeper via Helm as a Kubernetes admission controller and writes
ConstraintTemplates with Rego plus instantiated Constraints to validate, mutate, or deny
resource requests at admission time. Use when enforcing custom policy-as-code at admission
on Kubernetes v1.24+, blocking non-compliant workloads before scheduling, or expressing a
rule that built-in controls cannot. Keywords: Gatekeeper, ConstraintTemplate, Constraint,
Rego, admission webhook, audit, mutation. Do not use for the standard pod security profiles
that Pod Security Admission already covers - use
implementing-pod-security-admission-controller.
domain: cybersecurity
subdomain: container-security
tags:
- opa
- gatekeeper
- kubernetes
- admission-control
- policy-as-code
- rego
version: '1.0'
author: mahipal
license: Apache-2.0
nist_csf:
- PR.PS-01
- PR.IR-01
- ID.AM-08
- DE.CM-01
mitre_attack:
- T1610
- T1611
- T1609
- T1525
Implementing OPA Gatekeeper for Policy Enforcement
Overview
OPA Gatekeeper is a Kubernetes admission controller that enforces policies written in Rego. It uses ConstraintTemplates (policy blueprints with Rego logic) and Constraints (instantiated policies with parameters) to validate, mutate, or deny Kubernetes resource requests at admission time.
When to Use
When deploying or configuring implementing opa gatekeeper for policy enforcement capabilities in your environment
When establishing security controls aligned to compliance requirements
When building or improving security architecture for this domain
When conducting security assessments that require this implementation
Prerequisites
Kubernetes cluster v1.24+
Helm 3
kubectl with cluster-admin access
Familiarity with Rego policy language
Installing Gatekeeper
# Install via 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 \
--set replicas=3 \
--set audit.replicas=1 \
--set audit.logLevel=INFO
# Verify
kubectl get pods -n gatekeeper-system
kubectl get crd | grep gatekeeper
Verify Installation
# Check webhook
kubectl get validatingwebhookconfigurations gatekeeper-validating-webhook-configuration
# Check CRDs
kubectl get crd constrainttemplates.templates.gatekeeper.sh
kubectl get crd configs.config.gatekeeper.sh
ConstraintTemplate Examples
1. Require Labels on Resources
# template-required-labels.yaml
apiVersion: templates.gatekeeper.sh/v1
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, "details": {"missing_labels": missing}}] {
provided := {label | input.review.object.metadata.labels[label]}
required := {label | label := input.parameters.labels[_]}
missing := required - provided
count(missing) > 0
msg := sprintf("Missing required labels: %v", [missing])
}
# constraint-require-team-label.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: require-team-label
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Namespace"]
- apiGroups: ["apps"]
kinds: ["Deployment"]
parameters:
labels:
- "team"
- "environment"
2. Block Privileged Containers
# template-block-privileged.yaml
apiVersion: templates.gatekeeper.sh/v1
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("Privileged container not allowed: %v", [container.name])
}
violation[{"msg": msg}] {
container := input.review.object.spec.initContainers[_]
container.securityContext.privileged == true
msg := sprintf("Privileged init container not allowed: %v", [container.name])
}
# constraint-block-privileged.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sBlockPrivileged
metadata:
name: block-privileged-containers
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
namespaces:
- "production"
- "staging"
3. Restrict Container Image Registries
# template-allowed-repos.yaml
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8sallowedrepos
spec:
crd:
spec:
names:
kind: K8sAllowedRepos
validation:
openAPIV3Schema:
type: object
properties:
repos:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8sallowedrepos
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not image_matches(container.image)
msg := sprintf("Container image %v is not from an allowed registry. Allowed: %v", [container.image, input.parameters.repos])
}
violation[{"msg": msg}] {
container := input.review.object.spec.initContainers[_]
not image_matches(container.image)
msg := sprintf("Init container image %v is not from an allowed registry. Allowed: %v", [container.image, input.parameters.repos])
}
image_matches(image) {
repo := input.parameters.repos[_]
startswith(image, repo)
}
# constraint-allowed-repos.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sAllowedRepos
metadata:
name: restrict-image-repos
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
parameters:
repos:
- "gcr.io/my-project/"
- "ghcr.io/my-org/"
- "registry.k8s.io/"
4. Enforce Resource Limits
# template-require-limits.yaml
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8srequirelimits
spec:
crd:
spec:
names:
kind: K8sRequireLimits
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequirelimits
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not container.resources.limits.cpu
msg := sprintf("Container %v has no CPU limit", [container.name])
}
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not container.resources.limits.memory
msg := sprintf("Container %v has no memory limit", [container.name])
}
5. Block Latest Image Tag
# template-block-latest-tag.yaml
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8sblocklatesttag
spec:
crd:
spec:
names:
kind: K8sBlockLatestTag
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8sblocklatesttag
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
endswith(container.image, ":latest")
msg := sprintf("Container %v uses ':latest' tag. Use specific version tags.", [container.name])
}
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not contains(container.image, ":")
msg := sprintf("Container %v has no tag (defaults to latest). Use specific version tags.", [container.name])
}
6. Enforce Read-Only Root Filesystem
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8sreadonlyroot
spec:
crd:
spec:
names:
kind: K8sReadOnlyRoot
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8sreadonlyroot
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not container.securityContext.readOnlyRootFilesystem
msg := sprintf("Container %v must have readOnlyRootFilesystem set to true", [container.name])
}
Audit and Enforcement Modes
# Dry-run mode (audit only, don't block)
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sBlockPrivileged
metadata:
name: block-privileged-dryrun
spec:
enforcementAction: dryrun # dryrun | deny | warn
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
Check Audit Violations
# List all constraint violations
kubectl get k8sblockprivileged block-privileged-containers -o yaml | grep -A 20 violations
# Check all constraints audit status
kubectl get constraints -o json | jq '.items[] | {name: .metadata.name, violations: (.status.violations // [] | length)}'
Gatekeeper Config (Exempt Namespaces)
apiVersion: config.gatekeeper.sh/v1alpha1
kind: Config
metadata:
name: config
namespace: gatekeeper-system
spec:
match:
- excludedNamespaces:
- kube-system
- gatekeeper-system
- calico-system
processes:
- "*"
Monitoring
# Check Gatekeeper metrics
kubectl port-forward -n gatekeeper-system svc/gatekeeper-webhook-service 8443:443
# Prometheus metrics
kubectl get --raw /metrics | grep gatekeeper
Best Practices
Start with dryrun - Deploy constraints in dryrun mode first, review violations, then switch to deny
Use the policy library - Leverage https://github.com/open-policy-agent/gatekeeper-library for pre-built templates
Exempt system namespaces - Always exclude kube-system and gatekeeper-system
Version control policies - Store ConstraintTemplates and Constraints in Git
Monitor audit results - Check constraint .status.violations regularly
Test Rego policies - Use opa test or Rego Playground before deploying
Combine with admission webhooks - Layer Gatekeeper with Pod Security Admission for defense in depth
Other files in this skill
assets/template.md (verbatim)
OPA Gatekeeper Policy Deployment Checklist
Policy Rollout Plan
Pre-Deployment
Deployment Steps
Deploy ConstraintTemplate to cluster
Verify CRD created: kubectl get crd
Deploy Constraint in dryrun mode
Wait 24 hours for audit results
Review violations and remediate/exempt
Switch to warn mode
Wait 7 days, monitor for issues
Switch to deny mode
Post-Deployment
Policy Registry
Policy Name
Kind
Mode
Namespaces
Owner
block-privileged
K8sBlockPrivileged
deny
all except kube-system
Security
require-labels
K8sRequiredLabels
deny
all
Platform
allowed-repos
K8sAllowedRepos
deny
production, staging
Security
block-latest
K8sBlockLatestTag
warn
production
DevOps
require-limits
K8sRequireLimits
deny
production
SRE
Field
Value
Constraint Name
Resource
Namespace
Reason
Duration
Compensating Control
Approved By
Expiry Date
references/api-reference.md (verbatim)
API Reference: OPA Gatekeeper Policy Enforcement
OPA REST API (localhost:8181)
Endpoint
Method
Description
/v1/data/{path}
GET/POST
Query policy
/v1/policies/{id}
PUT
Create/update policy
/v1/data
POST
Evaluate input against policy
Gatekeeper CRDs
CRD
Description
ConstraintTemplate
Define policy schema + Rego
Constraint
Instantiate a template
Config
Audit/sync configuration
ConstraintTemplate Example
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8srequiredlabels
spec:
crd:
spec:
names:
kind: K8sRequiredLabels
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredlabels
violation[{"msg": msg}] {
not input.review.object.metadata.labels["app"]
msg := "Missing required label: app"
}
Key Libraries
Library
Use
kubernetes
K8s API client
requests
OPA REST queries
subprocess
kubectl commands
references/standards.md (verbatim)
Standards and References - OPA Gatekeeper Policy Enforcement
Industry Standards
NIST SP 800-190
Section 4.1: Image vulnerabilities - Enforce image registry restrictions
Section 4.2: Image configuration defects - Enforce security context requirements
Section 5.2: Registry security - Restrict allowed image sources
CIS Kubernetes Benchmark v1.8
5.2.1: Ensure Pods cannot run with privileged containers
5.2.2: Ensure Pods cannot share host PID namespace
5.2.3: Ensure Pods cannot share host IPC namespace
5.2.4: Ensure Pods cannot share host network namespace
5.2.5: Ensure containers do not allow privilege escalation
5.2.6: Ensure containers do not run as root
5.2.7: Ensure Pods use seccomp profile
5.2.8: Ensure Pods restrict volume types
5.2.9: Ensure Pods restrict host path volumes
5.7.1: Create administrative boundaries using namespaces
5.7.2: Ensure seccomp profile is set
5.7.3: Apply security context to pods
NSA/CISA Kubernetes Hardening Guide
Section 2: Pod Security - Admission control enforcement
Recommends admission controllers to enforce security baselines
Gatekeeper Policy Library
Template
Purpose
CIS Mapping
K8sPSPPrivilegedContainer
Block privileged containers
5.2.1
K8sPSPHostNamespace
Block host PID/IPC/Network
5.2.2-5.2.4
K8sPSPAllowPrivilegeEscalation
Prevent privilege escalation
5.2.5
K8sPSPRunAsNonRoot
Require non-root
5.2.6
K8sPSPSeccomp
Require seccomp profiles
5.2.7
K8sPSPVolumeTypes
Restrict volume types
5.2.8
K8sPSPHostFilesystem
Restrict hostPath
5.2.9
K8sAllowedRepos
Restrict image registries
5.1.1
K8sRequiredLabels
Enforce labeling standards
Organizational
K8sContainerLimits
Enforce resource limits
Operational
Compliance Mappings
PCI DSS v4.0
Req 2.2: Secure system components per configuration standards
Req 6.3.2: Develop software securely with automated controls
SOC 2
CC6.1: Logical access to system components is restricted
CC8.1: Changes to infrastructure are controlled
references/workflows.md (verbatim)
Workflow - OPA Gatekeeper Policy Enforcement
Phase 1: Install Gatekeeper
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 \
--set replicas=3 --set audit.replicas=1
kubectl -n gatekeeper-system rollout status deployment/gatekeeper-controller-manager
Phase 2: Deploy ConstraintTemplates
# Clone Gatekeeper policy library
git clone https://github.com/open-policy-agent/gatekeeper-library.git
# Apply common templates
kubectl apply -f gatekeeper-library/library/pod-security-policy/privileged-containers/template.yaml
kubectl apply -f gatekeeper-library/library/pod-security-policy/host-namespaces/template.yaml
kubectl apply -f gatekeeper-library/library/pod-security-policy/allow-privilege-escalation/template.yaml
kubectl apply -f gatekeeper-library/library/general/allowedrepos/template.yaml
kubectl apply -f gatekeeper-library/library/general/requiredlabels/template.yaml
kubectl apply -f gatekeeper-library/library/general/containerlimits/template.yaml
Phase 3: Deploy Constraints in Dryrun Mode
kubectl apply -f - <<EOF
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPPrivilegedContainer
metadata:
name: block-privileged-dryrun
spec:
enforcementAction: dryrun
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
excludedNamespaces:
- kube-system
- gatekeeper-system
EOF
Phase 4: Review Audit Violations
# Check violations for each constraint
kubectl get constraints -o json | jq '.items[] | {
name: .metadata.name,
enforcement: .spec.enforcementAction,
violations: (.status.violations // [] | length),
total_violations: .status.totalViolations
}'
# Get detailed violations
kubectl get k8spsprivilegedcontainer block-privileged-dryrun -o json | jq '.status.violations[]'
Phase 5: Switch to Enforcement
# After reviewing violations and remediating, switch to deny
kubectl patch k8spsprivilegedcontainer block-privileged-dryrun \
--type=merge -p '{"spec":{"enforcementAction":"deny"}}'
Phase 6: Test Enforcement
# This should be denied
kubectl run test-priv --image=nginx --overrides='{"spec":{"containers":[{"name":"test","image":"nginx","securityContext":{"privileged":true}}]}}'
# Expected: Error from server (Forbidden): admission webhook denied the request
kubectl delete pod test-priv --ignore-not-found
Phase 7: Monitor and Maintain
# Regular audit check
kubectl get constraints -o wide
# Check Gatekeeper health
kubectl get pods -n gatekeeper-system
kubectl logs -n gatekeeper-system -l control-plane=controller-manager --tail=20
Back to mukul975/Anthropic-Cybersecurity-Skills (817 security skills) or Agent skills .