<p>I have a multi-tenant Kubernetes cluster. On it I have an nginx reverse proxy with load balancer and the domain <code>*.example.com</code> points to its IP.</p>
<p>Now, several namespaces are essentially grouped together as project A and project B (according to the different users).</p>
<p>How, can I ensure that any service in a namespace with label <code>project=a</code>, can have any domain like <code>my-service.project-a.example.com</code>, but not something like <code>my-service.project-b.example.com</code> or <code>my-service.example.com</code>? Please keep in mind, that I use NetworkPolicies to isolate the communication between the different projects, though communication with the nginx namespace and the reverse proxy is always possible.</p>
<p>Any ideas would be very welcome.</p>
<hr />
<p><strong>EDIT:</strong></p>
<p>I made some progress as have been deploying Gatekeeper to my GKE clusters via Helm charts. Then I was trying to ensure that only Ingress hosts of the form &quot;<em>.project-name.example.com&quot; should be allowed. For this, I have different namespaces that each have labels &quot;project=a&quot; or similar and each of these should only allow to use ingress of the form &quot;</em>.a.example.com&quot;. Hence I need that project label information for the respective namespaces. I wanted to deploy the following resources</p>
<pre><code>apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: k8srequiredingress
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredIngress
      validation:
        # Schema for the `parameters` field
        openAPIV3Schema:
          type: object
          properties:
            labels:
              type: array
              items:
                type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequiredingress

        operations := {&quot;CREATE&quot;, &quot;UPDATE&quot;}
        ns := input.review.object.metadata.namespace


        violation[{&quot;msg&quot;: msg, &quot;details&quot;: {&quot;missing_labels&quot;: missing}}] {
          input.request.kind.kind == &quot;Ingress&quot;
          not data.kubernetes.namespaces[ns].labels.project

          msg := sprintf(&quot;Ingress denied as namespace '%v' is missing 'project' label&quot;, [ns])
        }


        violation[{&quot;msg&quot;: msg, &quot;details&quot;: {&quot;missing_labels&quot;: missing}}] {
          input.request.kind.kind == &quot;Ingress&quot;
          operations[input.request.operation]

          host := input.request.object.spec.rules[_].host
          project := data.kubernetes.namespaces[ns].labels.project
          not fqdn_matches(host, project)
          msg := sprintf(&quot;invalid ingress host %v, has to be of the form *.%v.example.com&quot;, [host, project])

        }

        fqdn_matches(str, pattern) {
          str_parts := split(str, &quot;.&quot;)
          count(str_parts) == 4
          str_parts[1] == pattern
        }

---

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredIngress
metadata:
  name: ns-must-have-gk
spec:
  match:
    kinds:
      - apiGroups: [&quot;&quot;]
        kinds: [&quot;Ingress&quot;]

---

apiVersion: config.gatekeeper.sh/v1alpha1
kind: Config
metadata:
  name: config
  namespace: &quot;gatekeeper-system&quot;
spec:
  sync:
    syncOnly:
      - group: &quot;&quot;
        version: &quot;v1&quot;
        kind: &quot;Namespace&quot;
</code></pre>
<p>However, when I try to setup everything in the cluster I keep getting:</p>
<pre><code>kubectl apply -f constraint_template.yaml

Error from server: error when creating &quot;constraint_template.yaml&quot;: admission webhook &quot;validation.gatekeeper.sh&quot; denied the request: invalid ConstraintTemplate: invalid data references: check refs failed on module {template}: errors (2):
disallowed ref data.kubernetes.namespaces[ns].labels.project
disallowed ref data.kubernetes.namespaces[ns].labels.project
</code></pre>
<p>Do you know how to fix that and what I did wrong. Also, in case you happen to know a better approach just let me know.</p>

<p>Alternative to other answer, you may use validation webhook to enfore by any parameter present in the request. Example, name,namespace, annotations, spec etc.</p>
<p>The validation webhook could be a service running in the cluster or External to cluster. This service would essentially make a logical decision based on the logic we put. For every request Sent by user, api server send a review request to the webhook and the validation webhook would either approve or reject the review.</p>
<p>You can read more about it <a href="https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#configure-admission-webhooks-on-the-fly" rel="nofollow noreferrer">here</a>,  more descriptive post by me <a href="https://technekey.com/what-is-validation-webhook-in-kubernetes/" rel="nofollow noreferrer">here</a>.</p>
