Predefined vs. custom SCCs

What's included in predefined SCCs and how to customize them

By

Rich Hagarty,

Bobby Woolf

This article describes what's included in Red Hat OpenShift's predefined security context constraints (SCCs) and also shows you how to customize an SCC.

An SCC is either predefined or custom. A predefined SCC is built into the cluster when the cluster is created. An administrator creates a custom SCC, which is then unique to that cluster. The administrator should not modify a predefined SCC, but should instead create or modify a custom SCC. Any SCC is global to its cluster, so any SCC can be assigned to any service account, regardless of the project the service account is in.

OpenShift's predefined SCCs

Each OpenShift cluster contains several predefined SCCs, each specifying a set of permissions. This table from "Managing SCCs in OpenShift" lists and explains the predefined SCCs. To meet the Pod Security Standards, a few SCCs with -v2 suffix were added into OpenShift v4.11 and later. (Note that "UID" is a user ID and "GID" is a group ID.)

SCC nameDescriptionComments
restrictedDenies access to all host features and requires pods to be run with a UID and SELinux context from the set that the cluster assigns to the project.This is the most secure SCC and is always used by default in OpenShift v4.10 and earlier. This will work for most typical stateless workloads. In clusters that were upgraded from OpenShift v4.10 or earlier to OpenShift v4.11 and later, this is still available but not the default one. In OpenShift v4.11 and later, a restricted-v2 SCC is used by default instead.
restricted-v2Like the restricted SCC, but with more strict restrictions to reach the restricted policy defined in Pod Security Standards. This is available in OpenShift v4.11 and later.This is the most restrictive SCC provided by a new OpenShift installation v4.11 or later and is used by default.
nonrootProvides all the same features as the restricted SCC, but allows users to run with any non-root UID.Suitable for applications that need predictable non-root UIDs, but can function with all the other limitations set by the restricted SCC.
nonroot-v2Like nonroot SCC, but with more strict restrictions, including ALL capabilities being dropped, the NET_BIND_SERVICE capability can be added explicitly, etc. This is available in OpenShift v4.11 and later.Suitable for applications that need predictable non-root UIDs, but can function with all the other limitations set by the restricted-v2 SCC.
anyuidSame as restricted, but allows users to run with any UID and GID.Potentially very risy as it allows running as root user outside the container. If used, SELinux controls can play an important role in adding a layer of protection. It's also a good idea to use seccomp to filter out undesired system calls.
hostmount-anyuidProvides all the features of the restricted SCC, but allows host mounts and any UID by a pod. This is primarily used by the persistent volume recycler, a trusted workload that is an essential infrastructure piece to the cluster.This SCC should only be used by the persistent volume recycler. Same warnings as with anyuid, but hostmount-anyuid goes further by allowing the mounting of host volumes. Warning: This SCC allows host file system access as any UID, including UID 0. Grant with caution.
hostnetworkAllows the use of host networking and host ports, but still requires pods to be run with a UID and SELinux context that are assigned to the project.This SCC allows the pod to "see and use" the host network stack directly. Requiring the pod run with a non-zero UID and preassigned SELinux context can add some security.
hostnetwork-v2Like hostnetwork SCC, but with more strict restrictions, including ALL capabilities being dropped, the NET_BIND_SERVICE capability can be added explicitly, etc. This is available in OpenShift v4.11 and later.This SCC allows the pod to "see and use" the host network stack directly. Requiring the pod run with a non-zero UID and preassigned SELinux context can add some security.
node-exporterUsed only for the Prometheus Node Exporter. (Prometheus is a popular Kubernetes monitoring tool.)This SCC should only be used by Prometheus. It is designed specifically for Prometheus to retrieve metrics from the cluster. It allows access to the host network, host PIDS, and host volumes, but not the host IPC. It also allows anyuid. Applications should not use this SCC.
hostaccessAllows access to all host project namespaces, but still requires pods to be run with a UID and SELinux context that are assigned to the project.Access to all host namespaces is dangerous, even though it does restrict UID and SELinux. This should only be used for necessary trusted workloads.
privilegedAllows access to all privileged and host features, as well as the ability to run as any user, group, or fsGroup, and with any SELinux context. This is the most relaxed SCC policy.This SCC allows a pod to control everything in the host and worker nodes, as well as other containers. Only trusted workloads should use this. There is a case to be made that this should never be used in production, as it allows the pod to completely control the host.


IMPORTANT: Do not modify the predefined SCCs. Customizing the predefined SCCs can lead to issues when OpenShift is upgraded. Instead, create new custom SCCs.

Now that you've gotten an overview of the predefined SCCs, let's examine a predefined SCC in detail.

Examining the restricted SCC

The restricted SCC is the default SCC because it is assigned to each project's default service account in OpenShift v4.10 or earlier. Therefore, a restricted SCC is the one used by all of the deployments that do not specify a service account, making it the most commonly used SCC. Let's examine the restricted SCC in detail. However, a restricted-v2 SCC is available and used by default in OpenShift v4.11 and later. In this case, you can check restricted-v2 SCC instead.

You can view an SCC by running either of the following OpenShift CLI commands:

oc get scc <scc name> -o yaml
oc describe scc/<scc name>

Here is a snippet of what the YAML for the restricted SCC looks like (with comment lines added for clarity):

$ oc get scc restricted  -o yaml
apiVersion: security.openshift.io/v1
kind: SecurityContextConstraints
metadata:
  name: restricted
...
# Privileges
allowPrivilegedContainer: false
allowHostNetwork: false
allowHostPID: false
...
# Capabilities
allowedCapabilities: null
defaultAddCapabilities: null
requiredDropCapabilities:
- KILL
- MKNOD
- SETUID
- SETGID
...
# Access Control
fsGroup:
  type: MustRunAs
runAsUser:
  type: MustRunAsRange
seLinuxContext:
  type: MustRunAs
supplementalGroups:
  type: RunAsAny
...

Note how locked down this SCC is -- it doesn't allow any special privileges or capabilities. However, it does allow any supplemental group ID to be specified, which enables pods to access the shared resources that are owned by a group.

If you are using OpenShift v4.11 or later, the YAML for the restricted-v2 will look like the following:

$ oc get scc restricted-v2  -o yaml
# Privileges
allowHostDirVolumePlugin: false
allowHostIPC: false
allowHostNetwork: false
allowHostPID: false
allowHostPorts: false
allowPrivilegeEscalation: false
allowPrivilegedContainer: false
# Capabilities
allowedCapabilities:
- NET_BIND_SERVICE
# Metadata
apiVersion: security.openshift.io/v1
# Capabilities
defaultAddCapabilities: null
# Access Control
fsGroup:
  type: MustRunAs
groups: []
# Metadata
kind: SecurityContextConstraints
metadata:
  ...
  name: restricted-v2
  ...
priority: null
readOnlyRootFilesystem: false
# Capabilities
requiredDropCapabilities:
- ALL
# Access Control
runAsUser:
  type: MustRunAsRange
seLinuxContext:
  type: MustRunAs
seccompProfiles:
- runtime/default
supplementalGroups:
  type: RunAsAny
users: []
volumes:
- configMap
- downwardAPI
- emptyDir
...

The restricted-v2 SCC's YAML output is similar to the restricted SCC except for the following differences:

  • ALL capabilities are dropped from containers.
  • The NET_BIND_SERVICE capability can be added explicitly.
  • seccompProfile is set to runtime/default by default.
  • allowPrivilegeEscalation must be unset or set to false in security contexts.

In addition to the predefined SCCs that are built into a cluster, the administrator can also add custom SCCs.

Creating a custom SCC

When determining which SCC to assign, it is important to remember that less is better. If a pod requires permission A, don't select an SCC that provides permissions A, B, and C.

If none of the predefined SCCs provides exactly the permissions an application requires, the administrator can create a custom one.

One way to create a custom SCC is to use a YAML file, such as the following:

apiVersion: security.openshift.io/v1
kind: SecurityContextConstraints
metadata:
  name: my-custom-scc
# Privileges
allowPrivilegedContainer: false
# Access Control
runAsUser:
  type: MustRunAsRange
  uidRangeMin: 1000
  uidRangeMax: 2000
seLinuxContext:
  type: RunAsAny
fsGroup:
  type: MustRunAs
  ranges:
  - min: 5000
    max: 6000
supplementalGroups:
  type: MustRunAs
  ranges:
  - min: 5000
    max: 6000
# Capabilities
defaultAddCapabilities:
  - CHOWN
  - SYS_TIME
requiredDropCapabilities:
  - MKNOD
allowedCapabilites:
  - NET_ADMIN

NOTE: Note that the SCC fields fsGroup and supplementalGroups are set to MustRunAs -- which typically would indicate setting a value, but in fact a range is specified.

You can save this SCC definition in a file named my-custom-scc.yaml and create the SCC with this command:

oc create -f my-custom-scc.yaml

To view the created SCC, use the command:

oc get scc my-custom-scc -o yaml

You can also view the SCC with the describe command:

$ oc describe scc/my-custom-scc
Name:                           my-custom-scc
Priority:                       <none>
Access:
  Users:                        <none>
  Groups:                       <none>
Settings:
  Allow Privileged:             false
  Allow Privilege Escalation:   true
  Default Add Capabilities:     CHOWN,SYS_TIME
  Required Drop Capabilities:   MKNOD
  Allowed Capabilities:         <none>
  Allowed Seccomp Profiles:     <none>
  Allowed Volume Types:         awsElasticBlockStore,azureDisk,azureFile,cephFS,cinder,configMap,csi,downwardAPI,emptyDir,fc,flexVolume,flocker,gcePersistentDisk,gitRepo,glusterfs,iscsi,nfs,persistentVolumeClaim,photonPersistentDisk,portworxVolume,projected,quobyte,rbd,scaleIO,secret,storageOS,vsphere
  Allowed Flexvolumes:          <all>
  Allowed Unsafe Sysctls:       <none>
  Forbidden Sysctls:            <none>
  Allow Host Network:           false
  Allow Host Ports:             false
  Allow Host PID:               false
  Allow Host IPC:               false
  Read Only Root Filesystem:    false
  Run As User Strategy: MustRunAsRange
    UID:                        <none>
    UID Range Min:              1000
    UID Range Max:              2000
  SELinux Context Strategy: RunAsAny
    User:                       <none>
    Role:                       <none>
    Type:                       <none>
    Level:                      <none>
  FSGroup Strategy: MustRunAs
    Ranges:                     5000-6000
  Supplemental Groups Strategy: MustRunAs
    Ranges:                     5000-6000

A quick note on some of the permissions specified in the SCC:

SELinux

How the seLinuxOptions values are used depends on the value of the seLinuxContext.type field:

  • MustRunAs -- Requires seLinuxContext.seLinuxOptions to be set, either in the SCC or in the project's configuration. These values are then validated against the seLinuxOptions that are requested in the deployment manifest.
  • RunAsAny -- Means no default values are provided, which allows any seLinuxOptions to be specified in the deployment manifest.

seccomp

seccomp, short for "Secure Computing state," is a Linux kernel security feature. When enabled, seccomp prevents the container from making a majority of system calls, eliminating most common vulnerabilities. seccomp is maintained by an allowlist profile that can be added to for custom use and is unique to each base image profile.

Summary

With you newly acquired understanding of predefined SCCs and custom SCCs, you're ready to learn the steps for making an SCC available to a deployment in the next article in this learning path.