I want to allow a ServiceAccount in namespace A to access a resource in namespace B. To achieve this I connect the ServiceAccount to a ClusterRole via a ClusterRoleBinding. The documentation says I can "use a ClusterRole to 1. define permissions on namespaced resources and be granted within individual namespace(s)"
But looking through the K8s documentation I can't find a way how to create a ClusterRole with namespaced resources. How can I achieve this?
I believe you need to create clusterrole not role. example:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: role-grantor
rules:
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["rolebindings"]
verbs: ["create"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles"]
verbs: ["bind"]
# omit resourceNames to allow binding any ClusterRole
resourceNames: ["admin","edit","view"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: role-grantor-binding
namespace: user-1-namespace
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: role-grantor
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: user-1
above example is from this link.
I find both other answers a little confusing, hopefully this is clearer.
You did the right thing in creating a ClusterRole
, but you want to bind it using a namespaced RoleBinding
, not a ClusterRoleBinding
.
Example using your examples. Notice how the RoleBinding
is in the B namespace, giving A's ServiceAccount
the permissions defined in the ClusterRole
, but limited to the B namespace.
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: what-a-is-allowed-to-do-in-b
rules:
- apiGroups: [""]
resources: ["pods", "deployments"] # etc
verbs: ["get", "list", "create"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app
namespace: namespace-a
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: what-a-is-allowed-to-do-in-b
namespace: namespace-b
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: what-a-is-allowed-to-do-in-b
subjects:
- kind: ServiceAccount
name: my-app
namespace: namespace-a
Notes:
You have to use the ClusterRole because you can't get outside your own namespace without one. By using a RoleBinding
, which is namespaced, you can then limit the access to the scope of the namespace of that RoleBinding
.
...how to create a ClusterRole with namespaced resources...
Read further down a bit:
A ClusterRole can be used to grant the same permissions as a Role. Because ClusterRoles are cluster-scoped. You can also use them to grant access to:
...
- namespaced resources (like Pods), across all namespaces
ClusterRole
won't help you to restraint access to a single namespaced object. You can however use RoleBinding
to reference a ClusterRole
and restraint access to the object in the namespace of the RoleBinding.