Which Policies Govern This Resource? Mapping Gatekeeper & Kyverno in Kubernetes

You've rolled out admission control — Gatekeeper for the org-wide guardrails, Kyverno for the team-specific ones — and the cluster is quietly enforcing dozens of rules. Then a question arrives that the tooling makes surprisingly hard: which policies actually apply to this Deployment, and is anything it owns violating one right now?

This guide works backward from that question. We'll look at why listing policies is easy but mapping their coverage is not, and how KubeAtlas v1.4 turns "which rules govern this resource" into a single query — on the graph, in the API, or in an offline report.

Why this is hard with native tooling

Both engines store their rules as their own custom resources: Gatekeeper as ConstraintTemplates plus the generated Constraint CRDs, Kyverno as ClusterPolicy and Policy objects. Listing them is trivial:

kubectl get constraints -A          # Gatekeeper
kubectl get clusterpolicies,policies -A   # Kyverno

But that list is the easy 20%. The questions that actually matter in an audit or an incident are harder:

The hidden factor most teams overlook: the dangerous gap isn't a missing policy, it's a policy you assume covers something that it doesn't. A Constraint scoped to the wrong namespace selector looks healthy — zero violations — precisely because it governs nothing.

Working backward: what a real answer looks like

The end goal is one relationship, queryable in both directions: policy → governs → resource, carrying the current violation state. That requires three things:

  1. Discover every policy across both engines — including Constraints created from a ConstraintTemplate long after the tool started.
  2. Model the relationship as a typed edge, so "what governs this resource" is as cheap as "what does this policy govern".
  3. Attach live violation status to each edge, in one normalized shape, regardless of which engine produced it.

This is exactly what KubeAtlas v1.4 adds to its dependency graph.

How KubeAtlas models it: ENFORCES edges

v1.4 introduces a new edge type — ENFORCES — drawn from each policy to the resources it governs, tagged with current violation status. Gatekeeper Constraints and Kyverno ClusterPolicies/Policies are watched continuously and projected onto the same graph as your workloads, config, and RBAC, so a policy is just another node with edges you can traverse.

The discovery is the interesting part. A naïve watcher would miss any Constraint whose CRD didn't exist at startup. KubeAtlas runs an informer-of-informers: it watches ConstraintTemplates and, whenever one generates a new Constraint CRD, registers an informer for it at runtime. Policies that appear after the tool is running are picked up automatically — no restart, no redeploy.

Good to know: the ENFORCES edges are purely additive — they sit alongside the existing dependency edges and change nothing about how the graph is built. KubeAtlas only renders edges for the engines you actually run; if a cluster has Gatekeeper but not Kyverno, you simply see the Gatekeeper half.

Step 1 — Upgrade to v1.4.0

Policy visibility ships in v1.4.0. If you're already running KubeAtlas, upgrade the chart; if not, the in-memory install is the fastest start:

helm upgrade --install kubeatlas oci://ghcr.io/lithastra/charts/kubeatlas \
  --version 1.4.0 \
  --namespace kubeatlas --create-namespace

kubectl -n kubeatlas rollout status deploy/kubeatlas
kubectl -n kubeatlas port-forward svc/kubeatlas 8080:80

KubeAtlas needs read access to the policy CRDs (Constraints, ConstraintTemplates, ClusterPolicies, Policies); the bundled ClusterRole already includes them.

Step 2 — Explore in the Policy view

Open http://localhost:8080 and switch to the new Policy view. It lists every Constraint and Kyverno policy in force and styles ENFORCES edges distinctly on the canvas, so you can:

Step 3 — Query it from the API

The same data is available through engine-aware endpoints, which is what you'd wire into a dashboard or a periodic check:

# every policy in force, both engines
curl -s localhost:8080/api/v1/policy/constraints | jq '.[].name'

# narrow to one engine
curl -s 'localhost:8080/api/v1/policy/constraints?engine=gatekeeper'
curl -s 'localhost:8080/api/v1/policy/constraints?engine=kyverno'

# the resources a given policy governs, with per-resource violation state
curl -s localhost:8080/api/v1/policy/constraints/require-run-as-nonroot/affected

The /affected response is the one that pays off in practice: it returns the resolved set of governed resources — the same edges you see on the canvas — each annotated with whether it currently passes or violates, so you can answer "is anything under this policy actually broken?" without touching two engines' status formats.

Step 4 — Air-gapped audits and CI: the diagnostic report

The Policy view is for exploring interactively; auditors and pipelines want an artifact. v1.4 adds a self-contained offline diagnostic report that runs against your current KUBECONFIG and needs no running server:

# generate a report from the current cluster context
kubeatlas diagnose

# or pull it from a running instance as JSON
curl -s localhost:8080/api/v1/diagnose | jq '.policyViolations'

The report snapshots the whole dependency graph — orphans, cycles, the top blast-radius resources — and renders as either HTML (deliberately air-gapped: no external CDN or font references, so it opens on an isolated network) or JSON. Crucially, the JSON carries a normalized policyViolations array distilled from the ENFORCES edges, so a Gatekeeper failure and a Kyverno failure arrive in one engine-agnostic shape your automation can consume without special-casing either engine.

Beyond the core: the same release adds a Headlamp Policy view and a policy-report option for the kubeatlas-action GitHub Action, which appends a policy-violation summary to the pull-request comment — so a change that would trip a Constraint is flagged in review, before it merges. Exact flags and output formats are in the documentation.

The owl's-eye summary

QuestionNative toolingKubeAtlas v1.4
Which policies exist?kubectl get per engineOne Policy view, both engines
Which policies govern resource X?Evaluate selectors by handReverse ENFORCES edges, one query
What does policy Y actually cover?Hope the selector is rightResolved affected set on the graph
Is anything violating, across engines?Reconcile two status formatsNormalized policyViolations
Hand an auditor a snapshot?ScreenshotsSelf-contained offline report

Admission policies are only as good as their coverage, and coverage is invisible until something is on the graph next to the resources it's supposed to protect. Put the policies on the map, and "which rules govern this — and is it passing?" becomes a question with a one-query answer.