Skip to main content

How to use Gatekeeper

Gatekeeper uses the OPA Constraint Framework to describe and enforce policy. Look there for more detailed information on their semantics and advanced usage.

Constraint Templates#

Before you can define a constraint, you must first define a ConstraintTemplate, which describes both the Rego that enforces the constraint and the schema of the constraint. The schema of the constraint allows an admin to fine-tune the behavior of a constraint, much like arguments to a function.

Here is an example constraint template that requires all labels described by the constraint to be present:

apiVersion: templates.gatekeeper.sh/v1beta1kind: ConstraintTemplatemetadata:  name: k8srequiredlabelsspec:  crd:    spec:      names:        kind: K8sRequiredLabels      validation:        # Schema for the `parameters` field        openAPIV3Schema:          properties:            labels:              type: array              items: 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("you must provide labels: %v", [missing])        }

You can install this ConstraintTemplate with the following command:

kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/demo/basic/templates/k8srequiredlabels_template.yaml

Constraints#

Constraints are then used to inform Gatekeeper that the admin wants a ConstraintTemplate to be enforced, and how. This constraint uses the K8sRequiredLabels constraint template above to make sure the gatekeeper label is defined on all namespaces:

apiVersion: constraints.gatekeeper.sh/v1beta1kind: K8sRequiredLabelsmetadata:  name: ns-must-have-gkspec:  match:    kinds:      - apiGroups: [""]        kinds: ["Namespace"]  parameters:    labels: ["gatekeeper"]

You can install this Constraint with the following command:

kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/demo/basic/constraints/all_ns_must_have_gatekeeper.yaml

Note the match field, which defines the scope of objects to which a given constraint will be applied. It supports the following matchers:

  • kinds accepts a list of objects with apiGroups and kinds fields that list the groups/kinds of objects to which the constraint will apply. If multiple groups/kinds objects are specified, only one match is needed for the resource to be in scope.
  • scope accepts *, Cluster, or Namespaced which determines if cluster-scoped and/or namesapced-scoped resources are selected. (defaults to *)
  • namespaces is a list of namespace names. If defined, a constraint will only apply to resources in a listed namespace.
  • excludedNamespaces is a list of namespace names. If defined, a constraint will only apply to resources not in a listed namespace.
  • labelSelector is a standard Kubernetes label selector.
  • namespaceSelector is a standard Kubernetes namespace selector. If defined, make sure to add Namespaces to your configs.config.gatekeeper.sh object to ensure namespaces are synced into OPA. Refer to the Replicating Data section for more details.

Note that if multiple matchers are specified, a resource must satisfy each top-level matcher (kinds, namespaces, etc.) to be in scope. Each top-level matcher has its own semantics for what qualifies as a match. An empty matcher is deemed to be inclusive (matches everything). Also understand namespaces, excludedNamespaces, and namespaceSelector will match on cluster scoped resources which are not namespaced. To avoid this adjust the scope to Namespaced.