gatekeeper icon indicating copy to clipboard operation
gatekeeper copied to clipboard

Resource violates rule but is created

Open danie1sullivan opened this issue 1 year ago • 4 comments

What steps did you take and what happened: [A clear and concise description of what the bug is.]

I have created a rule to block webhook configurations that do not have namespace selectors, unless exempt.

Constraint
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequireWebhookNamespaces
metadata:
  name: require-webhook-namespaces
spec:
  enforcementAction: deny
  match:
    scope: "*"
    kinds:
      - apiGroups: ["admissionregistration.k8s.io"]
        kinds: ["ValidatingWebhookConfiguration", "MutatingWebhookConfiguration"]
  parameters:
    exemptWebhooks: []
Template
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8srequirewebhooknamespaces
spec:
  crd:
    spec:
      names:
        kind: K8sRequireWebhookNamespaces
      validation:
        openAPIV3Schema:
          type: object
          properties:
            exemptWebhooks:
              type: array
              items: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequirewebhooknamespaces

        import future.keywords.if
        import future.keywords.in

        violation[{"msg": msg}] {
          not is_exempt(input.review.object.metadata.name)
          some webhook in input.review.object.webhooks
          not has_selectors(webhook)
          msg := sprintf("Webhook missing valid namespace selector: %v", [webhook.name])
        }

        has_selectors(wh) if {
          wh.namespaceSelector
          count(wh.namespaceSelector.matchExpressions) > 0
          some match in wh.namespaceSelector.matchExpressions
          required := {"key", "operator", "values"}
          found := object.keys(match)
          found == required
        }

        is_exempt(name) if {
          exempt := input.parameters.exemptWebhooks
          some webhook in exempt
          webhook == name
        }

This test resource is still able to be created:

Test Resource
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: test-webhook-admission
webhooks:
  - admissionReviewVersions:
      - v1
      - v1beta1
    clientConfig:
      service:
        name: test-webhook-service
        path: /validate-tests
        port: 443
    failurePolicy: Fail
    matchPolicy: Equivalent
    namespaceSelector: {}

    name: testtrigger.example.com
    rules:
      - apiGroups:
          - tests.example.com
        apiVersions:
          - v1
        operations:
          - CREATE
          - UPDATE
        resources:
          - testtriggers
        scope: '*'
    sideEffects: None
    timeoutSeconds: 10

What did you expect to happen:

I expected the test resource to be denied. It is denied when testing locally with gator:

Gator
$ gator test -f resource.yaml -f constraint.yaml -f template.yaml
admissionregistration.k8s.io/v1/ValidatingWebhookConfiguration test-webhook-admission: ["require-webhook-namespaces"] Message: "Webhook missing valid namespace selector: testtrigger.example.com"

The resource also shows in the Constraint as a violation:

Violation
$ kubectl get k8srequirewebhooknamespaces -o jsonpath='{.items[0].status.violations}' | jq .
[
  {
    "enforcementAction": "deny",
    "group": "admissionregistration.k8s.io",
    "kind": "ValidatingWebhookConfiguration",
    "message": "Webhook missing valid namespace selector: testtrigger.example.com",
    "name": "test-webhook-admission",
    "version": "v1"
  }
]

Anything else you would like to add: [Miscellaneous information that will assist in solving the issue.]

It seems that the creation event is never evaluated by Gatekeeper. We have several other rules that are correctly being enforced, so I assume it is not a general problem with our Gatekeeper deployment.

Gatekeeper is deployed using the Helm chart and is minimally altered. The rules for the validation webhook are default:

Webhook rules
$ kubectl get ValidatingWebhookConfiguration gatekeeper-validating-webhook-configuration -o jsonpath='{.webhooks[?(@.name=="validation.gatekeeper.sh")].rules}' | jq .
[
  {
    "apiGroups": [
      "*"
    ],
    "apiVersions": [
      "*"
    ],
    "operations": [
      "CREATE",
      "UPDATE"
    ],
    "resources": [
      "*",
      "pods/ephemeralcontainers",
      "pods/exec",
      "pods/log",
      "pods/eviction",
      "pods/portforward",
      "pods/proxy",
      "pods/attach",
      "pods/binding",
      "deployments/scale",
      "replicasets/scale",
      "statefulsets/scale",
      "replicationcontrollers/scale",
      "services/proxy",
      "nodes/proxy",
      "services/status"
    ],
    "scope": "*"
  }
]

It's entirely possible (or likely) that this is not a bug and I've missed something, but at this point I'm out of ideas.

Environment:

  • Gatekeeper version: 3.14.0
  • Kubernetes version: (use kubectl version):
Client Version: v1.28.2
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.28.4-eks-8cb36c9

danie1sullivan avatar Jan 12 '24 11:01 danie1sullivan

Kubernetes webhooks cannot evaluate ValidatingWebhookConfiguration/MutatingWebhookConfiguration objects.

ValidatingAdmissionPolicy might be able to, but there is a similar problem there (VAP objects cannot validate other VAP objects).

Violations should show up in audit.

K8s doc source: see the docstring for the rules field here: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#validatingwebhook-v1-admissionregistration-k8s-io

maxsmythe avatar Jan 12 '24 21:01 maxsmythe

Thanks @maxsmythe , I had suspected that but didn't know where to look. That answers my question, but should this issue then be considered a bug for gator?

danie1sullivan avatar Jan 15 '24 09:01 danie1sullivan

Thanks @maxsmythe , I had suspected that but didn't know where to look. That answers my question, but should this issue then be considered a bug for gator?

I have a similar issue which the policy is being flagged but Gatekeeper lets the resource to be created. https://github.com/open-policy-agent/gatekeeper/issues/3228

soroushatarod avatar Jan 18 '24 22:01 soroushatarod

Gatekeeper the webhook cannot/should not validate these resources. Gatekeeper audit and the gator CLI command should be able to validate them.

maxsmythe avatar Jan 26 '24 22:01 maxsmythe

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Mar 30 '24 12:03 stale[bot]