Managing security context constraints

    Default SCCs are created during installation and when you install some Operators or other components. As a cluster administrator, you can also create your own SCCs by using the OpenShift CLI ().

    Similar to the way that RBAC resources control user access, administrators can use security context constraints (SCCs) to control permissions for pods. These permissions determine the actions that a pod can perform and what resources it can access. You can use SCCs to define a set of conditions that a pod must run with to be accepted into the system.

    Security context constraints allow an administrator to control:

    • Whether a pod can run privileged containers with the allowPrivilegedContainer flag

    • Whether a pod is constrained with the allowPrivilegeEscalation flag

    • The capabilities that a container can request

    • The use of host directories as volumes

    • The SELinux context of the container

    • The container user ID

    • The use of host namespaces and networking

    • The allocation of an FSGroup that owns the pod volumes

    • The configuration of allowable supplemental groups

    • Whether a container requires write access to its root file system

    • The usage of volume types

    • The configuration of allowable seccomp profiles

    Do not set the openshift.io/run-level label on any namespaces in OKD. This label is for use by internal OKD components to manage the startup of major API groups, such as the Kubernetes API server and OpenShift API server. If the openshift.io/run-level label is set, no SCCs are applied to pods in that namespace, causing any workloads running in that namespace to be highly privileged.

    The cluster contains several default security context constraints (SCCs) as described in the table below. Additional SCCs might be installed when you install Operators or other components to OKD.

    Do not modify the default SCCs. Customizing the default SCCs can lead to issues when some of the platform pods deploy or OKD is upgraded. Additionally, the default SCC values are reset to the defaults during some cluster upgrades, which discards all customizations to those SCCs.

    Instead of modifying the default SCCs, create and modify your own SCCs as needed. For detailed steps, see Creating security context constraints.

    Table 1. Default security context constraints
    Security context constraintDescription

    anyuid

    Provides all features of the restricted SCC, but allows users to run with any UID and any GID.

    hostaccess

    Allows access to all host namespaces but still requires pods to be run with a UID and SELinux context that are allocated to the namespace.

    This SCC allows host access to namespaces, file systems, and PIDs. It should only be used by trusted pods. Grant with caution.

    hostmount-anyuid

    Provides all the features of the restricted SCC, but allows host mounts and running as any UID and any GID on the system.

    This SCC allows host file system access as any UID, including UID 0. Grant with caution.

    hostnetwork

    Allows using host networking and host ports but still requires pods to be run with a UID and SELinux context that are allocated to the namespace.

    If additional workloads are run on control plane hosts, use caution when providing access to hostnetwork. A workload that runs hostnetwork on a control plane host is effectively root on the cluster and must be trusted accordingly.

    hostnetwork-v2

    Like the hostnetwork SCC, but with 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.

    node-exporter

    Used for the Prometheus node exporter.

    This SCC allows host file system access as any UID, including UID 0. Grant with caution.

    nonroot

    Provides all features of the restricted SCC, but allows users to run with any non-root UID. The user must specify the UID or it must be specified in the manifest of the container runtime.

    nonroot-v2

    Like the nonroot SCC, but with 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.

    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 the most relaxed SCC and should be used only for cluster administration. Grant with caution.

    The privileged SCC allows:

    • Users to run privileged pods

    • Pods to mount host directories as volumes

    • Pods to run as any user

    • Pods to run with any MCS label

    • Pods to use the host’s IPC namespace

    • Pods to use the host’s PID namespace

    • Pods to use any FSGroup

    • Pods to use any supplemental group

    • Pods to use any seccomp profiles

    • Pods to request any capabilities

    Setting privileged: true in the pod specification does not necessarily select the privileged SCC. The SCC that has allowPrivilegedContainer: true and has the highest prioritization will be chosen if the user has the permissions to use it.

    restricted

    Denies access to all host features and requires pods to be run with a UID, and SELinux context that are allocated to the namespace.

    The restricted SCC:

    • Ensures that pods cannot run as privileged

    • Ensures that pods cannot mount host directory volumes

    • Requires that a pod is run as a user in a pre-allocated range of UIDs

    • Requires that a pod is run with a pre-allocated MCS label

    • Allows pods to use any FSGroup

    • Allows pods to use any supplemental group

    In clusters that were upgraded from OKD 4.10 or earlier, this SCC is available for use by any authenticated user. The restricted SCC is no longer available to users of new OKD 4.11 or later installations, unless the access is explicitly granted.

    restricted-v2

    Like the restricted SCC, but with the following differences:

    • 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.

    This is the most restrictive SCC provided by a new installation and will be used by default for authenticated users.

    Security context constraints settings

    Security context constraints (SCCs) are composed of settings and strategies that control the security features a pod has access to. These settings fall into three categories:

    CategoryDescription

    Controlled by a boolean

    Fields of this type default to the most restrictive value. For example, AllowPrivilegedContainer is always set to false if unspecified.

    Controlled by an allowable set

    Fields of this type are checked against the set to ensure their value is allowed.

    Controlled by a strategy

    Items that have a strategy to generate a value provide:

    • A mechanism to generate the value, and

    • A mechanism to ensure that a specified value falls into the set of allowable values.

    CRI-O has the following default list of capabilities that are allowed for each container of a pod:

    • CHOWN

    • DAC_OVERRIDE

    • FSETID

    • FOWNER

    • SETGID

    • SETUID

    • SETPCAP

    • NET_BIND_SERVICE

    • KILL

    The containers use the capabilities from this default list, but pod manifest authors can alter the list by requesting additional capabilities or removing some of the default behaviors. Use the allowedCapabilities, defaultAddCapabilities, and requiredDropCapabilities parameters to control such requests from the pods. With these parameters you can specify which capabilities can be requested, which ones must be added to each container, and which ones must be forbidden, or dropped, from each container.

    You can drop all capabilites from containers by setting the requiredDropCapabilities parameter to ALL. This is what the restricted-v2 SCC does.

    Security context constraints strategies

    RunAsUser

    • MustRunAs - Requires a runAsUser to be configured. Uses the configured runAsUser as the default. Validates against the configured runAsUser.

      Example MustRunAs snippet

    • MustRunAsRange - Requires minimum and maximum values to be defined if not using pre-allocated values. Uses the minimum as the default. Validates against the entire allowable range.

      Example MustRunAsRange snippet

      1. ...
      2. runAsUser:
      3. type: MustRunAsRange
      4. uidRangeMax: <maxvalue>
      5. uidRangeMin: <minvalue>
      6. ...
    • MustRunAsNonRoot - Requires that the pod be submitted with a non-zero runAsUser or have the USER directive defined in the image. No default provided.

      Example MustRunAsNonRoot snippet

      1. ...
      2. runAsUser:
      3. type: MustRunAsNonRoot
      4. ...
    • RunAsAny - No default provided. Allows any runAsUser to be specified.

      Example RunAsAny snippet

      1. ...
      2. runAsUser:
      3. type: RunAsAny
      4. ...

    SELinuxContext

    • MustRunAs - Requires seLinuxOptions to be configured if not using pre-allocated values. Uses seLinuxOptions as the default. Validates against seLinuxOptions.

    SupplementalGroups

    • MustRunAs - Requires at least one range to be specified if not using pre-allocated values. Uses the minimum value of the first range as the default. Validates against all ranges.

    • RunAsAny - No default provided. Allows any supplementalGroups to be specified.

    FSGroup

    • MustRunAs - Requires at least one range to be specified if not using pre-allocated values. Uses the minimum value of the first range as the default. Validates against the first ID in the first range.

    • RunAsAny - No default provided. Allows any fsGroup ID to be specified.

    The usage of specific volume types can be controlled by setting the volumes field of the SCC.

    The allowable values of this field correspond to the volume sources that are defined when creating a volume:

    This list of allowable volume types is not exhaustive because new types are added with each release of OKD.

    For backwards compatibility, the usage of allowHostDirVolumePlugin overrides settings in the volumes field. For example, if allowHostDirVolumePlugin is set to false but allowed in the volumes field, then the hostPath value will be removed from volumes.

    Admission control

    Admission control with SCCs allows for control over the creation of resources based on the capabilities granted to a user.

    In terms of the SCCs, this means that an admission controller can inspect the user information made available in the context to retrieve an appropriate set of SCCs. Doing so ensures the pod is authorized to make requests about its operating environment or to generate a set of constraints to apply to the pod.

    The set of SCCs that admission uses to authorize a pod are determined by the user identity and groups that the user belongs to. Additionally, if the pod specifies a service account, the set of allowable SCCs includes any constraints accessible to the service account.

    Admission uses the following approach to create the final security context for the pod:

    1. Retrieve all SCCs available for use.

    2. Generate field values for security context settings that were not specified on the request.

    3. Validate the final settings against the available constraints.

    If a matching set of constraints is found, then the pod is accepted. If the request cannot be matched to an SCC, the pod is rejected.

    A pod must validate every field against the SCC. The following are examples for just two of the fields that must be validated:

    These examples are in the context of a strategy using the pre-allocated values.

    An FSGroup SCC strategy of MustRunAs

    If the pod defines a fsGroup ID, then that ID must equal the default fsGroup ID. Otherwise, the pod is not validated by that SCC and the next SCC is evaluated.

    If the SecurityContextConstraints.fsGroup field has value RunAsAny and the pod specification omits the Pod.spec.securityContext.fsGroup, then this field is considered valid. Note that it is possible that during validation, other SCC settings will reject other pod fields and thus cause the pod to fail.

    A SupplementalGroups SCC strategy of MustRunAs

    If the pod specification defines one or more supplementalGroups IDs, then the pod’s IDs must equal one of the IDs in the namespace’s openshift.io/sa.scc.supplemental-groups annotation. Otherwise, the pod is not validated by that SCC and the next SCC is evaluated.

    If the SecurityContextConstraints.supplementalGroups field has value RunAsAny and the pod specification omits the Pod.spec.securityContext.supplementalGroups, then this field is considered valid. Note that it is possible that during validation, other SCC settings will reject other pod fields and thus cause the pod to fail.

    Security context constraints prioritization

    Security context constraints (SCCs) have a priority field that affects the ordering when attempting to validate a request by the admission controller.

    A priority value of 0 is the lowest possible priority. A nil priority is considered a 0, or lowest, priority. Higher priority SCCs are moved to the front of the set when sorting.

    When the complete set of available SCCs is determined, the SCCs are ordered in the following manner:

    1. The highest priority SCCs are ordered first.

    2. If the priorities are equal, the SCCs are sorted from most restrictive to least restrictive.

    3. If both the priorities and restrictions are equal, the SCCs are sorted by name.

    By default, the anyuid SCC granted to cluster administrators is given priority in their SCC set. This allows cluster administrators to run pods as any user by specifying RunAsUser in the pod’s SecurityContext.

    About pre-allocated security context constraints values

    The admission controller is aware of certain conditions in the security context constraints (SCCs) that trigger it to look up pre-allocated values from a namespace and populate the SCC before processing the pod. Each SCC strategy is evaluated independently of other strategies, with the pre-allocated values, where allowed, for each policy aggregated with pod specification values to make the final values for the various IDs defined in the running pod.

    The following SCCs cause the admission controller to look for pre-allocated values when no ranges are defined in the pod specification:

    1. A RunAsUser strategy of MustRunAsRange with no minimum or maximum set. Admission looks for the openshift.io/sa.scc.uid-range annotation to populate range fields.

    2. An SELinuxContext strategy of MustRunAs with no level set. Admission looks for the openshift.io/sa.scc.mcs annotation to populate the level.

    3. A FSGroup strategy of MustRunAs. Admission looks for the openshift.io/sa.scc.supplemental-groups annotation.

    4. A SupplementalGroups strategy of MustRunAs. Admission looks for the openshift.io/sa.scc.supplemental-groups annotation.

    During the generation phase, the security context provider uses default values for any parameter values that are not specifically set in the pod. Default values are based on the selected strategy:

    1. RunAsAny and MustRunAsNonRoot strategies do not provide default values. If the pod needs a parameter value, such as a group ID, you must define the value in the pod specification.

    2. MustRunAs (single value) strategies provide a default value that is always used. For example, for group IDs, even if the pod specification defines its own ID value, the namespace’s default parameter value also appears in the pod’s groups.

    3. MustRunAsRange and MustRunAs (range-based) strategies provide the minimum value of the range. As with a single value MustRunAs strategy, the namespace’s default parameter value appears in the running pod. If a range-based strategy is configurable with multiple ranges, it provides the minimum value of the first configured range.

    FSGroup and SupplementalGroups strategies fall back to the openshift.io/sa.scc.uid-range annotation if the openshift.io/sa.scc.supplemental-groups annotation does not exist on the namespace. If neither exists, the SCC is not created.

    By default, the annotation-based FSGroup strategy configures itself with a single range based on the minimum value for the annotation. For example, if your annotation reads 1/3, the FSGroup strategy configures itself with a minimum and maximum value of 1. If you want to allow more groups to be accepted for the FSGroup field, you can configure a custom SCC that does not use the annotation.

    The openshift.io/sa.scc.supplemental-groups annotation accepts a comma-delimited list of blocks in the format of <start>/<length or <start>-<end>. The openshift.io/sa.scc.uid-range annotation accepts only a single block.

    The following examples show the security context constraints (SCC) format and annotations:

    Annotated privileged SCC

    1. allowHostDirVolumePlugin: true
    2. allowHostIPC: true
    3. allowHostNetwork: true
    4. allowHostPID: true
    5. allowHostPorts: true
    6. allowPrivilegedContainer: true
    7. allowedCapabilities: (1)
    8. - '*'
    9. apiVersion: security.openshift.io/v1
    10. defaultAddCapabilities: [] (2)
    11. fsGroup: (3)
    12. type: RunAsAny
    13. groups: (4)
    14. - system:cluster-admins
    15. - system:nodes
    16. kind: SecurityContextConstraints
    17. metadata:
    18. annotations:
    19. kubernetes.io/description: 'privileged allows access to all privileged and host
    20. features and the ability to run as any user, any group, any fsGroup, and with
    21. any SELinux context. WARNING: this is the most relaxed SCC and should be used
    22. only for cluster administration. Grant with caution.'
    23. creationTimestamp: null
    24. name: privileged
    25. priority: null
    26. readOnlyRootFilesystem: false
    27. requiredDropCapabilities: (5)
    28. - KILL
    29. - MKNOD
    30. - SETUID
    31. - SETGID
    32. runAsUser: (6)
    33. type: RunAsAny
    34. seLinuxContext: (7)
    35. type: RunAsAny
    36. seccompProfiles:
    37. - '*'
    38. supplementalGroups: (8)
    39. type: RunAsAny
    40. users: (9)
    41. - system:serviceaccount:default:router
    42. - system:serviceaccount:openshift-infra:build-controller
    43. volumes: (10)
    44. - '*'
    1A list of capabilities that a pod can request. An empty list means that none of capabilities can be requested while the special symbol allows any capabilities.
    2A list of additional capabilities that are added to any pod.
    3The FSGroup strategy, which dictates the allowable values for the security context.
    4The groups that can access this SCC.
    5A list of capabilities to drop from a pod. Or, specify ALL to drop all capabilities.
    6The runAsUser strategy type, which dictates the allowable values for the security context.
    7The seLinuxContext strategy type, which dictates the allowable values for the security context.
    8The supplementalGroups strategy, which dictates the allowable supplemental groups for the security context.
    9The users who can access this SCC.
    10The allowable volume types for the security context. In the example, allows the use of all volume types.

    The users and groups fields on the SCC control which users can access the SCC. By default, cluster administrators, nodes, and the build controller are granted access to the privileged SCC. All authenticated users are granted access to the restricted-v2 SCC.

    Without explicit setting

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: security-context-demo
    5. spec:
    6. securityContext: (1)
    7. containers:
    8. - name: sec-ctx-demo
    9. image: gcr.io/google-samples/node-hello:1.0

    With explicit runAsUser setting

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: security-context-demo
    5. spec:
    6. securityContext:
    7. runAsUser: 1000 (1)
    8. containers:
    9. - name: sec-ctx-demo
    10. image: gcr.io/google-samples/node-hello:1.0
    1A container or pod that requests a specific user ID will be accepted by OKD only when a service account or a user is granted access to a SCC that allows such a user ID. The SCC can allow arbitrary IDs, an ID that falls into a range, or the exact user ID specific to the request.

    This configuration is valid for SELinux, fsGroup, and Supplemental Groups.

    Creating security context constraints

    You can create security context constraints (SCCs) by using the OpenShift CLI (oc).

    Creating and modifying your own SCCs are advanced operations that might cause instability to your cluster. If you have questions about using your own SCCs, contact Red Hat Support. For information about contacting Red Hat support, see Getting support.

    Prerequisites

    • Install the OpenShift CLI (oc).

    • Log in to the cluster as a user with the cluster-admin role.

    Procedure

    1. Define the SCC in a YAML file named scc-admin.yaml:

      Optionally, you can drop specific capabilities for an SCC by setting the requiredDropCapabilities field with the desired values. Any specified capabilities are dropped from the container. To drop all capabilities, specify ALL. For example, to create an SCC that drops the KILL, MKNOD, and SYS_CHROOT capabilities, add the following to the SCC object:

      1. requiredDropCapabilities:
      2. - KILL
      3. - MKNOD
      4. - SYS_CHROOT

      You cannot list a capability in both allowedCapabilities and requiredDropCapabilities.

      CRI-O supports the same list of capability values that are found in the .

    2. Create the SCC by passing in the file:

      1. $ oc create -f scc-admin.yaml

      Example output

      1. securitycontextconstraints "scc-admin" created

    Verification

    • Verify that the SCC was created:

      1. $ oc get scc scc-admin

      Example output

      1. NAME PRIV CAPS SELINUX RUNASUSER FSGROUP SUPGROUP PRIORITY READONLYROOTFS VOLUMES
      2. scc-admin true [] RunAsAny RunAsAny RunAsAny RunAsAny <none> false [awsElasticBlockStore azureDisk azureFile cephFS cinder configMap downwardAPI emptyDir fc flexVolume flocker gcePersistentDisk gitRepo glusterfs iscsi nfs persistentVolumeClaim photonPersistentDisk quobyte rbd secret vsphere]

    You can specify SCCs as resources that are handled by RBAC. This allows you to scope access to your SCCs to a certain project or to the entire cluster. Assigning users, groups, or service accounts directly to an SCC retains cluster-wide scope.

    You cannot assign a SCC to pods created in one of the default namespaces: default, kube-system, kube-public, openshift-node, openshift-infra, openshift. These namespaces should not be used for running pods or services.

    To include access to SCCs for your role, specify the scc resource when creating a role.

    1. $ oc create role <role-name> --verb=use --resource=scc --resource-name=<scc-name> -n <namespace>

    This results in the following role definition:

    1The role’s name.
    2Namespace of the defined role. Defaults to default if not specified.
    3The API group that includes the SecurityContextConstraints resource. Automatically defined when scc is specified as a resource.
    4An example name for an SCC you want to have access.
    5Name of the resource group that allows users to specify SCC names in the resourceNames field.
    6A list of verbs to apply to the role.

    A local or cluster role with such a rule allows the subjects that are bound to it with a role binding or a cluster role binding to use the user-defined SCC called scc-name.

    Because RBAC is designed to prevent escalation, even project administrators are unable to grant access to an SCC. By default, they are not allowed to use the verb use on SCC resources, including the restricted-v2 SCC.

    Reference of security context constraints commands

    You can manage security context constraints (SCCs) in your instance as normal API objects using the OpenShift CLI (oc).

    You must have cluster-admin privileges to manage SCCs.

    To get a current list of SCCs:

    1. $ oc get scc

    Example output

    1. NAME PRIV CAPS SELINUX RUNASUSER FSGROUP SUPGROUP PRIORITY READONLYROOTFS VOLUMES
    2. anyuid false <no value> MustRunAs RunAsAny RunAsAny RunAsAny 10 false ["configMap","downwardAPI","emptyDir","persistentVolumeClaim","projected","secret"]
    3. hostaccess false <no value> MustRunAs MustRunAsRange MustRunAs RunAsAny <no value> false ["configMap","downwardAPI","emptyDir","hostPath","persistentVolumeClaim","projected","secret"]
    4. hostmount-anyuid false <no value> MustRunAs RunAsAny RunAsAny RunAsAny <no value> false ["configMap","downwardAPI","emptyDir","hostPath","nfs","persistentVolumeClaim","projected","secret"]
    5. hostnetwork false <no value> MustRunAs MustRunAsRange MustRunAs MustRunAs <no value> false ["configMap","downwardAPI","emptyDir","persistentVolumeClaim","projected","secret"]
    6. hostnetwork-v2 false ["NET_BIND_SERVICE"] MustRunAs MustRunAsRange MustRunAs MustRunAs <no value> false ["configMap","downwardAPI","emptyDir","persistentVolumeClaim","projected","secret"]
    7. node-exporter true <no value> RunAsAny RunAsAny RunAsAny RunAsAny <no value> false ["*"]
    8. nonroot false <no value> MustRunAs MustRunAsNonRoot RunAsAny RunAsAny <no value> false ["configMap","downwardAPI","emptyDir","persistentVolumeClaim","projected","secret"]
    9. nonroot-v2 false ["NET_BIND_SERVICE"] MustRunAs MustRunAsNonRoot RunAsAny RunAsAny <no value> false ["configMap","downwardAPI","emptyDir","persistentVolumeClaim","projected","secret"]
    10. privileged true ["*"] RunAsAny RunAsAny RunAsAny RunAsAny <no value> false ["*"]
    11. restricted false <no value> MustRunAs MustRunAsRange MustRunAs RunAsAny <no value> false ["configMap","downwardAPI","emptyDir","persistentVolumeClaim","projected","secret"]
    12. restricted-v2 false ["NET_BIND_SERVICE"] MustRunAs MustRunAsRange MustRunAs RunAsAny <no value> false ["configMap","downwardAPI","emptyDir","persistentVolumeClaim","projected","secret"]

    Examining security context constraints

    You can view information about a particular SCC, including which users, service accounts, and groups the SCC is applied to.

    For example, to examine the restricted SCC:

    1. $ oc describe scc restricted

    Example output

    1. Name: restricted
    2. Priority: <none>
    3. Access:
    4. Users: <none> (1)
    5. Groups: <none> (2)
    6. Settings:
    7. Allow Privileged: false
    8. Allow Privilege Escalation: true
    9. Default Add Capabilities: <none>
    10. Required Drop Capabilities: KILL,MKNOD,SETUID,SETGID
    11. Allowed Capabilities: <none>
    12. Allowed Seccomp Profiles: <none>
    13. Allowed Volume Types: configMap,downwardAPI,emptyDir,persistentVolumeClaim,projected,secret
    14. Allowed Flexvolumes: <all>
    15. Allowed Unsafe Sysctls: <none>
    16. Forbidden Sysctls: <none>
    17. Allow Host Network: false
    18. Allow Host Ports: false
    19. Allow Host PID: false
    20. Allow Host IPC: false
    21. Read Only Root Filesystem: false
    22. Run As User Strategy: MustRunAsRange
    23. UID: <none>
    24. UID Range Min: <none>
    25. UID Range Max: <none>
    26. SELinux Context Strategy: MustRunAs
    27. User: <none>
    28. Role: <none>
    29. Type: <none>
    30. Level: <none>
    31. FSGroup Strategy: MustRunAs
    32. Ranges: <none>
    33. Supplemental Groups Strategy: RunAsAny
    34. Ranges: <none>
    1Lists which users and service accounts the SCC is applied to.
    2Lists which groups the SCC is applied to.

    To preserve customized SCCs during upgrades, do not edit settings on the default SCCs.

    Deleting security context constraints

    To delete an SCC:

    1. $ oc delete scc <scc_name>

    To update an existing SCC: