How to check Security Context Constraints (SCC) in OpenShift

OpenShift では、Pod 実行時の各種権限の管理に Security Context Constraints (SCC) が使用されます。Manifest 設計において明示的な指定を行わなくても SCC が適用されますが、設定の確認方法が思いのほか面倒ではあります。
ここでは、Red Hat OpenShift on IBM Cloud (ROKS) 4.11 を使用して、SCC 設定の確認方法の例をご紹介します。


#### What is SCC
OpenShift の公式ドキュメントによれば、SCC の役割は以下の通りです。
__About security context constraints__
https://docs.openshift.com/container-platform/4.11/authentication/managing-security-context-constraints.html
> 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.

#### Default SCC
先の Online Document によれば、Default SCC は以下の通りです。
> __restricted-v2__
This is the most restrictive SCC provided by a new installation and will be used by default for authenticated users.

これは、以下で確認することができます。
`authenticated users` とは `system:authenticated Group` のことです。
```shell
$ oc describe clusterrolebindings system:openshift:scc:restricted-v2
Name:         system:openshift:scc:restricted-v2
Labels:       <none>
Annotations:  include.release.openshift.io/ibm-cloud-managed: true
              include.release.openshift.io/self-managed-high-availability: true
              include.release.openshift.io/single-node-developer: true
Role:
  Kind:  ClusterRole
  Name:  system:openshift:scc:restricted-v2
Subjects:
  Kind   Name                  Namespace
  ----   ----                  ---------
  Group  system:authenticated
```


#### List of SCC
全ての SCC は以下で確認することができます。
NAME に `ibm` が含まれるものは、ROKS 固有の SCC です。

```shell
$ oc get scc
NAME                        PRIV    CAPS                                                                                                                                              SELINUX     RUNASUSER          FSGROUP     SUPGROUP    PRIORITY     READONLYROOTFS   VOLUMES
anyuid                      false   <no value>                                                                                                                                        MustRunAs   RunAsAny           RunAsAny    RunAsAny    10           false            ["configMap","downwardAPI","emptyDir","persistentVolumeClaim","projected","secret"]
hostaccess                  false   <no value>                                                                                                                                        MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    <no value>   false            ["configMap","downwardAPI","emptyDir","hostPath","persistentVolumeClaim","projected","secret"]
hostmount-anyuid            false   <no value>                                                                                                                                        MustRunAs   RunAsAny           RunAsAny    RunAsAny    <no value>   false            ["configMap","downwardAPI","emptyDir","hostPath","nfs","persistentVolumeClaim","projected","secret"]
hostnetwork                 false   <no value>                                                                                                                                        MustRunAs   MustRunAsRange     MustRunAs   MustRunAs   <no value>   false            ["configMap","downwardAPI","emptyDir","persistentVolumeClaim","projected","secret"]
hostnetwork-v2              false   ["NET_BIND_SERVICE"]                                                                                                                              MustRunAs   MustRunAsRange     MustRunAs   MustRunAs   <no value>   false            ["configMap","downwardAPI","emptyDir","persistentVolumeClaim","projected","secret"]
ibm-anyuid-hostaccess-scc   false   ["SETPCAP","AUDIT_WRITE","CHOWN","NET_RAW","DAC_OVERRIDE","FOWNER","FSETID","KILL","SETUID","SETGID","NET_BIND_SERVICE","SYS_CHROOT","SETFCAP"]   RunAsAny    RunAsAny           RunAsAny    RunAsAny    <no value>   false            ["*"]
ibm-anyuid-hostpath-scc     false   ["SETPCAP","AUDIT_WRITE","CHOWN","NET_RAW","DAC_OVERRIDE","FOWNER","FSETID","KILL","SETUID","SETGID","NET_BIND_SERVICE","SYS_CHROOT","SETFCAP"]   RunAsAny    RunAsAny           RunAsAny    RunAsAny    <no value>   false            ["*"]
ibm-anyuid-scc              false   ["SETPCAP","AUDIT_WRITE","CHOWN","NET_RAW","DAC_OVERRIDE","FOWNER","FSETID","KILL","SETUID","SETGID","NET_BIND_SERVICE","SYS_CHROOT","SETFCAP"]   RunAsAny    RunAsAny           RunAsAny    RunAsAny    <no value>   false            ["configMap","downwardAPI","emptyDir","persistentVolumeClaim","projected","secret"]
ibm-privileged-scc          true    ["*"]                                                                                                                                             RunAsAny    RunAsAny           RunAsAny    RunAsAny    <no value>   false            ["*"]
ibm-restricted-scc          false   []                                                                                                                                                MustRunAs   MustRunAsNonRoot   MustRunAs   MustRunAs   <no value>   false            ["configMap","downwardAPI","emptyDir","persistentVolumeClaim","projected","secret"]
node-exporter               true    <no value>                                                                                                                                        RunAsAny    RunAsAny           RunAsAny    RunAsAny    <no value>   false            ["*"]
nonroot                     false   <no value>                                                                                                                                        MustRunAs   MustRunAsNonRoot   RunAsAny    RunAsAny    <no value>   false            ["configMap","downwardAPI","emptyDir","persistentVolumeClaim","projected","secret"]
nonroot-v2                  false   ["NET_BIND_SERVICE"]                                                                                                                              MustRunAs   MustRunAsNonRoot   RunAsAny    RunAsAny    <no value>   false            ["configMap","downwardAPI","emptyDir","persistentVolumeClaim","projected","secret"]
privileged                  true    ["*"]                                                                                                                                             RunAsAny    RunAsAny           RunAsAny    RunAsAny    <no value>   false            ["*"]
restricted                  false   <no value>                                                                                                                                        MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    <no value>   false            ["configMap","downwardAPI","emptyDir","persistentVolumeClaim","projected","secret"]
restricted-v2               false   ["NET_BIND_SERVICE"]                                                                                                                              MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    <no value>   false            ["configMap","downwardAPI","emptyDir","persistentVolumeClaim","projected","secret"]
```


#### SCC to ServiceAccount
`oc adm policy` コマンドで SCC を ServiceAccount に紐付けることで、Pod の権限管理を行います。
SCC と ServiceAccount の関係は、以下で確認することができます。
```shell
$ oc get clusterrolebindings | egrep "^NAME|^system:openshift:scc:"
NAME                                                                        ROLE                                                                                    AGE
system:openshift:scc:anyuid                                                 ClusterRole/system:openshift:scc:anyuid                                                 459d
system:openshift:scc:privileged                                             ClusterRole/system:openshift:scc:privileged                                             459d
```
`-o wide` を付与することで、一覧で確認することができます。
```shell
$ oc get clusterrolebindings -o wide | egrep "^NAME|^system:openshift:scc:"
NAME                             ROLE                                        AGE    USERS GROUPS SERVICEACCOUNTS
system:openshift:scc:anyuid      ClusterRole/system:openshift:scc:anyuid     459d                my-account1/my-namespace1, my-account2/my-namespace2 
system:openshift:scc:privileged  ClusterRole/system:openshift:scc:privileged 459d                my-account3/my-namespace3, my-account4/my-namespace4
```
設定内容を個別に確認することもできます。
```shell
$ oc describe clusterrolebindings system:openshift:scc:anyuid
Name:         system:openshift:scc:anyuid
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  system:openshift:scc:anyuid
Subjects:
  Kind            Name                 Namespace
  ----            ----                 ---------
  ServiceAccount  my-account1          my-namespace1
  ServiceAccount  my-account2          my-namespace2
```
```shell
$ oc describe clusterrolebindings system:openshift:scc:privileged
Name:         system:openshift:scc:privileged
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  system:openshift:scc:privileged
Subjects:
  Kind            Name                 Namespace
  ----            ----                 ---------
  ServiceAccount  my-account3          my-namespace3
  ServiceAccount  my-account4          my-namespace4
```
#### SCC to Pod
Pod に適用されている SCC は以下で確認することができます。
```shell
$ oc get pods -o=custom-columns="NAME:.metadata.name,SA:.spec.serviceAccount,SCC:.metadata.annotations.openshift\.io/scc"
NAME  SA            SCC
pod1  my-account3   privileged
pod2  my-account1   anyuid
pod3  my-account4   privileged
pod4  default       restricted
```