OpenShift: Assign SecurityContextConstraint to a ServiceAccount

SecurityContextConstraint OpenShift ServiceAccount Pod

3 min read | by Jordi Prats

If you try to create a pod with some privileges using the securityContext you are going to find out that it's not going to work on OpenShift as it would on a vanilla Kubernetes:

$ kubectl describe sts example-no-scc
Name:               example-no-scc
(...)

Events:
  Type     Reason        Age                 From                    Message
  ----     ------        ----                ----                    -------
  Warning  FailedCreate  18s (x13 over 38s)  statefulset-controller  create Pod example-no-scc-0 in StatefulSet example-no-scc failed error: pods "example-no-scc-0" is forbidden: unable to validate against any security context constraint: [provider "anyuid": Forbidden: not usable by user or serviceaccount, spec.initContainers[0].securityContext.capabilities.add: Invalid value: "DAC_OVERRIDE": capability may not be added, spec.containers[0].securityContext.capabilities.add: Invalid value: "DAC_OVERRIDE": capability may not be added, spec.containers[1].securityContext.capabilities.add: Invalid value: "DAC_OVERRIDE": capability may not be added, provider "nonroot": Forbidden: not usable by user or serviceaccount, provider "hostmount-anyuid": Forbidden: not usable by user or serviceaccount, provider "machine-api-termination-handler": Forbidden: not usable by user or serviceaccount, provider "hostnetwork": Forbidden: not usable by user or serviceaccount, provider "hostaccess": Forbidden: not usable by user or serviceaccount, provider "node-exporter": Forbidden: not usable by user or serviceaccount, provider "privileged": Forbidden: not usable by user or serviceaccount]

To be able to create a Pod (either directly or via a Deployment, StatefulSet, ...) you'll need to assign the ServiceAccount it is using to a SecurityContextConstraint. You'll find some predefined that might suit your needs:

  • restricted: Denies access to all host features and requires pods to be run with a UID, and SELinux context (most restrictive)
  • nonroot: Same as restricted but allows users to set any non-root UID
  • anyuid : Same as restricted but allows users to configure any UID and any GID
  • hostmount-anyuid: Same as restricted allows host mounts and any UID by a pod
  • hostnetwork: Allows using host networking (includes host ports)
  • node-exporter: Predefined SCC intended for Prometheus node exporter
  • hostaccess: Allows access to all host namespaces but still requires pods to be run with a UID and SELinux context
  • privileged: Allows access to all privileged and host features and the ability to run as any user, any group, any fsGroup, and with any SELinux context. This is what you have on a vanilla Kubernetes (aka no restrictions)

So, if we are alright with running the demo-sa ServiceAccount on the demo-ns namespace with the privileged SecurityContextConstraint we can use oc adm policy to add it:

$ oc adm policy add-scc-to-user privileged system:serviceaccount:demo-ns:demo-sa
clusterrole.rbac.authorization.k8s.io/system:openshift:scc:privileged added: "demo-sa"

We can always remove the privilege using remove-scc-from-user:

$ oc adm policy remove-scc-from-user privileged system:serviceaccount:demo-ns:demo-sa
clusterrole.rbac.authorization.k8s.io/system:openshift:scc:privileged removed: "demo-sa"

Posted on 08/09/2022