NSS
NSS

Reputation: 795

Create kubeconfig with restricted permission

I need to create a kubeconfig with restricted access, I want to be able to provide permission to update configmap in specific namesapce, how can I create such a kubeconfig with the following permission

  1. for specefic namespace (myns)
  2. update only configmap (mycm)

Is there a simple way to create it ?

The tricky part here is that I need that some program will have access to cluster X and modify only this comfigMap, How would I do it from outside process without providing the full kubeconfig file which can be problematic from security reason

To make it clear, I own the cluster, I just want to give to some program restricted permissions

Upvotes: 1

Views: 3667

Answers (2)

hariK
hariK

Reputation: 3059

This is not straight forward. But still possible.

Create the namespace myns if not exists.

$ kubectl create ns myns
namespace/myns created

Create a service account cm-user in myns namespace. It'll create a secret token as well.

$ kubectl create sa cm-user -n myns
serviceaccount/cm-user created

$  kubectl get sa cm-user -n myns
NAME      SECRETS   AGE
cm-user   1         18s

$ kubectl get secrets -n myns
NAME                  TYPE                                  DATA   AGE
cm-user-token-kv5j5   kubernetes.io/service-account-token   3      63s
default-token-m7j9v   kubernetes.io/service-account-token   3      96s

Get the token and ca.crt from cm-user-token-kv5j5 secret.

$ kubectl get secrets cm-user-token-kv5j5 -n myns -oyaml

Base64 decode the value of token from cm-user-token-kv5j5.

Now create a user using the decoded token.

$ kubectl config set-credentials cm-user --token=<decoded token value>
User "cm-user" set.

Now generate a kubeconfig file kubeconfig-cm.

apiVersion: v1
kind: Config
clusters:
- cluster:
    certificate-authority-data: <ca.crt value from cm-user-token-kv5j5 secret>
    server: <kubernetes server>
  name: <cluster>
contexts:
- context:
    cluster:<cluster>
    namespace: myns
    user: cm-user
  name: cm-user
current-context: cm-user 
users:
- name: cm-user
  user:
    token: <decoded token>

Now create a role and rolebinding for sa cm-user.

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: myns
  name: cm-user-role
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["update", "get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: cm-user-rb
  namespace: myns
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: cm-user-role
subjects:
- namespace: myns
  kind: ServiceAccount
  name: cm-user

We are done. Now using this kubeconfig file you can update the mycm configmap. It doesn't have any other privileges.

$ kubectl get cm -n myns --kubeconfig kubeconfig-cm
NAME                 DATA   AGE
mycm                 0      8s

$ kubectl delete cm mycm -n myns --kubeconfig kubeconfig-cm
Error from server (Forbidden): configmaps "mycm" is forbidden: User "system:serviceaccount:myns:cm-user" cannot delete resource "configmaps" in API group "" in the namespace "myns"

Upvotes: 6

Arghya Sadhu
Arghya Sadhu

Reputation: 44559

You need to use RBAC and define role and then bind that role to a user or serviceaccount using rolebinding

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: configmap-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["configmaps"]
  verbs: ["update", "get", "list"]

---

apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "jane" to read config maps in the "default" namespace.
# You need to already have a Role named "configmap-reader" in that namespace.
kind: RoleBinding
metadata:
  name: read-configmap
  namespace: default
subjects:
# You can specify more than one "subject"
- kind: User
  name: jane # "name" is case sensitive
  apiGroup: rbac.authorization.k8s.io
roleRef:
  # "roleRef" specifies the binding to a Role / ClusterRole
  kind: Role #this must be Role or ClusterRole
  name: configmap-reader # this must match the name of the Role or ClusterRole you wish to bind to
  apiGroup: rbac.authorization.k8s.io

https://kubernetes.io/docs/reference/access-authn-authz/rbac/

Upvotes: 1

Related Questions