--- title: Use Pod Security Policies in UCP description: Learn how to use Pod Security Policies to lock down Kubernetes as part of Universal Control Plane. keywords: UCP, Kubernetes, psps, pod security policies --- Pod Security Policies (PSPs) are cluster-level resources which are enabled by default in Docker Universal Control Plane (UCP) 3.2. See [Pod Security Policy](https://kubernetes.io/docs/concepts/policy/pod-security-policy/) for an explanation of this Kubernetes concept. There are two default PSPs in UCP: a `privileged` policy and an `unprivileged` policy. Administrators of the cluster can enforce additional policies and apply them to users and teams for further control of what runs in the Kubernetes cluster. This guide describes the two default policies, and provides two example use cases for custom policies. ## Kubernetes Role Based Access Control (RBAC) To interact with PSPs, a user will need to be granted access to the `PodSecurityPolicy` object in Kubernetes RBAC. If the user is a `UCP Admin`, then the user can already manipulate PSPs. A normal user can interact with policies if a UCP admin creates the following `ClusterRole` and `ClusterRoleBinding`: ``` $ cat < Note: PSPs do not override security defaults built into the > UCP RBAC engine for Kubernetes pods. These [Security > defaults](https://docs.docker.com/ee/ucp/authorization/) prevent non-admin > users from mounting host paths into pods or starting privileged pods. ```bash $ kubectl get podsecuritypolicies NAME PRIV CAPS SELINUX RUNASUSER FSGROUP SUPGROUP READONLYROOTFS VOLUMES privileged true * RunAsAny RunAsAny RunAsAny RunAsAny false * unprivileged false RunAsAny RunAsAny RunAsAny RunAsAny false * ``` The specification for the `privileged` policy is as follows: ``` allowPrivilegeEscalation: true allowedCapabilities: - '*' fsGroup: rule: RunAsAny hostIPC: true hostNetwork: true hostPID: true hostPorts: - max: 65535 min: 0 privileged: true runAsUser: rule: RunAsAny seLinux: rule: RunAsAny supplementalGroups: rule: RunAsAny volumes: - '*' ``` The specification for the `unprivileged` policy is as follows: ``` allowPrivilegeEscalation: false allowedHostPaths: - pathPrefix: /dev/null readOnly: true fsGroup: rule: RunAsAny hostPorts: - max: 65535 min: 0 runAsUser: rule: RunAsAny seLinux: rule: RunAsAny supplementalGroups: rule: RunAsAny volumes: - '*' ``` ## Use the unprivileged policy > Note: When following this guide, if the prompt `$` follows `admin`, the action > needs to be performed by a user with access to create pod security policies as > discussed in [the Kubernetes RBAC section](#kubernetes-role-based-access-control). If the prompt `$` > follows `user`, the UCP account does not need access to the PSP > object in Kubernetes. The user only needs the ability to create Kubernetes pods. > To switch users from the `privileged` policy to the `unprivileged` policy (or any custom policy), an admin must first remove the `ClusterRoleBinding` that links all users and service accounts to the `privileged` policy. ``` admin $ kubectl delete clusterrolebindings ucp:all:privileged-psp-role ``` When the `ClusterRoleBinding` is removed, cluster admins can still deploy pods, and these pods are deployed with the `privileged` policy. But users or service accounts are unable to deploy pods, because Kubernetes does not know what pod security policy to apply. Note cluster admins would not be able to deploy deployments, see [using the unprivileged policy in a deployment](#using-the-unprivileged-policy-in-a-deployment) for more details. ```bash user $ kubectl apply -f pod.yaml Error from server (Forbidden): error when creating "pod.yaml": pods "demopod" is forbidden: unable to validate against any pod security policy: [] ``` Therefore, to allow a user or a service account to use the `unprivileged` policy (or any custom policy), you must create a `RoleBinding` to link that user or team with the alternative policy. For the `unprivileged` policy, a `ClusterRole` has already been defined, but has not been attached to a user. ```bash # List Existing Cluster Roles admin $ kubectl get clusterrole | grep psp privileged-psp-role 3h47m unprivileged-psp-role 3h47m # Define which user to apply the ClusterRole too admin $ USER=jeff # Create a RoleBinding linking the ClusterRole to the User admin $ cat < Note: In a most use cases a Pod is not actually scheduled by a user. When > creating Kubernetes objects such as Deployments or Daemonsets the pods are > being scheduled by a service account or a controller. If you have disabled the `privileged` PSP policy, and created a `RoleBinding` to map a user to a new PSP policy, Kubernetes objects like Deployments and Daemonsets will not be able to deploy pods. This is because Kubernetes objects, like Deployments, use a `Service Account` to schedule pods, instead of the user that created the Deployment. ```bash user $ kubectl get deployments NAME READY UP-TO-DATE AVAILABLE AGE nginx 0/1 0 0 88s user $ kubectl get replicasets NAME DESIRED CURRENT READY AGE nginx-cdcdd9f5c 1 0 0 92s user $ kubectl describe replicasets nginx-cdcdd9f5c ... Warning FailedCreate 48s (x15 over 2m10s) replicaset-controller Error creating: pods "nginx-cdcdd9f5c-" is forbidden: unable to validate against any pod security policy: [] ``` For this deployment to be able to schedule pods, the service account defined wthin the deployment specification needs to be associated with a PSP policy. If a service account is not defined within a deployment spec, the default service account in a namespace is used. This is the case in the deployment output above, there is no service account defined, therefore a `Rolebinding` to grant the default service account in the default namespace to use PSP policy is needed. An example `RoleBinding` to associate the `unprivileged` PSP policy in UCP with the defaut service account in the default namespace is: ```bash admin $ cat < Error: container has runAsNonRoot and image will run as root ``` ### Example 2: Use a PSP to apply seccomp policies A second use case for PSPs is to prevent a user from deploying containers without a [seccomp policy](https://docs.docker.com/engine/security/seccomp/). By default, Kubernetes does not apply a seccomp policy to pods, so a default seccomp policy could be applied for all pods by a PSP. ```bash admin $ cat <