Gatekeeper/OPA constraints on a subset of namespaces without using labels

1/1/2020

I'm using gatekeeper/OPA to create constraints for various services I have running in specific namespaces. To do so, I'm relying on namespaceSelectors to match the constraint to only a set of namespaces. My CI/CD process is responsible for labeling all my custom namespaces with the required labels that my constraint will be looking for.

However I now need to make sure that no new namespace is created without the required labels (otherwise this namespace will ignore all my constraints). The fact that my CI/CD tooling applies these labels does not allow me to be certain that no other namespace has been created in my cluster without these labels.

If I apply the k8srequiredlabels[2] constraint template on all namespaces, this will find a violation on system namespaces such as kube-system. The gatekeeper constraints allow you to specify either of the following to match your constraint[1]:

labelSelector
namespaceSelector
namespaces list

Ideally I'd like to be able to say that I want to ensure that all namespaces have x labels on them, except the namespaces in an exclusion list (e.g kube-system). However there's no option to use the above 'Namespaces' list in an exclusive way and the other 2 options require someone to manually add labels to the newly created namespaces (which opens up room for error).

  • Any suggestions on how you can ensure that a subset of your clusters namespace's have x labels without having to manually label them and use a label/namespaceSelector?
  • How would you prevent a namespace from being created using OPA & Gatekeeper if it does not meet certain criteria such as having x label on it?

[1] https://github.com/open-policy-agent/gatekeeper/pull/131/files

[2] https://github.com/open-policy-agent/gatekeeper/blob/master/demo/agilebank/templates/k8srequiredlabels_template.yaml

-- keftes
kubernetes
open-policy-agent

2 Answers

1/10/2020

You can use Helm to dynamically assigning labels to specific namespaces.

The namespace value can be derived either from --namespace parameter which is the same namespace where helm chart is deployed to. In the charts it should be accessed with {{.Release.Namespace}} then. Or you can set these namespaces using --set when deploying helm chart with helm upgrade. If there are few environments you can access them as aliases in values.yaml and then set namespaces values for them like this:

helm upgrade \
   <chart_name> \
      <path_to_the_chart> \
        --set <environment_one>.namespace=namespace1 \
        --set <environment_two>.namespace=namespace2 \
...

Please take a look on: dynamic-namespace-variable.

To check if specific namespace has proper labels use Webhook admission controller.

Here you can find more information: webhook-admssion-controller.

-- MaggieO
Source: StackOverflow

2/15/2020

Problem 1 can be solved by using OPA itself. You can write mutating webhook using OPA (https://github.com/open-policy-agent/opa/issues/943) to add labels to your newly created namespaces or you can write a mutating controller (using Golang). Underneath both does the same thing.

For 2nd problem, you need to add validation rule in your rego files on namespace creation and verify if the label exists.

Extra relevant information: To perform actions on specific namespaces based on the label, you can add namesapceSelector in your validating/mutating webhook configuration.

-- anmol agrawal
Source: StackOverflow