Alcide Rapid 7 Logo Alcide Rapid 7 Logo
Alcide has been acquired by Rapid7- a leading provider of security analytics and automation. Learn more

Pod Security Policy

October 24, 2019

for bllog article page-Pod Security Policy

What is Pod Security Policy?

The Pod Security Policy, sometimes called PSP in short, is a Kubernetes resource that allows the enforcement of policy rules during the creation phase of a Pod.
When a PodSecurityPolicy resource is created, it does nothing. In order to use it, the requesting user or target pod’s service account must be authorized to use the policy, by allowing the use verb on the policy.


Most Kubernetes pods are not created directly by users. Instead, they are typically created indirectly as part of a Deployment, ReplicaSet, or other templated controller via the controller manager. Granting the controller access to the policy would grant access for all pods created by that controller, so the preferred method for authorizing policies is to grant access to the pod’s service account 

For example, if one wishes to make sure that Pod with root privileges can only be created by the cluster administrator and not by any other user then the following operations will do the trick:

  • Define a Pod Security Policy that deny the creation of Pod with root privileges
  • Associate the Pod Security Policy with Role or a Cluster Role that is binded to non-admin        users
  • Define a Pod Security Policy that allows the creation of Pod with root privileges
  • Associate the Pod Security Policy with Role or a Cluster Role that is binded to admin users


The below diagram illustrates that place of the Pod Security Policy within the different Kubernetes objects

diagram for blog









The Pod Security Policy Object (PodSecurityPolicy) is bound either to a User (User) or to a Service Account (ServiceAccount

The binding to the User or the Service Account is done Associating the Pod SecurityPolicy to a Role (Role) or the Cluster Role (ClusterRole) that is binded via the Role Binding (RoleBinding) or the Cluster Role Binding (ClusterRoleBinding) to the User or the Service Account.

See the Pod Security Policy documentation for the full details.


Activating the Pod Security Policy

The Pod Security Policy is part of Kubernetes admission control mechanism, so in order to have the Pod Security Policy take effect, the Kubernetes Admission Control needs to be activated.

When the User or the Service Account access the Kubernetes API for creating a Pod, the Admission Control is invoked and checks if the Pod attributes conform with the rules defined in the Pod Security Policy. In case there is a mismatch the API server will fail the operation.


Controlling Container Runtime

One way to control the Kubernetes worker node’s Container Runtime is to gain access to it’s API interface by connecting to a local file system unix socket, which can be done by mounting the socket to another container – In docker for example the default unix socket file is located in   /var/run/docker.sock 


– /var/run/docker.sock:/var/run/docker.sock


Docker CLI client uses this socket to execute docker commands by default. You can override these settings as well.

There may be different valid applications that require access to  the container runtime . For example logging agents such as fluentd, worker node monitoring agents such as Datadog, or security agents.. An uncommon usage can be the creation of new containers on the worker node directly through the container runtime and not through Kubernetes APIs
This increases attack surface so one should avoid  mounting the container runtime unix-socket based API endpoint inside a Pod in order not to compromise the host that is running docker daemon, since Docker by default launches all containers as root.




Example:  Protecting Docker Container Runtime API

In the following example we will see how can the Pod Security Policy be used to protect against mounting docker.sock into a container. We will first define a namespace, psp-example, where our example will run, a service account malicious-user, that will represent the user that is trying to create a Pod that can access the docker.sock 

kubectl create namespace psp-example

kubectl create serviceaccount -n psp-example malicious-user


Step 1: Define the Pod Security Policy

First let’s define the Pod Security Policy that will limit the allowed volumes:

apiVersion: policy/v1beta1

kind: PodSecurityPolicy


  name: psp-protect-docker


  privileged: false  # Don’t allow privileged pods!

  allowPrivilegeEscalation: false

  # The rest fills in some required fields.


    rule: RunAsAny


    rule: RunAsAny


    rule: RunAsAny


    rule: RunAsAny


  – configMap

  – emptyDir

  – secret

  – projected

  – downwardAPI


  # This specifies a whitelist of host paths that are allowed to be used by hostPath volumes. An empty list means there is no restriction on host paths used.

  – pathPrefix: “/tmp”

    readOnly: true

Note the use of the allowedHostPaths to limit the allows files on the host. 


Next we will create the Policy:

kubectl create -f example_psp.yaml


Step 2: Create a Role and Attach the Pod Security Policy

Now we will create a Role and attach the Pod Security Policy to the Role:


kind: ClusterRole


  name: role-unprivileged

  # “namespace” omitted since ClusterRoles are not namespaced


– apiGroups:

  – policy


  – psp-protect-docker


  – podsecuritypolicies


  – use

– apiGroups: [“”]

  resources: [“pods”]

  verbs: [“get”, “list”, “watch”, “create”]


Next we will create the Role:

kubectl create -f example_role.yaml


Step 3: Bind the Role to the User

Now we will bind the role to a user, a service account in our case:


kind: ClusterRoleBinding


  name: role-binding-unprivileged



  kind: ClusterRole

  name: role-unprivileged


  – kind: ServiceAccount

    name: malicious-user

    namespace: psp-example

Next we will run the binding:

kubectl create -f example_role_binding.yaml 


Running the Example

Lets define a pod:

apiVersion: v1

kind: Pod


  name: attacking-pod



  – name: docker-socket


      path: /var/run/docker.sock


  – name:  pause



    – mountPath: /my-docker

      name: docker-socket


      allowPrivilegeEscalation: true


Now we enable the Admission control to enable Pod Security Policy. For example the gcloud command for my-cluster would be:

gcloud beta container clusters update my-cluster –enable-pod-security-policy –zone us-east1-d


Next we will run the Pod creation:

kubectl create -f attaching_pod.yaml –as=system:serviceaccount:psp-example:malicious-user -n psp-example’


We will get an error message indicating that the pod creation violates the Pod Security Policy:

Error from server (Forbidden): error when creating “attacking_pod.yaml”: pods “attacking-pod” is forbidden: unable to validate against any pod security policy: [spec.volumes[0]: Invalid value: “hostPath”: hostPath volumes are not allowed to be used spec.containers[0].securityContext.allowPrivilegeEscalation: Invalid value: true: Allowing privilege escalation for containers is not allowed]


Subscribe for updates, fresh insights, stories and tips

The latest posts delivered to your inbox