Skip to main content
Version: Next

Customizing Startup Behavior

Allow retries when adding objects to OPA​

Gatekeeper's webhook servers undergo a bootstrapping period during which they are unavailable until the initial set of resources (constraints, templates, synced objects, etc...) have been ingested. This prevents Gatekeeper's webhook from validating based on an incomplete set of policies. This wait-for-bootstrapping behavior can be configured.

The --readiness-retries flag defines the number of retry attempts allowed for an object (a Constraint, for example) to be successfully added to OPA. The default is 0. A value of -1 allows for infinite retries, blocking the webhook until all objects have been added to OPA. This guarantees complete enforcement, but has the potential to indefinitely block the webhook from serving requests.

Enable profiling using pprof​

The --enable-pprof flag enables an HTTP server for profiling using the pprof library. By default, it serves to localhost:6060 but the port can be customized with the --pprof-port flag.

Disable certificate generation and rotation for Gatekeeper's webhook​

By default, Gatekeeper uses open-policy-agent/cert-controller to handle the webhook's certificate rotation and generation. If you want to use a third-party solution, you may disable the cert-controller feature using --disable-cert-rotation.

Disable OPA built-in functions​

The --disable-opa-builtin flag disables specific OPA built-ins functions. Starting with v3.8.0, Gatekeeper disables the http.send built-in function by default. For more information, please see external data.

[Alpha] Emit admission and audit events​

The --emit-admission-events flag enables the emission of all admission violations as Kubernetes events. This flag is in alpha stage and it is set to false by default.

The --emit-audit-events flag enables the emission of all audit violation as Kubernetes events. This flag is in alpha stage and it is set to false by default.

The --admission-events-involved-namespace flag controls which namespace admission events will be created in. When set to true, admission events will be created in the namespace of the object violating the constraint. If the object has no namespace (ie. cluster scoped resources), they will be created in the namespace Gatekeeper is installed in. Setting to false will cause all admission events to be created in the Gatekeeper namespace.

The --audit-events-involved-namespace flag controls which namespace audit events will be created in. When set to true, audit events will be created in the namespace of the object violating the constraint. If the object has no namespace (ie. cluster scoped resources), they will be created in the namespace Gatekeeper is installed in. Setting to false will cause all audit events to be created in the Gatekeeper namespace.

There are four types of events that are emitted by Gatekeeper when the emit event flags are enabled:

EventDescription
FailedAdmissionThe Gatekeeper webhook denied the admission request (default behavior).
WarningAdmissionWhen enforcementAction: warn is specified in the constraint.
DryrunViolationWhen enforcementAction: dryrun is specified in the constraint.
AuditViolationA violation is detected during an audit.

❗ Warning: if the same constraint and violating resource tuple was emitted for more than 10 times in a 10-minute rolling interval, the Kubernetes event recorder will aggregate the events, e.g.

39s         Warning   FailedAdmission   namespace/test      (combined from similar events):  Admission webhook "validation.gatekeeper.sh" denied request, Resource Namespace: , Constraint: ns-must-have-gk, Message: you must provide labels: {"gatekeeper"}

Gatekeeper might burst 25 events about an object, but limit the refill rate to 1 new event every 5 minutes. This will help control the long-tail of events for resources that are always violating the constraint.

[Alpha] Emit API server audit annotations for admission evaluations​

The --emit-admission-audit-annotations flag adds audit annotations to validation requests that reach Gatekeeper policy evaluation. It is disabled by default. When enabled, it annotates violations only unless --admission-audit-annotations-include-success=true is also set. Requests skipped before policy evaluation, such as excluded namespaces, are not annotated.

The validation webhook returns one evaluation entry in AdmissionResponse.auditAnnotations. The API server prefixes that key with the webhook name, producing validation.gatekeeper.sh/evaluation in the API audit event. Its versioned JSON value contains Gatekeeper's allowed decision, bounded summaries of deny, warn, and dryrun violations, the total and included violation counts, and a truncation indicator. The decision is specific to Gatekeeper; another admission plugin or a later API server error can still reject the request. Request identity belongs to the enclosing audit event and is not repeated in this payload. The AdmissionReview UID, event type, evaluated resource kind/version, resource labels, and Constraint annotations are also intentionally omitted. The value is limited to 10 KiB. Long messages, policy-provided details, or additional violations may be omitted, and the payload reports truncation.

With --admission-audit-annotations-include-success=true, an evaluation with no violations produces this custom annotation value; otherwise it produces no custom annotation:

{"schemaVersion":"v1","allowed":true,"violations":[],"totalViolations":0,"includedViolations":0,"truncated":false}

When admission audit annotations are enabled on a process performing the generate operation, generated ValidatingAdmissionPolicyBindings add the Kubernetes Audit action alongside Deny or Warn; dryrun already maps to Audit. Failed native validations therefore produce Kubernetes' standard validation.policy.admission.k8s.io/validation_failure annotation. Kubernetes controls that annotation's content and aggregation; it is not an exhaustive list of all matching bindings. By default, generated ValidatingAdmissionPolicies omit the custom evaluation marker and rely on this native failure annotation.

To also annotate successful evaluations, set --admission-audit-annotations-include-success=true. It defaults to false and has no effect unless --emit-admission-audit-annotations is enabled. Success here means zero violations, not simply an allowed request: deny, warn, and dryrun violations remain annotated regardless of this setting. When both flags are enabled, generated VAPs add an evaluation audit annotation with the value true when at least one binding evaluates the request. Kubernetes deduplicates this constant across matching bindings, keeping the value bounded without listing matching Constraint names. This option does not re-evaluate CEL expressions or change admission decisions. For Helm, set emitAdmissionAuditAnnotations=true for violations-only auditing, and also set admissionAuditAnnotationsIncludeSuccess=true to include successful evaluations. If the webhook and native VAP enforcement points both evaluate a request, both may add audit entries.

For split deployments, configure both flags consistently on the validation webhook process and the process performing the generate operation. Restart the affected processes when changing these startup settings; generated VAPs are reconciled to the selected mode. API server audit logging must be enabled at Metadata or a higher level. Audit annotations do not create Kubernetes Event resources, do not annotate admitted objects, and do not change admission decisions. The violation-export payload is unaffected by these settings. Policy messages and details may contain user-controlled or sensitive data, so protect access to the audit backend.

[Beta] Enable mutation logging and annotations​

The --log-mutations flag enables logging of mutation events and errors.

The --mutation-annotations flag adds the following two annotations to mutated objects:

AnnotationValue
gatekeeper.sh/mutation-idThe UUID of the mutation.
gatekeeper.sh/mutationsA list of comma-separated mutations in the format of <MutationType>/<MutationNamespace>/<MutationName>:<MutationGeneration> that are applied to the object.

❗ Note that this will break the idempotence requirement that Kubernetes sets for mutation webhooks. See the Kubernetes docs here for more details

[Alpha] Remote Cluster Mode for Gatekeeper​

The --enable-remote-cluster flag enables Gatekeeper to run in a local (management) cluster while enforcing policies on a separate target cluster specified via --kubeconfig. This is designed for hosted control plane architectures where the target cluster's API server runs within the management cluster.

📖 For a full end-to-end setup walkthrough, installing CRDs across both clusters, deploying Gatekeeper, wiring webhook certificates, and a smoke test see the Remote Cluster Mode guide.

When to Use​

Use remote cluster mode when:

  • Gatekeeper runs in a local (management) cluster
  • You want to enforce policies on a remote target cluster

Configuration​

--enable-remote-cluster            # Enable remote cluster mode
--kubeconfig=/path/to/target.yaml # Kubeconfig for target cluster

How It Works​

Status resources live on the management cluster alongside the Gatekeeper pod, with OwnerReferences pointing to the pod. This enables automatic garbage collection — when a pod restarts, Kubernetes cleans up its old status resources automatically.

RBAC Requirements​

Gatekeeper needs permissions on the management/local cluster to resolve its pod identity and manage status resources:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: gatekeeper-manager-role
namespace: gatekeeper-system
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get"]
- apiGroups: ["status.gatekeeper.sh"]
resources: ["*"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

Migration from Previous Versions​

If upgrading from a version where --enable-remote-cluster stored status resources on the target cluster, you may have orphaned status resources on the target cluster. Run the following to clean them up:

kubectl delete constrainttemplatepodstatuses,constraintpodstatuses,mutatorpodstatuses,expansiontemplatepodstatuses,configpodstatuses,providerpodstatuses,connectionpodstatuses \
-n gatekeeper-system --all --context <target-cluster-context>

This is a one-time cleanup. After upgrading, status resources are automatically managed on the management cluster.

# List all pod names referenced in status resources (repeat for each status type)
kubectl get constrainttemplatepodstatuses -n gatekeeper-system \
-o jsonpath="{.items[*].metadata.labels['gatekeeper\.sh/pod']}" | tr ' ' '\n' | sort -u

# Compare with running Gatekeeper pods in local cluster
kubectl get pods -n gatekeeper-system -l control-plane=controller-manager -o name

To clean up orphaned resources after identifying old pod names:

# Delete status resources for a specific old pod
OLD_POD="gatekeeper-controller-manager-old-xyz"
kubectl delete constrainttemplatepodstatuses,constraintpodstatuses,mutatorpodstatuses,expansiontemplatepodstatuses,configpodstatuses,providerpodstatuses,connectionpodstatuses \
-n gatekeeper-system -l gatekeeper.sh/pod=$OLD_POD

Other Configuration Options​

For the complete list of configuration flags for your specific version of Gatekeeper, run the Gatekeeper binary with the --help flag. For example:

docker run openpolicyagent/gatekeeper:v3.10.0-beta.0 --help

To ensure you are seeing all relevant flags, be sure the image tag (:3.10.0-beta.0 above) corresponds with the version of Gatekeeper you are running.