K8s RBAC serviceaccount with extended permissions - kubernetes

I am looking for option to have serviceaccount (which is not cluster admins) to be able to create new namespace and automatically get admin permission on it (while all system namespaces are not editable by this serviceaccount).
Currently my serviceaccount binded to clusterrole contains
- apiGroups:
- ""
resources:
- namespaces
verbs:
- create
However it can't do anything on namespace it creates.
Would like to get any suggestions, recommendations.

Unfortunately, it is not possible to do using RBAC objects only.
In the RBAC API, a role contains rules that represent a set of
permissions. Permissions are purely additive (there are no “deny”
rules).
However there is a possible workaround:
you add a pod with Kubernetes python/go/java client inside, using service account with create-Roles+RoleBindings-permissions on a cluster level
then you run a simple code that monitor api-server for new namespaces and create RoleBinding for the namespace-admin in the new namespace
this RoleBinding refers to cluster-admin role, which gives the user all permission in the specific namespace
to differentiate new namespaces from existing ones, the script can also put a label on the namespace: namespace-admin=true or similar.
Also, you could consider using RBAC Manager. Dynamic Namespaces and Labels to be more specific.
RBAC Definitions can now include namespaceSelectors in place of
namespace attributes when specifying Role Binding configuration. This
can be incredibly helpful when working with dynamically provisioned
namespaces.
Please let me know if that helped.

Related

Is there a way to grant access to a ServiceAccount from all namespaces in Kubernetes? Or a cluster-wide ServiceAccount?

I'm going to have an unknown number of users access my K8s (specifically OpenShift if that helps) cluster. Each user will have their own random namespace. So I do not know the namespaces in advance as they will be dynamically created. But I want each user to be able to utilize a ServiceAccount that I create ahead of time.
So, if I create a ServiceAccount fooSA in my namespace foo, I'd like to be able to define a deployment that utilizes fooSA from the bar namespace. For example:
myapp.yaml
...
spec:
serviceAccount: fooSA
...
kubectl apply -f myapp.yaml -n bar
How can I accomplish this?
As ServiceAccounts are namespace scoped I cannot figure out a way to accomplish this.

[Kubernetes]- How to limit a user to only delete namespaces that have been dynamically created by the user?

I want to create a user that has permission to create temporary namespaces (i.e. create and then delete the namespaces) and have full access within these namespaces only, and without being able to delete any other namespaces within the cluster. My problem is that the namespaces in this case are created dynamically by the user with a random name each time...is there any way to meet this requirement for a user to:
Create namespace (with a random name that is only known after execution)
Have full access to this name space only
Able to delete this namespace only
You can first restrict user to create/delete resources only in the namespace using a Role bind that role to the user.
Then you can use ClusterRole with only access to the namespaces resource and allow it to create, delete, etc.
ClusterRole and Role define which resources you can operate on. If your role needs to manage resources in multiple namespaces, you need to use ClusterRole
and RoleBinding defines which namespace your account will be granted
Example:
Create a Role in the namespace that can be used to grant access to resources.
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: namespace1
name: user-namespace-role
rules:
- apiGroups: [""]
resources: ["services", "endpoints", "pods"] # etc...
verbs: ["get", "list", "create",”delete”] # etc
Then execute the below command which creates rolebinding that defines which namespace your account will be granted.
$ kubectl create rolebinding user-namespace-binding --role=user-namespace-role --user=<user-name> --namespace=namespace1
Now Create a ClusterRole that can be used to grant access in any particular namespace, or across all namespaces
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: cluster-role-all-namespaces
rules:
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] # etc
Then Execute the below command to create clusterrolebinding:
$ kubectl create clusterrolebinding all-namespaces-binding --clusterrole=cluster-role-all-namespaces --user=<username>
Refer to Using RBAC authorization for more information.
On my understanding there is no way to accomplish this kind of permissions - I know it's surprising because it would seem like a common use case. Using Roles, the rules only apply to the namespace the role belongs to, using an appropriate RoleBinding. Therefore we can limit actions on specific namespaces, but we cannot define a permission on a namespace with unknown name. Also using regex is not supported to match namespaces names. To solve it with Roles, we would have to apply the role every time a new namespace is created, I think makes no sense for the use case.
As you may know Kubernetes also defines cluster roles and cluster role bindings. Those are similar to normal roles but without a namespace limitation. Of course, using them in this case can break through the isolation we want, that's what they are meant to do.
What I suggest is to predefine a list of namespaces for which those accounts will have permissions. That means you need to create/use the same namespaces and to not generate them dinamically with random names. It also means that it will not be able to create new namespaces.
Lastly, I wanted to mention Hierarchical Namespaces. Under HNS, administrators can organize tenants according to a group hierarchy and allocate capabilities accordingly.

Allowing patching of Kubernetes resource metadata through a role

Is it somehow possible to seperately allow patching of resources' metadata through a role in a Kubernetes cluster?
I would like to solely allow patching of namespace's metadata without giving write permissions to the whole namespace object.
The usecase is to allow deployment pipelines to add/change annotations to the namespace without giving them full control.
To add/change namespace's metadata without giving write permissions to the whole namespace object, you can create a RBAC role where you can restrict access to namespace resources. So that deployment pipeline can have access to change only the metadata i.e., annotations to the namespace without giving them full control.
An RBAC Role contains rules that represent a set of permissions. Permissions are purely additive (there are no "deny" rules).
A Role always sets permissions within a particular namespace; when you create a Role, you have to specify the namespace it belongs in.
Let us consider an example Role in the namespace that can be used to grant read access to resources pods and services:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: <namespace-name>
name: read-access
rules:
- apiGroups: [""]
resources: ["pods", “services”]
verbs: ["get", "watch", "list"]
To grant read access to all the resources which are mentioned in the namespace, use this special character “*” in the resources field i.e., resources: ["*”].
Note : If you want to restrict resources to a specific user you can use Rolebinding. A role binding grants the permissions defined in a role to a user or set of users. It holds a list of subjects (users, groups, or service accounts), and a reference to the role being granted. A RoleBinding grants permissions within a specific namespace
Refer RBAC Role for more information.

Role definition for Kubernetes user to work on single namespace

I am currently facing the current situation. I want to give users access to individual namespaces, such that they can
create and deploy ressources with Helm charts (for instance, from Bitnami)
On the other hand the users are not supposed to
create/retrieve/modify/delete RBAC settings like ServiceAccounts, RoleBindings, Roles, NetworkPolicies
get hands on secrets associated to ServiceAccounts
Of course, the crucial thing is to define the best Role for it here. Likely, the following is not the best idea here:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: role
namespace: example-namespace
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
Hence, it would be great if you could come along with some sensible approach that the users can work on it as freely as possible, yet do not get hands on some more "dangerous" resources.
In essence, I want to follow the workflow outlined here (https://jeremievallee.com/2018/05/28/kubernetes-rbac-namespace-user.html). So what matters most is that individual users in one namespace, cannot read the secrets of the users in the same namespace, such that they cannot authenticate with the credentials of someone else.
In my opinion the following strategy will help:
RBAC to limit access to service accounts of own namespace only.
Make sure automountServiceAccountToken: false in secret and POD level using policies. This helps in protecting secrets when there is a node security breach. The secret will only be available for execution time and will not be stored in the POD.
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#use-the-default-service-account-to-access-the-api-server
Encrypt secrets stored in ETCD using kms(recommended). But if you dont have a kms provider then you can also choose other providers to ensure minimum security.
https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/#providers
Sound like the ClusterRole edit would almost fit your needs.
https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles
It will allow access to secrets "However, this role allows accessing Secrets and running Pods as any ServiceAccount in the namespace, so it can be used to gain the API access levels of any ServiceAccount in the namespace."

Kubernetes - ClusterRole with namespace is allowed?

The documentation says,
If you want to define a role within a namespace, use a Role; if you want to define a role cluster-wide, use a ClusterRole.
So, why am I able to create a ClusterRole in a namespace for a non-namespaced resource StorageClass (or, sc in short)?
kubectl -n apps create clusterrole scrole --verb=create,update,patch,delete --resource=sc
Also, is it correct to say that, a Role is applicable for namespaced resources only and ClusterRole for non-namespaced resources only?
The namespace parameter is redundant and not used even if you provide it while creating a ClusterRole.
A ClusterRole can define permission to namespace scoped resources as well and you can use a RoleBinding to assign the permission to a user or group or service account. When you do that it's basically providing permission to the resources within the namespace where the RoleBinding is created.This is to avoid creating duplicate Roles in every namespace to provide the same permission.
Also when you have cluster scoped resources in a ClusterRole you need to use a ClusterRoleBinding to assign the permission to a a user or group or service account.