apiVersion: templates.gatekeeper.sh/v1alpha1 kind: ConstraintTemplate metadata: name: requiredannotations spec: crd: spec: names: kind: RequiredAnnotations listKind: RequiredAnnotationsList plural: requiredannotations singular: requiredannotations validation: # Schema for the `parameters` field openAPIV3Schema: properties: labels: type: array items: string targets: - target: admission.k8s.gatekeeper.sh rego: | package requiredannotations violation[{"msg": msg, "details": {"Invalid namespace": ns}}] { # Check if the actual user is one of the restricted_users actual_user := {input.review.userInfo.username} restricted_users := {username | username := input.constraint.spec.parameters.usernames[_]} # Check if the namespace is annotated with the required labels ns := input.review.object.metadata.namespace real_ns := data.inventory.cluster.v1.Namespace[ns] actual := {annotation | annotation := real_ns.metadata.annotations["category"]} required := {annotation | annotation := input.constraint.spec.parameters.annotations[_]} count(actual_user - restricted_users) == 0 count(required & actual) == 0 msg := sprintf("Missing labels for username %v namespace %v: Required one of labels: %v Actual labels: %v", [actual_user, ns, required, actual]) }