Role definition for Kubernetes user to work on single namespace - kubernetes

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

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.

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.

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.

How to add or introduce a kubernetes normal user?

I saw it on offical doc, but I don't know how to add or introduce a normal user outside kubernetes clusters. And I searched a lot about normal user in kubernetes but nothing useful.
I know it's different from serviceaccount and we cannot add a normal user through Kubernetes API.
Any idea about how to add or introduce a normal user to kubernetes cluster and what's normal user for?
See "Comparing Kubernetes Authentication Methods" by Etienne Dilocker
A possible solution is the x509 client certs:
Advantages
operating the Kubernetes cluster and issuing user certificates is decoupled
much more secure than basic authentication
Disadvantages
x509 certificates tend to have a very long lifetime (months or years). So, revoking user access is nearly impossible. If we instead choose to issue short-lived certificates, the user experience drops, because replacing certificates involves some effort.
But Etienne recommends OpenID:
Wouldn’t it be great if we could have short-lived certificates or tokens, that are issued by a third-party, so there is no coupling to the operators of the K8s cluster.
And at the same time all of this should be integrated with existing enterprise infrastructure, such as LDAP or Active Directory.
This is where OpenID Connect (OIDC) comes in.
For my example, I’ve used Keycloak as a token issuer. Keycloak is both a token issuer and an identity provider out-of-the box and quite easy to spin up using Docker.
To use RBAC with that kind of authentication is not straight-forward, but possible.
See "issue 118; Security, auth and logging in"
With 1.3 I have SSO into the dashboard working great with a reverse proxy and OIDC/OAuth2. I wouldn't create an explicit login screen, piggy back off of the RBAC model and the Auth model that is already supported. It would be great to have something that says who the logged in user is though.
Note that since 1.3, there might be simpler solution.
The same thread includes:
I have a prototype image working that will do what I think you're looking for: https://hub.docker.com/r/mlbiam/openunison-k8s-dashboard/
I removed all the requirements for user provisioning and stripped it down to just:
reverse proxy
integration with openid connect
display the user's access token
simple links page
It includes the role binding:
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1alpha1
metadata:
name: admin-role
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
nonResourceURLs: ["*"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1alpha1
metadata:
name: admin-binding
subjects:
- kind: Group
name: admin
- kind: ServiceAccount
name: default
namespace: kube-system
- kind: ServiceAccount
name: openunison
namespace: default
roleRef:
kind: ClusterRole
name: admin-role
Again, this was specific to the dashboard RBAC access, and has since been improved with PR 2206 Add log in mechanism (to dashboard).
It still can give you some clues in order to link a regular user to kubernetes RBAC.

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.