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

Authorization with ClusterRoleBinding not working as expected when using system:serviceaccounts

XMLWordPrintable

    • Important
    • No
    • Rejected
    • False
    • Hide

      None

      Show
      None

      Description of problem:

      Authorization by OpenShift Container Platform 4 is not working as expected, when using system:serviceaccounts Group in the ClusterRoleBinding.
      
      Here, one would assume that every serviceAccount would be granted the permissions to access the defined resources but actually access is denied.
      
      $ curl -k -X POST -H "Content-Type: application/json" -H "Authorization: Bearer <token>" --data "@/tmp/post.json" https://api.<url>:6443/apis/authorization.k8s.io/v1/subjectaccessreviews
      {
        "kind": "SubjectAccessReview",
        "apiVersion": "authorization.k8s.io/v1",
        "metadata": {
          "creationTimestamp": null,
          "managedFields": [
            {
              "manager": "curl",
              "operation": "Update",
              "apiVersion": "authorization.k8s.io/v1",
              "time": "2023-03-13T09:17:45Z",
              "fieldsType": "FieldsV1",
              "fieldsV1": {
                "f:spec": {
                  "f:resourceAttributes": {
                    ".": {},
                    "f:group": {},
                    "f:name": {},
                    "f:namespace": {},
                    "f:resource": {},
                    "f:verb": {}
                  },
                  "f:user": {}
                }
              }
            }
          ]
        },
        "spec": {
          "resourceAttributes": {
            "namespace": "project-100",
            "verb": "use",
            "group": "sharedresource.openshift.io",
            "resource": "sharedsecrets",
            "name": "shared-subscription"
          },
          "user": "system:serviceaccount:project-100:builder"
        },
        "status": {
          "allowed": false
        }
      }
      
      When specifying the serviceAccount in the ClusterRoleBinding access is granted:
      
      $ oc get clusterrolebinding shared-secret-cluster-role-binding -o yaml
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        annotations:
          kubectl.kubernetes.io/last-applied-configuration: |
            {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"ClusterRoleBinding","metadata":{"annotations":{},"name":"shared-secret-cluster-role-binding"},"roleRef":{"apiGroup":"rbac.authorization.k8s.io","kind":"ClusterRole","name":"shared-secret-cluster-role"},"subjects":[{"apiGroup":"rbac.authorization.k8s.io","kind":"Group","name":"system:serviceaccounts"}]}
        creationTimestamp: "2023-03-13T08:59:46Z"
        name: shared-secret-cluster-role-binding
        resourceVersion: "1575464"
        uid: dd11825d-834a-4807-ab82-30dc0a415985
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: shared-secret-cluster-role
      subjects:
      - apiGroup: rbac.authorization.k8s.io
        kind: Group
        name: system:serviceaccounts
      - kind: ServiceAccount
        name: builder
        namespace: project-101
      
      $ curl -k -X POST -H "Content-Type: application/json" -H "Authorization: Bearer <token>" --data "@/tmp/post.json" https://api.<url>:6443/apis/authorization.k8s.io/v1/subjectaccessreviews
      {
        "kind": "SubjectAccessReview",
        "apiVersion": "authorization.k8s.io/v1",
        "metadata": {
          "creationTimestamp": null,
          "managedFields": [
            {
              "manager": "curl",
              "operation": "Update",
              "apiVersion": "authorization.k8s.io/v1",
              "time": "2023-03-13T09:16:47Z",
              "fieldsType": "FieldsV1",
              "fieldsV1": {
                "f:spec": {
                  "f:resourceAttributes": {
                    ".": {},
                    "f:group": {},
                    "f:name": {},
                    "f:namespace": {},
                    "f:resource": {},
                    "f:verb": {}
                  },
                  "f:user": {}
                }
              }
            }
          ]
        },
        "spec": {
          "resourceAttributes": {
            "namespace": "project-101",
            "verb": "use",
            "group": "sharedresource.openshift.io",
            "resource": "sharedsecrets",
            "name": "shared-subscription"
          },
          "user": "system:serviceaccount:project-101:builder"
        },
        "status": {
          "allowed": true,
          "reason": "RBAC: allowed by ClusterRoleBinding \"shared-secret-cluster-role-binding\" of ClusterRole \"shared-secret-cluster-role\" to ServiceAccount \"builder/project-101\""
        }
      }
      
      Both namespaces exist and have the serviceAccount automatically created.
      
      $ oc get sa -n project-100
      NAME       SECRETS   AGE
      builder    1         11m
      default    1         11m
      deployer   1         11m
      
      $ oc get sa -n project-101
      NAME       SECRETS   AGE
      builder    1         4m1s
      default    1         4m1s
      deployer   1         4m
      
      The difference is only how authorization is granted. For project-101 the serviceAccount is explicitly granted while for project-100 authorization should be granted via Group called system:serviceaccounts
      

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

      OpenShift Container Platform 4.12.5

      How reproducible:

      Always

      Steps to Reproduce:

      1. Install OpenShift Container Platform 4.12
      2. Create SharedSecret CRD using oc apply -f https://raw.githubusercontent.com/openshift/api/master/sharedresource/v1alpha1/0000_10_sharedsecret.crd.yaml
      3. Create SharedSecret resource:
      $ oc get sharedsecret shared-subscription -o yaml
      apiVersion: sharedresource.openshift.io/v1alpha1
      kind: SharedSecret
      metadata:
        annotations:
          kubectl.kubernetes.io/last-applied-configuration: |
            {"apiVersion":"sharedresource.openshift.io/v1alpha1","kind":"SharedSecret","metadata":{"annotations":{},"name":"shared-subscription"},"spec":{"secretRef":{"name":"etc-pki-entitlement","namespace":"openshift-config-managed"}}}
        creationTimestamp: "2023-03-13T08:54:48Z"
        generation: 1
        name: shared-subscription
        resourceVersion: "1567499"
        uid: 15c350aa-0de1-4a02-b876-9b822ba0afe5
      spec:
        secretRef:
          name: etc-pki-entitlement
          namespace: openshift-config-managed
      4. Create ClusterRole to grant access to SharedSecret:
      $ oc get clusterrole shared-secret-cluster-role -o yaml
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        annotations:
          kubectl.kubernetes.io/last-applied-configuration: |
            {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"ClusterRole","metadata":{"annotations":{},"name":"shared-secret-cluster-role"},"rules":[{"apiGroups":["sharedresource.openshift.io"],"resourceNames":["shared-subscription"],"resources":["sharedsecrets"],"verbs":["use"]}]}
        creationTimestamp: "2023-03-13T08:57:24Z"
        name: shared-secret-cluster-role
        resourceVersion: "1568481"
        uid: 99324722-ac62-4bb8-a7fe-7ac915393e19
      rules:
      - apiGroups:
        - sharedresource.openshift.io
        resourceNames:
        - shared-subscription
        resources:
        - sharedsecrets
        verbs:
        - use
      5. Create ClusterRoleBinding to access SharedSecret
      $ oc get clusterrolebinding shared-secret-cluster-role-binding -o yaml
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        annotations:
          kubectl.kubernetes.io/last-applied-configuration: |
            {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"ClusterRoleBinding","metadata":{"annotations":{},"name":"shared-secret-cluster-role-binding"},"roleRef":{"apiGroup":"rbac.authorization.k8s.io","kind":"ClusterRole","name":"shared-secret-cluster-role"},"subjects":[{"apiGroup":"rbac.authorization.k8s.io","kind":"Group","name":"system:serviceaccounts"}]}
        creationTimestamp: "2023-03-13T08:59:46Z"
        name: shared-secret-cluster-role-binding
        resourceVersion: "1575464"
        uid: dd11825d-834a-4807-ab82-30dc0a415985
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: shared-secret-cluster-role
      subjects:
      - apiGroup: rbac.authorization.k8s.io
        kind: Group
        name: system:serviceaccounts
      - kind: ServiceAccount
        name: builder
        namespace: project-101
      6. Run SubjectAccessReview call to validate authoriztion:
      $ curl -k -X POST -H "Content-Type: application/json" -H "Authorization: Bearer <token>" --data "@/tmp/post.json" https://api.<url>:6443/apis/authorization.k8s.io/v1/subjectaccessreviews
      {
        "kind": "SubjectAccessReview",
        "apiVersion": "authorization.k8s.io/v1",
        "metadata": {
          "creationTimestamp": null,
          "managedFields": [
            {
              "manager": "curl",
              "operation": "Update",
              "apiVersion": "authorization.k8s.io/v1",
              "time": "2023-03-13T09:17:45Z",
              "fieldsType": "FieldsV1",
              "fieldsV1": {
                "f:spec": {
                  "f:resourceAttributes": {
                    ".": {},
                    "f:group": {},
                    "f:name": {},
                    "f:namespace": {},
                    "f:resource": {},
                    "f:verb": {}
                  },
                  "f:user": {}
                }
              }
            }
          ]
        },
        "spec": {
          "resourceAttributes": {
            "namespace": "project-100",
            "verb": "use",
            "group": "sharedresource.openshift.io",
            "resource": "sharedsecrets",
            "name": "shared-subscription"
          },
          "user": "system:serviceaccount:project-100:builder"
        },
        "status": {
          "allowed": false
        }
      }
      

      Actual results:

      $ curl -k -X POST -H "Content-Type: application/json" -H "Authorization: Bearer <token>" --data "@/tmp/post.json" https://api.<url>:6443/apis/authorization.k8s.io/v1/subjectaccessreviews
      {
        "kind": "SubjectAccessReview",
        "apiVersion": "authorization.k8s.io/v1",
        "metadata": {
          "creationTimestamp": null,
          "managedFields": [
            {
              "manager": "curl",
              "operation": "Update",
              "apiVersion": "authorization.k8s.io/v1",
              "time": "2023-03-13T09:17:45Z",
              "fieldsType": "FieldsV1",
              "fieldsV1": {
                "f:spec": {
                  "f:resourceAttributes": {
                    ".": {},
                    "f:group": {},
                    "f:name": {},
                    "f:namespace": {},
                    "f:resource": {},
                    "f:verb": {}
                  },
                  "f:user": {}
                }
              }
            }
          ]
        },
        "spec": {
          "resourceAttributes": {
            "namespace": "project-100",
            "verb": "use",
            "group": "sharedresource.openshift.io",
            "resource": "sharedsecrets",
            "name": "shared-subscription"
          },
          "user": "system:serviceaccount:project-100:builder"
        },
        "status": {
          "allowed": false
        }
      }
       

      Expected results:

      $ curl -k -X POST -H "Content-Type: application/json" -H "Authorization: Bearer <token>" --data "@/tmp/post.json" https://api.<url>:6443/apis/authorization.k8s.io/v1/subjectaccessreviews
      {
        "kind": "SubjectAccessReview",
        "apiVersion": "authorization.k8s.io/v1",
        "metadata": {
          "creationTimestamp": null,
          "managedFields": [
            {
              "manager": "curl",
              "operation": "Update",
              "apiVersion": "authorization.k8s.io/v1",
              "time": "2023-03-13T09:16:47Z",
              "fieldsType": "FieldsV1",
              "fieldsV1": {
                "f:spec": {
                  "f:resourceAttributes": {
                    ".": {},
                    "f:group": {},
                    "f:name": {},
                    "f:namespace": {},
                    "f:resource": {},
                    "f:verb": {}
                  },
                  "f:user": {}
                }
              }
            }
          ]
        },
        "spec": {
          "resourceAttributes": {
            "namespace": "project-101",
            "verb": "use",
            "group": "sharedresource.openshift.io",
            "resource": "sharedsecrets",
            "name": "shared-subscription"
          },
          "user": "system:serviceaccount:project-101:builder"
        },
        "status": {
          "allowed": true,
          "reason": "RBAC: allowed by ClusterRoleBinding \"shared-secret-cluster-role-binding\" of ClusterRole \"shared-secret-cluster-role\" to ServiceAccount \"builder/project-101\""
        }
      }
       

      Additional info:

      The goal is to use the Group "system:serviceaccounts" to authorize all serviceAccounts to access the given resources to avoid listing all namespaces specifically and thus have the need to create a controller that needs to update a list or similar.
       

            gmontero@redhat.com Gabe Montero
            rhn-support-sreber Simon Reber
            Jitendar Singh Jitendar Singh
            Votes:
            0 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated:
              Resolved: