Skip to content
CloudOps
All prompts
AI for Kubernetes & Helm Difficulty: Intermediate ClaudeChatGPT

Kyverno / Gatekeeper Policy Authoring Prompt

Author and debug policies for Kyverno or OPA Gatekeeper — validate, mutate, generate; audit vs enforce modes; exclusions; constraint templates.

Target user
Platform engineers writing admission policies
Difficulty
Intermediate
Tools
Claude, ChatGPT

The prompt

You are a senior Kubernetes platform engineer who has written hundreds of policies in both Kyverno and OPA Gatekeeper. You know when to choose each (Kyverno for K8s-native YAML; Gatekeeper for complex Rego/multi-cloud) and how to roll out new policies safely.

I will provide:
- The goal: write a new policy / debug an existing one / migrate from PSP
- The policy intent (e.g., "require all images from internal registry", "disallow privileged containers")
- Which engine: Kyverno or Gatekeeper
- For debugging: the policy YAML, the resource being applied, and the violation message

Your job:

1. **Choose the right tool/approach**:
   - **Kyverno**: K8s-native YAML; easier learning curve; built-in mutate/generate; common policies have community samples
   - **OPA Gatekeeper**: Rego language (steeper); more expressive; can integrate with non-K8s data; ConstraintTemplate + Constraint model
2. **Kyverno policy structure**:
   - **`Policy` (namespaced)** vs **`ClusterPolicy` (cluster-scoped)**
   - Rules: `validate`, `mutate`, `generate`, `verifyImages`
   - `match` / `exclude` blocks scope the policy
   - `validationFailureAction: Audit` (warn only) or `Enforce` (block)
   - `background: true` audits existing resources too
3. **Gatekeeper structure**:
   - **`ConstraintTemplate`** — defines the Rego logic + the schema for parameters
   - **`Constraint`** — instance of a template with parameters and scope
   - Rego is functional; admission resource is in `input.review.object`
   - Enforcement actions: `deny`, `warn`, `dryrun`
4. **For new policy rollout** (recommended pattern):
   - Start in `Audit` (Kyverno) / `dryrun` (Gatekeeper) — observe violations
   - Use `kubectl get policyreport` (Kyverno) / `kubectl get constraint <name>` (Gatekeeper status) for current violations
   - Fix violators
   - Switch to `Enforce` / `deny`
5. **For exclusions** (essential for stability):
   - Exclude `kube-system`, monitoring, and the policy engine's own namespace
   - Use `excludedNamespaces` (Kyverno), `match.excludedNamespaces` (Gatekeeper Constraint)
   - Exclude controllers that bypass admission via aggregated API
6. **Common policies** to implement:
   - Require labels (team, owner, environment)
   - Disallow `latest` tag
   - Require resource requests/limits
   - Disallow privileged, hostNetwork, hostPID
   - Require image from approved registry
   - Disallow `default` ServiceAccount usage
   - Require PodDisruptionBudget for production workloads
7. **For mutating policies**:
   - Add labels, annotations, default resource requests
   - Inject sidecars (similar to mesh injection)
   - Set `imagePullPolicy: IfNotPresent` automatically
   - Kyverno mutate is simpler than writing a custom mutating webhook
8. **For policy debug**:
   - Kyverno: `kubectl describe clusterpolicy <name>` shows recent violations; `kubectl get policyreport -A` per-namespace
   - Gatekeeper: `kubectl get constraints` shows `status.totalViolations` and recent
   - Both: webhook logs show the admission decision per request

Mark DESTRUCTIVE: enabling Enforce mode without first running in Audit (immediate breakage), policies selecting kube-system, complex Rego that produces wrong denials.

---

Goal: [write / debug / migrate]
Engine: [Kyverno / Gatekeeper]
Policy intent: [DESCRIBE]
Current policy (if existing):
```yaml
[PASTE]
```
Failing resource and violation (if debugging):
```
[PASTE]
```

Why this prompt works

Policy engines (Kyverno, Gatekeeper) enable powerful cluster-wide guardrails but also enable cluster-wide outages when misconfigured. This prompt enforces audit-first rollout and proper namespace exclusions.

How to use it

  1. Pick the engine BEFORE writing the policy. They’re different.
  2. Start in Audit mode. Always.
  3. Iterate with PolicyReports (Kyverno) or Constraint status (Gatekeeper) to find violators.
  4. Exclude system namespaces in every policy.

Useful commands

Kyverno

# Inventory
kubectl get clusterpolicies
kubectl get policies -A

# Status of policies
kubectl describe clusterpolicy <name>
kubectl get policyreport -A
kubectl get clusterpolicyreport

# Test a policy against a resource
# Install kyverno CLI: https://kyverno.io/docs/kyverno-cli/
kyverno test ./policies/
kyverno apply ./policy.yaml --resource ./resource.yaml

# View violations
kubectl get policyreport -A -o json | \
    jq '.items[] | .results[] | select(.result=="fail") | {namespace:.resources[].namespace, name:.resources[].name, policy:.policy, rule:.rule, message:.message}'

Gatekeeper

# Inventory
kubectl get constrainttemplates
kubectl get constraints

# Status
kubectl describe constraint <name>
kubectl get constraint <name> -o jsonpath='{.status.totalViolations}'

# Test
gator test --filename ./policy.yaml --filename ./resource.yaml

# View violations
kubectl get constraints -o json | \
    jq '.items[] | {name:.metadata.name, kind:.kind, totalViolations:.status.totalViolations, recent:.status.violations}'

Kyverno policy examples

Require labels

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-team-label
spec:
  validationFailureAction: Audit         # start in Audit
  background: true
  rules:
  - name: check-team
    match:
      any:
      - resources:
          kinds: [Deployment, StatefulSet, DaemonSet]
    exclude:
      any:
      - resources:
          namespaces: [kube-system, kube-public, kyverno]
    validate:
      message: "Workloads must have a 'team' label."
      pattern:
        metadata:
          labels:
            team: "?*"

Disallow latest tag

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-latest-tag
spec:
  validationFailureAction: Enforce
  rules:
  - name: validate-image-tag
    match:
      any:
      - resources:
          kinds: [Pod]
    exclude:
      any:
      - resources:
          namespaces: [kube-system]
    validate:
      message: "Image tag :latest is not allowed."
      pattern:
        spec:
          containers:
          - image: "!*:latest"

Mutate (default resource requests)

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: add-default-requests
spec:
  rules:
  - name: add-requests
    match:
      any:
      - resources:
          kinds: [Pod]
    mutate:
      patchStrategicMerge:
        spec:
          containers:
          - (name): "?*"
            resources:
              requests:
                +(memory): "128Mi"
                +(cpu): "100m"

Gatekeeper examples

ConstraintTemplate (require labels)

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}] {
        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 (use the template)

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: must-have-team
spec:
  enforcementAction: dryrun                # start in dryrun
  match:
    kinds:
    - apiGroups: ["apps"]
      kinds: [Deployment, StatefulSet]
    excludedNamespaces: [kube-system, kube-public]
  parameters:
    labels: ["team"]

Rollout pattern (any engine)

Day 1: Deploy policy in Audit / dryrun mode
Day 2-7: Watch PolicyReports / Constraint status; identify violators
Day 7-14: Engage owners; fix violators
Day 14: Flip to Enforce / deny in non-production
Day 21: Flip to Enforce / deny in production after observing one week

Common findings this catches

  • Policy enabled in Enforce day 1 → mass production breakage.
  • Policy selects kube-system → cluster-critical pods blocked.
  • No excludedNamespaces for monitoring/logging — those tools often break first.
  • Mutating policy added at the same time as a GitOps tool → drift loop.
  • Constraint template Rego buggy — false denials cluster-wide.
  • Image verification policy without verifier health → blocks all new pods when verifier down.
  • PolicyReports growing unbounded in clusters with many violations → set retention or address violators.

When to escalate

  • Cluster-wide policy outage → revert (delete the policy) immediately.
  • Complex Rego policies — peer review; possible bugs in Constraint Template.
  • Policy collisions (Kyverno + Gatekeeper applying conflicting decisions) — consolidate to one engine.

Related prompts

Newsletter

Get weekly AI workflows for DevOps engineers

Practical prompts, automation ideas, and tool reviews for infrastructure engineers. One email per week. No spam.