Tutorial: Create a Kubernetes Pod Security Policy

Kubernetes is the go-to container management tool for most enterprise-level businesses. But there are so many bits and pieces that come into play, security can become an issue. Not only do you have to ensure the systems your containers are deployed upon have well-established security controls, you also have to deploy those containers and pods with a strict eye on security. If not, you run the risk of exposure to data theft and other losses.
To that end, you must use every caution you can when deploying to your Kubernetes cluster. One thing that should be considered a must is the pod security policy. I want to walk you through the basics of creating a Kubernetes pod security policy. From there, you will have a launchpad from which you can continue your exploration and education into the crafting solid and secure deployments.
But first…
What Is a Kubernetes Pod?
Before we dive into the security policy, you might need to first understand what a pod is (if not, feel free to skip this section). For those that do need this information, know that a pod, in its simplest form, is a collection of processes that make up a container. These processes can include:
- Storage resources.
- Unique network IP addresses.
- Configuration options that dictate how a container should run.
These pieces come together (in one collection or another) as a unit for deployment. This unit can be in the form of a single container or a number of containers working together (such as WordPress, NGINX, and MySQL). Each of those containers will have configuration options of their own, but they come together to work as a cohesive whole — a Pod.
The problem with this is that, without the means to manage the security of the collective whole, you’re going to have to manage the security of the individual bits. This led the Kubernetes developers to create the…wait for it…
The Pod Security Policy
With a Pod Security Policy, Kubernetes admins can control the security of a pod specification. But it’s more than that. Pod Security Policies are configurations that define specific security conditions that a pod must meet, in order to be accepted into a cluster. If the conditions are not met, said pod will be rejected. By making use of the PodSecurityPolicy object definition, it is possible to control the likes of:
- A pod’s ability to run privileged containers.
- A pod’s ability to use privilege escalation.
- A pod’s access to volume types.
- A pod’s access to host file systems.
- A pod’s usage of host networking objects and configurations.
But how is a pod security policy defined?
Let’s dive into…
Creating a Kubernetes Pod Security Policy
The pod security policy is defined within a YAML file. That YAML file is then applied, with the help of the kubectl command, to define the new policy.
Let’s create a new pod security policy. This policy will do the following (by way of the RunAsAny rule, which is more permissive than the runAsUser option):
- Disable a pod’s ability to run a privileged container.
- Allow the use of SELinux.
- Allow the use of Linux groups.
- Allow users to run container entry points with a different username.
- Allow the use of fsGroup (volumes that support ownership management).
To create the necessary YAML file, issue the command (you can name the file whatever you like, so long as it ends with the .yaml extension):
nano no-privilege.yaml
In that new file, paste the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: name: no-privilege spec: privileged: false seLinux: rule: RunAsAny supplementalGroups: rule: RunAsAny runAsUser: rule: RunAsAny fsGroup: rule: RunAsAny volumes: - '*' |
Remember, as this is a YAML file, your indentation must be consistent (otherwise the file will fail).
Save and close the file.
To apply the newly created policy, issue the command:
kubectl apply -f no-privelege.yaml
The above command will report back the following:
podsecurity.policy/no-privilege created
Your pod security policy is now in place. Should you decide you need to change that particular policy, you can edit the YAML file and re-run the command to update the changes. You can also create as many policies as you need (creating different YAML files and applying them in a similar fashion as you did above).
You can verify that your policy is in place with the command:
kubectl get psp no-privilege
The above command will print out the policy, as defined in the YAML file (Figure 1).

Figure 1: Our new pod security policy is in place.
Now that you have your pod security policy created you need to know…
How to Assign a Pod Security Policy
With the help of Role-Based Access Control (RBAC), you can assign a pod security policy to a deployment. Let’s say we want to create a cluster-wide role, named no-privilege, which will make use of the policy by the same name.
To do this, we’ll create a new YAML file that will not only create the cluster-wide role (using the ClusterRole definition), it will also create a cluster binding to grant access to the no-privilege role to every authenticated user. To do this, create the new file with the command:
nano rbac-noprivilege.yaml
In that file, paste the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: no-privilege:no-privilege rules: - apiGroups: - extensions resources: - podsecuritypolicies resourceNames: - psp verbs: - use --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: no-privilege:no-privilege subjects: - kind: Group name: system:authenticated apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: no-privilege:no-privilege apiGroup: rbac.authorization.k8s.io |
Save and close the file. Apply the role with the command:
kubectl apply -f rbac-noprivilege.yaml
The above command will print out:
1 2 |
clusterrole.rbac.authorization.k8s.io/no-privilege:no-privilege created clusterrolebinding.rbac.authorization.k8s.io/no-privilege:no-privilege created |
Now you can check to make sure you’re able to use the new policy with the command:
kubectl auth can-i use no-privilege/no-privilege
The output should report, “yes.”
Let’s check to see if any user can use the new policy with the command:
kubectl auth can-i use no-privilege/no-privilege --as-group=system:authenticated --as=any-user
The output of the above command should report, “no.”
That’s it. You’ve created and applied your first Kubernetes pod security policy. With the help of this technique, you can greatly enhance the security of your Kubernetes deployments.