Documentation
Gatekeeper ¶
This package provides custom admission control using gatekeeper. Under the hood, gatekeeper uses Open Policy Agent to enforce policy when requests hit the Kubernetes API server.
Supported Providers ¶
The following table shows the providers this package can work with.
AWS | Azure | vSphere | Docker |
---|---|---|---|
✅ | ✅ | ✅ | ✅ |
Components ¶
- gatekeeper: Uses Open Policy Agent (OPA) to validate whether a request is authorized.
- audit-controller: Identifies existing resources in the cluster that break active policy.
Configuration ¶
The following configuration values can be set to customize the gatekeeper installation.
Global ¶
Value | Required/Optional | Description |
---|---|---|
namespace | Optional | The namespace in which to deploy gatekeeper. |
gatekeeper Configuration ¶
Currently there is no gatekeeper customization.
Usage Example ¶
This walkthrough demonstrates how to apply a policy that restricts root users from running containers. The gatekeeper project maintains a library of policies at github.com/open-policy-agent/gatekeeper-library. This walkthrough will leverage a policy from this repository.
Apply the following constraint template, which check for specified labels.
apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata: name: k8srequiredlabels annotations: description: Requires all resources to contain a specified label with a value matching a provided regular expression. spec: crd: spec: names: kind: K8sRequiredLabels validation: # Schema for the `parameters` field openAPIV3Schema: properties: message: type: string labels: type: array items: type: object properties: key: type: string allowedRegex: type: string targets: - target: admission.k8s.gatekeeper.sh rego: | package k8srequiredlabels get_message(parameters, _default) = msg { not parameters.message msg := _default } get_message(parameters, _default) = msg { msg := parameters.message } violation[{"msg": msg, "details": {"missing_labels": missing}}] { provided := {label | input.review.object.metadata.labels[label]} required := {label | label := input.parameters.labels[_].key} missing := required - provided count(missing) > 0 def_msg := sprintf("you must provide labels: %v", [missing]) msg := get_message(input.parameters, def_msg) } violation[{"msg": msg}] { value := input.review.object.metadata.labels[key] expected := input.parameters.labels[_] expected.key == key # do not match if allowedRegex is not defined, or is an empty string expected.allowedRegex != "" not re_match(expected.allowedRegex, value) def_msg := sprintf("Label <%v: %v> does not satisfy allowed regex: %v", [key, value, expected.allowedRegex]) msg := get_message(input.parameters, def_msg) }
Verify the
k8srequiredlabels
CRD was created.kubectl get crds | grep -i k8srequiredlabels
Create a constraint that requires the label
owner
to be specified.apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sRequiredLabels metadata: name: all-must-have-owner spec: match: kinds: - apiGroups: [""] kinds: ["Namespace"] parameters: message: "All namespaces must have an `owner` label" labels: - key: owner
Create a namespace
kubectl create ns test
Verify it fails to deploy due to missing label.
Error from server ([denied by all-must-have-owner] All namespaces must have an `owner` label): admission webhook "validation.gatekeeper.sh" denied the request: [denied by all-must-have-owner] All namespaces must have an `owner` label
Create a namespace with the owner label.
apiVersion: v1 kind: Namespace metadata: name: test labels: owner: bearcanoe
Example Mutation definitions
---
apiVersion: mutations.gatekeeper.sh/v1beta1
kind: Assign
metadata:
name: allow-privilege-escalation
spec:
match:
scope: Namespaced
kinds:
- apiGroups: ["*"]
kinds: ["Pod"]
applyTo:
- groups: [""]
kinds: ["Pod"]
versions: ["v1"]
location: "spec.containers[name:*].securityContext.allowPrivilegeEscalation"
parameters:
pathTests:
- subPath: "spec.containers[name:*].securityContext.allowPrivilegeEscalation"
condition: MustNotExist
assign:
value: false
---
apiVersion: mutations.gatekeeper.sh/v1alpha1
kind: AssignMetadata
metadata:
name: label-location
spec:
match:
scope: Namespaced
location: "metadata.labels.location"
parameters:
assign:
value: "Florida"