Uploaded image for project: 'OpenShift Bugs'
  1. OpenShift Bugs
  2. OCPBUGS-160

NS autolabeler requires RoleBinding subject namespace to be set when using ServiceAccount

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done-Errata
    • Icon: Undefined Undefined
    • 4.14.0
    • 4.12
    • apiserver-auth
    • None
    • None
    • Auth - Sprint 223, Auth - Sprint 232, Auth - Sprint 233, Auth - Sprint 234, Auth - Sprint 235
    • 5
    • False
    • Hide

      None

      Show
      None
    • Hide
      * Previously, the NS autolabeler required the `RoleBinding` object's `.subject[].namespace` field to be set when `.subjects[].kind` is set to `ServiceAccount` in order to successfully bind the service account to a role. With this release, the NS autolabeler uses the namespace of the `RoleBinding` object if the `.subject[].namespace` is not specified. (link:https://issues.redhat.com/browse/OCPBUGS-160[*OCPBUGS-160*])
      Show
      * Previously, the NS autolabeler required the `RoleBinding` object's `.subject[].namespace` field to be set when `.subjects[].kind` is set to `ServiceAccount` in order to successfully bind the service account to a role. With this release, the NS autolabeler uses the namespace of the `RoleBinding` object if the `.subject[].namespace` is not specified. (link: https://issues.redhat.com/browse/OCPBUGS-160 [* OCPBUGS-160 *])
    • Bug Fix
    • Done

      Description of problem:

      The NS autolabeler should adjust the PSS namespace labels such that a previously permitted workload (based on the SCCs it has access to) can still run.

      The autolabeler requires the RoleBinding's .subjects[].namespace to be set when .subjects[].kind is ServiceAccount even though this is not required by the RBAC system to successfully bind the SA to a Role

      Version-Release number of selected component (if applicable):

      $ oc version
      Client Version: 4.7.0-0.ci-2021-05-21-142747
      Server Version: 4.12.0-0.nightly-2022-08-15-150248
      Kubernetes Version: v1.24.0+da80cd0

      How reproducible: 100%

      Steps to Reproduce:

      ---
      apiVersion: v1
      kind: Namespace
      metadata:
        name: test

      ---
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: mysa
        namespace: test

      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: Role
      metadata:
        name: myrole
        namespace: test
      rules:
      - apiGroups:
        - security.openshift.io
        resourceNames:
        - privileged
        resources:
        - securitycontextconstraints
        verbs:
        - use

      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: RoleBinding
      metadata:
        name: myrb
        namespace: test
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: Role
        name: myrole
      subjects:
      - kind: ServiceAccount
        name: mysa
        #namespace: test  # This is required for the autolabeler

      ---
      kind: Job
      apiVersion: batch/v1
      metadata:
        name: myjob
        namespace: test
      spec:
        template:
          spec:
            containers:
              - name: ubi
                image: registry.access.redhat.com/ubi8
                command: ["/bin/bash", "-c"]
                args: ["whoami; sleep infinity"]
            restartPolicy: Never
            securityContext:
              runAsUser: 0
            serviceAccount: mysa
            terminationGracePeriodSeconds: 2
      {{}}

      Actual results:

      Applying the manifest, above, the Job's pod will not start:

      $ kubectl -n test describe job/myjob...Events:
        Type     Reason        Age   From            Message
        ----     ------        ----  ----            -------
        Warning  FailedCreate  20s   job-controller  Error creating: pods "myjob-zxcvv" is forbidden: violates PodSecurity "restricted:v1.24": allowPrivilegeEscalation != false (container "ubi" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "ubi" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "ubi" must set securityContext.runAsNonRoot=true), runAsUser=0 (pod must not set runAsUser=0), seccompProfile (pod or container "ubi" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
        Warning  FailedCreate  20s   job-controller  Error creating: pods "myjob-fkb9x" is forbidden: violates PodSecurity "restricted:v1.24": allowPrivilegeEscalation != false (container "ubi" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "ubi" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "ubi" must set securityContext.runAsNonRoot=true), runAsUser=0 (pod must not set runAsUser=0), seccompProfile (pod or container "ubi" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
        Warning  FailedCreate  10s   job-controller  Error creating: pods "myjob-5klpc" is forbidden: violates PodSecurity "restricted:v1.24": allowPrivilegeEscalation != false (container "ubi" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "ubi" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "ubi" must set securityContext.runAsNonRoot=true), runAsUser=0 (pod must not set runAsUser=0), seccompProfile (pod or container "ubi" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")

      Uncommenting the "namespace" field in the RoleBinding will allow it to start as the autolabeler will adjust the Namespace labels.

      However, the namespace field isn't actually required by the RBAC system. Instead of using the autolabeler, the pod can be allowed to run by (w/o uncommenting the field):

      $ kubectl label ns/test security.openshift.io/scc.podSecurityLabelSync=false
      namespace/test labeled
      $ kubectl label ns/test pod-security.kubernetes.io/enforce=privileged --overwrite
      namespace/test labeled

       

      We now see that the pod is running as root and has access to the privileged scc:

      $ kubectl -n test get po -oyaml
      apiVersion: v1
      items:
      - apiVersion: v1
        kind: Pod
        metadata:
          annotations:
            k8s.ovn.org/pod-networks: '{"default":{"ip_addresses":["10.129.2.18/23"],"mac_address":"0a:58:0a:81:02:12","gateway_ips":["10.129.2.1"],"ip_address":"10.129.2.18/23","gateway_ip":"10.129.2.1"'}}
            k8s.v1.cni.cncf.io/network-status: |-
              [{
                  "name": "ovn-kubernetes",
                  "interface": "eth0",
                  "ips": [
                      "10.129.2.18"
                  ],
                  "mac": "0a:58:0a:81:02:12",
                  "default": true,
                  "dns": {}
              }]
            k8s.v1.cni.cncf.io/networks-status: |-
              [{
                  "name": "ovn-kubernetes",
                  "interface": "eth0",
                  "ips": [
                      "10.129.2.18"
                  ],
                  "mac": "0a:58:0a:81:02:12",
                  "default": true,
                  "dns": {}
              }]
            openshift.io/scc: privileged
          creationTimestamp: "2022-08-16T13:08:24Z"
          generateName: myjob-
          labels:
            controller-uid: 1867dbe6-73b2-44ea-a324-45c9273107b8
            job-name: myjob
          name: myjob-rwjmv
          namespace: test
          ownerReferences:
          - apiVersion: batch/v1
            blockOwnerDeletion: true
            controller: true
            kind: Job
            name: myjob
            uid: 1867dbe6-73b2-44ea-a324-45c9273107b8
          resourceVersion: "36418"
          uid: 39f18dea-31d4-4783-85b5-8ae6a8bec1f4
        spec:
          containers:
          - args:
            - whoami; sleep infinity
            command:
            - /bin/bash
            - -c
            image: registry.access.redhat.com/ubi8
            imagePullPolicy: Always
            name: ubi
            resources: {}
            terminationMessagePath: /dev/termination-log
            terminationMessagePolicy: File
            volumeMounts:
            - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
              name: kube-api-access-6f2h6
              readOnly: true
          dnsPolicy: ClusterFirst
          enableServiceLinks: true
          imagePullSecrets:
          - name: mysa-dockercfg-mvmtn
          nodeName: ip-10-0-140-172.ec2.internal
          preemptionPolicy: PreemptLowerPriority
          priority: 0
          restartPolicy: Never
          schedulerName: default-scheduler
          securityContext:
            runAsUser: 0
          serviceAccount: mysa
          serviceAccountName: mysa
          terminationGracePeriodSeconds: 2
          tolerations:
          - effect: NoExecute
            key: node.kubernetes.io/not-ready
            operator: Exists
            tolerationSeconds: 300
          - effect: NoExecute
            key: node.kubernetes.io/unreachable
            operator: Exists
            tolerationSeconds: 300
          volumes:
          - name: kube-api-access-6f2h6
            projected:
              defaultMode: 420
              sources:
              - serviceAccountToken:
                  expirationSeconds: 3607
                  path: token
              - configMap:
                  items:
                  - key: ca.crt
                    path: ca.crt
                  name: kube-root-ca.crt
              - downwardAPI:
                  items:
                  - fieldRef:
                      apiVersion: v1
                      fieldPath: metadata.namespace
                    path: namespace
              - configMap:
                  items:
                  - key: service-ca.crt
                    path: service-ca.crt
                  name: openshift-service-ca.crt
        status:
          conditions:
          - lastProbeTime: null
            lastTransitionTime: "2022-08-16T13:08:24Z"
            status: "True"
            type: Initialized
          - lastProbeTime: null
            lastTransitionTime: "2022-08-16T13:08:28Z"
            status: "True"
            type: Ready
          - lastProbeTime: null
            lastTransitionTime: "2022-08-16T13:08:28Z"
            status: "True"
            type: ContainersReady
          - lastProbeTime: null
            lastTransitionTime: "2022-08-16T13:08:24Z"
            status: "True"
            type: PodScheduled
          containerStatuses:
          - containerID: cri-o://8fd1c3a5ee565a1089e4e6032bd04bceabb5ab3946c34a2bb55d3ee696baa007
            image: registry.access.redhat.com/ubi8:latest
            imageID: registry.access.redhat.com/ubi8@sha256:08e221b041a95e6840b208c618ae56c27e3429c3dad637ece01c9b471cc8fac6
            lastState: {}
            name: ubi
            ready: true
            restartCount: 0
            started: true
            state:
              running:
                startedAt: "2022-08-16T13:08:28Z"
          hostIP: 10.0.140.172
          phase: Running
          podIP: 10.129.2.18
          podIPs:
          - ip: 10.129.2.18
          qosClass: BestEffort
          startTime: "2022-08-16T13:08:24Z"
      kind: List
      metadata:
        resourceVersion: ""
      {{}}

       

      $ kubectl -n test logs job/myjob
      root

       

      Expected results:

      The autolabeler should properly follow the RoleBinding back to the SCC

       

      Additional info:

              rh-ee-irinis Ilias Rinis
              jstrunk@redhat.com John Strunk
              Debargha Mukherjee Debargha Mukherjee (Inactive)
              Giriyamma Karagere Ramaswamy (Inactive)
              Votes:
              1 Vote for this issue
              Watchers:
              13 Start watching this issue

                Created:
                Updated:
                Resolved: