Anthropic-Cybersecurity-Skills implementing-opa-gatekeeper-for-policy-enforcement
Enforce Kubernetes admission policies using OPA Gatekeeper with ConstraintTemplates, Rego rules, and the Gatekeeper
install
source · Clone the upstream repo
git clone https://github.com/mukul975/Anthropic-Cybersecurity-Skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/mukul975/Anthropic-Cybersecurity-Skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/implementing-opa-gatekeeper-for-policy-enforcement" ~/.claude/skills/mukul975-anthropic-cybersecurity-skills-implementing-opa-gatekeeper-for-policy-e && rm -rf "$T"
manifest:
skills/implementing-opa-gatekeeper-for-policy-enforcement/SKILL.mdsource content
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
mode first, review violations, then switch todryrundeny - 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
regularly.status.violations - Test Rego policies - Use
or Rego Playground before deployingopa test - Combine with admission webhooks - Layer Gatekeeper with Pod Security Admission for defense in depth