-
Bug
-
Resolution: Done-Errata
-
Major
-
4.12
-
Quality / Stability / Reliability
-
False
-
-
None
-
Important
-
No
-
None
-
Rejected
-
None
-
None
-
None
-
None
-
None
-
None
-
None
-
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.