Allowing patching of Kubernetes resource metadata through a role - kubernetes

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.

Related

[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.

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."

K8s RBAC serviceaccount with extended permissions

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.

Kubernetes RBAC cluster-admin without secret reading permission

Is it possible to create a Kubernetes cluster admin without the ability to read namespace secrets?
I know you can create a ClusterRole and list every single resource and omit secret but seems unintuitive.
Can you use Aggregated ClusterRoles to remove a permission? so using ClusterRole cluster-admin and have a role that uses:
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: [""]
Not really Aggregated Cluster Roles is a set union of several ClusterRoles. To get the behavior you want you would need a set subtraction of cluster-admin role minus the rules that you have defined. It's not supported in K8s as of this writing.

How can I create a Kubernetes role in which a users can create namespaces in which they can do anything?

I have created a role, below is definition the role:
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: ${SERVICE_ACCOUNT_NAME}-full-access-role
namespace: ${NAMESPACE}
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["*"]
verbs: ["*"]
- apiGroups: ["batch"]
resources:
- jobs
- cronjobs
verbs: ["*"]
Using this role a user can create, list and delete any resource in a namespace but problem is it can also list all namespaces in cluster.
I want to enable users to create namespaces and can perform any action in it as well but also they can't list any resource even other namespaces that are't created by the user.
I think you cannot deny user access right to list all namespaces and give them the access you need at the same. At least not in the bare metal kubernetes. Read the following GH issue, it's about the similar issue that you encounter.
It would help if you can tell us which cloud platform you are on. To my knowledge, different cloud platforms handle Role based access differently.
With that being said, I believe there should be predefined roles for the specific level of access you want. Usually role based authorization trickles down. If you grant someone access to a resource at the folder level, the user will be able to access all resources in that folder. Since you want to grant access to any resource in an namespace, I would grant the user access at that level.