What does Gatekeeper's gator test command evaluate, and what must you feed it?
answer
- runs where no API server exists
- everything arrives as plain YAML
- rules and objects in one stream
- exit code is what gates the merge
basics
~20 sgator test evaluates Gatekeeper policy locally: you hand it ConstraintTemplates, their Constraints, and the Kubernetes objects to review, and it reports which object violated which constraint. It needs no cluster, no kubeconfig and no admission webhook.
solid answer
~40 s`gator` is the CLI that ships with Gatekeeper, and `gator test` runs the same policy evaluation the admission webhook would, entirely offline. You pass it one stream of Kubernetes YAML — the `ConstraintTemplate` that holds the rule, the `Constraint` that scopes it and sets `enforcementAction`, and the manifests you want reviewed — via `-f/--filename` on files or directories, or on stdin. It prints each violation with the constraint that fired and the message the rule returned, and it exits non-zero when a violation comes from a deny-enforced constraint, which is what makes it usable as a pre-merge check in the rule repository's own CI. It reviews only what you give it: nothing is fetched from an API server, so a rule that expects to see other cluster objects needs those supplied as fixtures too.
go deeper
Be ready to say what the three input kinds are — template, constraint, objects — and that no cluster is involved. Knowing the command exists and produces a pass/fail with a message is most of what is asked here.
Explain how the tool classifies each YAML document, what the exit code depends on, and why a rule that reads other cluster objects needs those handed to it as fixtures rather than fetched.
Show where this sits in a rule repository's pipeline: a credential-free pre-merge check, structured output parsed by the job, and a clear account of which failures it can and cannot catch before a constraint reaches a cluster.
Own the argument that policy is a software product with its own test suite and release path. The value of an offline runner is that a rule change gets reviewed and proven like any other code, without a shared cluster becoming the bottleneck.
## Why an offline runner exists at all Gatekeeper expresses policy as ordinary Kubernetes API objects. A `ConstraintTemplate` carries the rule and the schema for its parameters; applying it creates a CRD, and a `Constraint` is an instance of that CRD saying where the rule applies (`spec.match`) and how hard it bites (`spec.enforcementAction`). That packaging is convenient in a cluster and awkward in CI: the natural way to test it would be to stand up a cluster, install Gatekeeper, apply the policy and try to create a bad object. `gator` exists so you do not have to. It embeds the same constraint-framework evaluation the admission webhook uses, so the verdict you get on a laptop is the verdict the webhook would give for the same object. ## The input is one stream of manifests `gator test` reads Kubernetes YAML documents from files or directories (`-f/--filename`, repeatable) or from standard input, and sorts each document by kind: - `ConstraintTemplate` documents become the available rules. - `Constraint` documents (instances of the CRDs those templates define) become the enforced policy, each with its own match block and enforcement action. - Everything else — a Deployment, a Pod, a Namespace, a PodDisruptionBudget — is treated as an object to review, or as context the rules may read. Because the input is just YAML, anything that can render YAML can feed it: a directory of example manifests committed next to the rule, or the rendered output of your templating step piped in. It reviews concrete manifests, not templates, so render first. ## What it prints and what it returns For every object that fails, it names the constraint that rejected it and the message the rule returned, and it can emit structured output (`-o json` / `-o yaml`) when a CI step needs to parse rather than read the result. The exit code is the part that matters for automation: a violation of a constraint enforced with `deny` (the default) makes the command exit non-zero; violations reported by a constraint set to `dryrun` or `warn` are printed but do not by themselves fail the run. An error — an unreadable file, a template that will not compile — also fails, and that is a feature: a rule repository should not merge a template that does not build. ## What it deliberately does not do - It does not talk to an API server. There is no kubeconfig, no service account, no network dependency, which is what makes it safe to run on every pull request. - It says nothing about objects already running. Judging live objects is Gatekeeper's audit loop in the cluster, not this command. - A green run does not prove the constraint is installed in any cluster, or that it is enforcing there rather than sitting in dry-run. - It is not a Rego unit-test runner. It exercises the whole packaging — template plus constraint plus a real Kubernetes object — rather than the rule body in isolation, which is why it catches packaging mistakes (a wrong `kinds` entry, a parameter name that does not match the schema) that a rule-level test cannot see. ## A worked example Say the platform team ships an availability rule: any Deployment with more than one replica must be covered by a PodDisruptionBudget. The rule repository holds `template.yaml`, `constraint.yaml`, and a folder of example workloads. `gator test` over that folder answers a narrow but valuable question before anyone merges: given these exact rules, do these exact manifests pass or fail, and with what message? A three-replica Deployment with no matching budget should fail with a message a developer can act on; a single-replica Deployment should pass. If the rule needs to know which PodDisruptionBudgets exist, those objects have to be part of the input as well — offline means offline, and the tool will not invent cluster state for you. ## Where it belongs The natural home is a pre-merge check on the constraint repository itself, running with no cluster and no credentials anywhere in the job. That keeps the feedback loop for a rule change measured in seconds and keeps a broken rule from ever reaching a cluster — which is the whole point of treating a guardrail as code that has its own tests.
- Can you pipe rendered Helm or Kustomize output straight into gator test?Yes. It reads YAML documents from stdin as happily as from files, so rendering your workloads and piping them in works. Render first, though — it reviews concrete Kubernetes objects, not charts or overlays, so an unrendered template is just an object it cannot make sense of.
- What does a green gator test run not tell you about your clusters?Almost everything operational. It does not show that the constraint is installed anywhere, that it is enforcing rather than in dry-run there, or that the objects already running comply — that last one is the job of Gatekeeper's in-cluster audit. It proves only that these rules, on these manifests, produce these verdicts.
- Why must the ConstraintTemplate be in the input and not just the Constraint?The Constraint is an instance of a CRD that the template defines, and the rule body lives in the template. Without the template there is no rule to run and no CRD kind to recognise, so the constraint is meaningless — in a cluster the CRD already exists, but offline you supply both halves.
It is a flight simulator for the admission webhook: same instruments, same decisions, no aircraft and no runway.
saying these in an interview costs you the question
- Thinks gator test needs a kubeconfig or a live cluster
- Passes only the objects and forgets the ConstraintTemplate
- Reads a green run as proof the constraint is enforcing in production
- Confuses reviewing manifests with auditing objects already running
- Expects gator to fetch other cluster objects the rule depends on