Search code examples
kuberneteskubernetes-podkubernetes-psp

Why is my PodSecurityPolicy applied even if I don't have access?


I have two PodSecurityPolicy:

  • 000-privileged (only kube-system service accounts and admin users)
  • 100-restricted (everything else)

I have a problem with their assignment to pods.

First policy binding:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: psp:privileged
rules:
- apiGroups:
  - extensions
  resources:
  - podsecuritypolicies
  resourceNames:
  - 000-privileged
  verbs:
  - use
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: psp:privileged-kube-system
  namespace: kube-system
subjects:
- kind: Group
  name: system:serviceaccounts
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: psp:privileged
  apiGroup: rbac.authorization.k8s.io

Second policy binding:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: psp:restricted
rules:
- apiGroups:
  - extensions
  resources:
  - podsecuritypolicies
  resourceNames:
  - 100-restricted
  verbs:
  - use
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: psp:restricted
subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io
- kind: Group
  name: system:serviceaccounts
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: psp:restricted
  apiGroup: rbac.authorization.k8s.io

Everything works fine in kube-system.

However, in other namespaces, it does not work as expected:

  • If I create a Deployment (kubectl apply -f deployment.yml), its pod gets tagged with psp 100-restricted.

  • If I create a Pod (kubectl apply -f pod.yml), it gets tagged with psp 000-privileged. I really don't get why its not 100-restricted.

My kubectl is configured with external authentication token from OpenID Connect (OIDC).

I verified the access and everything seems ok:

kubectl auth can-i use psp/100-restricted
yes
kubectl auth can-i use psp/000-privileged
no

Any clue?


Solution

  • The problem was that my user had access to all verbs (*) of all resources (*) of the 'extensions' apiGroup in its Role.

    The documentation is a bit unclear (https://github.com/kubernetes/examples/tree/master/staging/podsecuritypolicy/rbac):

    The use verb is a special verb that grants access to use a policy while not permitting any other access. Note that a user with superuser permissions within a namespace (access to * verbs on * resources) would be allowed to use any PodSecurityPolicy within that namespace.

    I got confused by the mention of 'within that namespace'. Since PodSecurityGroup are not "namespaced", I assumed they could not be used without a ClusterRole/RoleBinding in the namespace giving explicit access. Seems I was wrong...

    I modified my role to specify the following:

    rules:
    - apiGroups: ["", "apps", "autoscaling", "batch"]
      resources: ["*"]
      verbs: ["*"]
    - apiGroups: ["extensions"]
      resources: ["*"]
      # Avoid using * here to prevent use of 'use' verb for podsecuritypolicies resource
      verbs: ["create", "get", "watch", "list", "patch", "delete", "deletecollection", "update"]
    

    And now it picks up the proper PSP. One interesting thing, it also prevent users from modifying (create/delete/update/etc) podsecuritypolicies.

    It seems 'use' verb is quite special after all.....