-
Bug
-
Resolution: Done-Errata
-
Major
-
4.12
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.