kyverno / policies

Kyverno policies for security and best practices
Apache License 2.0
323 stars 233 forks source link

[Question] How to match PATCH requests? #1138

Open Da-Juan opened 2 weeks ago

Da-Juan commented 2 weeks ago

Hi,

I'm looking to create a validate policy to allow users to use kubectl rollout restart. Rollout restart creates a PATCH request that sets the annotation kubectl.kubernetes.io/restartedAt on the resources.

I tried with a match on UPDATE operations but it doesn't seem to catch PATCH requests.

Do you have any idea if it is possible to create such policy?

Thanks

realshuting commented 2 weeks ago

What resource are you selecting in the policy? Can you share the policy please?

Da-Juan commented 2 weeks ago

I tried to select deployments, statefulsets and daemonsets as we allow patch only on these resources with the RBAC.

Here is the policy I tried:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: restrict-patch-to-rollout-restart
spec:
  validationFailureAction: Enforce
  background: false
  rules:
    - name: restrict-patch
      match:
        any:
          - resources:
              kinds:
                - Deployment
                - StatefulSet
                - DaemonSet
              operations:
                - UPDATE
            clusterRoles:
              - namespace-owner
      validate:
        message: "PATCH is allowed only for rollout-restarts"
        pattern:
          metadata:
            annotations:
              kubectl.kubernetes.io/restartedAt: "?*"
realshuting commented 2 weeks ago

Does the policy work if you remove this?

            clusterRoles:
              - namespace-owner
Da-Juan commented 2 weeks ago

I just tried this I can perform a rollout restart on my test deployment but I can also do a kubectl edit on the deployment and change the requests/limits for example.

Here is my test deployment manifest:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        resources:
          requests:
            memory: "32Mi"
            cpu: "250m"
          limits:
            memory: "32Mi"
            cpu: "500m"
realshuting commented 2 weeks ago

When you define a clusterroles in the match block it means only requests sent by the ClusterRolenamespace-owner are processed.

Da-Juan commented 2 weeks ago

Yes, that's what I want. I want my policy to match only namespace owners users but not other service accounts like fluxcd for example.

realshuting commented 2 weeks ago

Yes, that's what I want. I want my policy to match only namespace owners users but not other service accounts like fluxcd for example.

Is your namespace owner defined by the clusterrole namespace-owner? If not, you need to specify the exact names of those clusterroles. You can also inspect the user info in admission requests by setting --dumpPayload container flag for the admission controller.

Da-Juan commented 2 weeks ago

Yes the namespace owners are users that have a RoleBinding on the namespace-owner ClusterRole. But this is not my problem here.

What I'm looking to do is to allow my namespace owners to use kubectl rollout restart but forbid them to use kubectl edit on the same resources.