OPA Gatekeeper: Globally restrict it's scope to selected namespaces

Kubernetes OPA gatekeeper scope labels

2 min read | by Jordi Prats

To prevent OPA Gatekeeper to apply rules to some namespaces we can add exclusions at the rule level but this can be very inconvenient since we would need to add it to every single rule. A change on these exclusion list can be a pain as well.

We can configure the ValidatingWebhookConfiguration to restrict it globally to namespaces that have a some label.

To be able to restrict to which namespaces we want it to apply rules we'll need to update the namespaceSelector.matchExpressions property for the validation.gatekeeper.sh webhook adding the label we want to use with the operator Exists:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  labels:
    gatekeeper.sh/system: "yes"
  name: gatekeeper-validating-webhook-configuration
webhooks:
- admissionReviewVersions:
  - v1
  - v1beta1
  clientConfig:
    service:
      name: gatekeeper-webhook-service
      namespace: gatekeeper-system
      path: /v1/admit
  failurePolicy: Ignore
  matchPolicy: Exact
  name: validation.gatekeeper.sh
  namespaceSelector:
    matchExpressions:
    - key: admission.gatekeeper.sh/ignore
      operator: DoesNotExist
    - key: namespace.owner
      operator: Exists
  rules:
(...)

We can test it by creating a rule without any exclusions:

$ kubectl get K8sBlockNodePort block-node-port -o jsonpath='{.spec}'
{"enforcementAction":"deny"}

Then we can create a namespace with the label that we are using to trigger OPA gatekeeper:

apiVersion: v1
kind: Namespace
metadata:
  labels:
    namespace.owner: pet2cattle
  name: demo-ns

And test it creating an object that we know it will trigger the rule:

$ kubectl apply -f testPod.yaml -n pet2cattle
Error from server (Forbidden): error when creating "testPod.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [restrict-tolerations] found restricted toleration(s)

On the other hand, for any other namespace that doesn't have that label it won't prevent us from creating the object:

$ kubectl apply -f testPod.yaml -n another-ns
pod/pod-tolerations-test created

Posted on 23/11/2022