Lab 04: Managing RBAC and Custom Kubeconfigs on OKS
In this lab, you will learn how to use OKS CLI to manage access to a Kubernetes cluster. You will discover how to create users, assign roles through RBAC (Role-Based Access Control), and generate secure kubeconfigs to manage access to Kubernetes resources with fine-grained control. We will also cover how to secure kubeconfigs through encryption.
Prerequisites
Section intitulée « Prerequisites »- Access to a Kubernetes cluster via OKS.
- The OKS CLI tool installed and configured.
- A project in OKS with sufficient permissions to create roles and generate kubeconfigs.
Verify Cluster Access
Section intitulée « Verify Cluster Access »Make sure you have the required permissions to access the target cluster. You must have a user or role that allows you to export or retrieve the cluster configuration.
Retrieve the kubeconfig file
Section intitulée « Retrieve the kubeconfig file »oks-cli cluster kubeconfig --cluster-name my-cluster --project-name my-project > kubeconfig.yamlexport KUBECONFIG=./kubeconfig.yamlTest the cluster
Section intitulée « Test the cluster »kubectl get nodesPart 1: Preparing Roles with RBAC
Section intitulée « Part 1: Preparing Roles with RBAC »In this section, we will create roles with different permissions to grant access to the cluster based on user needs.
1.1 Create a namespace-admin role
Section intitulée « 1.1 Create a namespace-admin role »The namespace-admin role grants full access to a specific namespace.
This can be useful for namespace administrators who need to manage all resources within a given namespace.
First, we will create the dev namespace where we will work.
Either directly from the command line (imperative mode):
kubectl create namespace devnamespace/dev createdOr declaratively using a ns-dev.yaml file like this:
apiVersion: v1kind: Namespacemetadata: name: devkubectl apply -f ns-dev.yamlThen, create a YAML file to define a namespace-admin role and a RoleBinding in a namespace called dev.
# ServiceAccountapiVersion: v1kind: ServiceAccountmetadata: name: namespace-admin namespace: dev
---# Role (with all permissions in the namespace)apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: name: namespace-admin-role namespace: devrules: - apiGroups: ["*"] resources: ["*"] verbs: ["*"]
---# RoleBinding (bound to the ServiceAccount)apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata: name: namespace-admin-binding namespace: devsubjects:- kind: Group name: namespace-admin namespace: devroleRef: kind: Role name: namespace-admin-role apiGroup: rbac.authorization.k8s.ioApply this manifest to your cluster with the following command:
kubectl apply -f namespace-admin-role.yamlThis creates a role that grants full access (*) to all resources in the dev namespace and binds it to the namespace-admin group.
Verify that all objects were created successfully:
kubectl get role,rolebindings,sa --namespace devNAME CREATED ATrole.rbac.authorization.k8s.io/namespace-admin-role 2025-06-16T13:44:08Z
NAME ROLE AGErolebinding.rbac.authorization.k8s.io/namespace-admin-binding Role/namespace-admin-role 65s
NAME SECRETS AGEserviceaccount/default 0 3m4sserviceaccount/namespace-admin 0 94sFor the rest of this lab, we will launch an nginx pod in the dev namespace and come back to it later.
kubectl run nginx --image=nginx --namespace devpod/nginx created1.2 Create a readonly-users role
Section intitulée « 1.2 Create a readonly-users role »The readonly-users role will be used to grant read-only access to all cluster resources.
Create a YAML file to define a ClusterRole called readonly and a ClusterRoleBinding for the readonly-users group.
# ClusterRole (read-only)apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: name: readonly labels: app.kubernetes.io/name: readonly app.kubernetes.io/part-of: rbac-systemrules:- apiGroups: ["*"] resources: ["*"] verbs: ["get", "list", "watch"]
---# ClusterRoleBinding (bound to the readonly-users group)apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: name: readonly-binding labels: app.kubernetes.io/name: readonly-binding app.kubernetes.io/part-of: rbac-systemsubjects:- kind: Group name: readonly-users apiGroup: rbac.authorization.k8s.ioroleRef: kind: ClusterRole name: readonly apiGroup: rbac.authorization.k8s.ioApply this manifest to your cluster:
kubectl apply -f readonly-role.yamlThis grants read-only access to all cluster resources for users in the readonly-users group.
Part 2: Generating kubeconfigs for users
Section intitulée « Part 2: Generating kubeconfigs for users »Once the roles are created, we need to generate kubeconfig files for each user group so they can access the cluster with the appropriate permissions.
2.1 Generate a kubeconfig for the namespace-admin group
Section intitulée « 2.1 Generate a kubeconfig for the namespace-admin group »To grant access to the namespace-admin group, generate a kubeconfig containing the authentication information and the required permissions.
oks-cli cluster kubeconfig --cluster-name my-cluster --project-name my-project --group "namespace-admin" --refresh > namespace-admin-kubeconfig.yamlThis command generates a kubeconfig for the namespace-admin group and updates it with the permissions of the namespace-admin role in the dev namespace.
We will now verify that the namespace-admin group has access to all resources in the dev namespace, but not to other namespaces.
Start by using the configuration file to access the cluster as a user in the namespace-admin group:
export KUBECONFIG=./namespace-admin-kubeconfig.yamlLet’s verify that we can create a new pod with our namespace-admin role:
kubectl run nginx2 --image=nginx --namespace devpod/nginx2 createdNow list the pods in the dev namespace. We should see the nginx pod created earlier when setting up the namespace-admin role, as well as the new nginx2 pod:
kubectl get pods --namespace devNAME READY STATUS RESTARTS AGEnginx 1/1 Running 0 23mnginx2 1/1 Running 0 1mNow let’s verify that we cannot create or list anything in another namespace, for example the default namespace:
kubectl get pods --namespace defaultError from server (Forbidden): pods is forbidden: User "kube-user" cannot list resource "pods" in API group "" in the namespace "default"This is the expected result: our role gives us access only to the dev namespace and no others.
2.2 Generate a kubeconfig for the readonly-users group
Section intitulée « 2.2 Generate a kubeconfig for the readonly-users group »Similarly, generate a kubeconfig for users in the readonly-users group to allow them read-only access to the cluster.
oks-cli cluster kubeconfig --cluster-name my-cluster --project-name my-project --group "readonly-users" --user user1 --ttl 2592000 > readonly-users-kubeconfig.yamlThis command generates a kubeconfig for the readonly-users group and updates it with read-only permissions.
We will now verify that we have read-only access to all cluster resources, but cannot create Kubernetes resources.
Start by using the configuration file to access the cluster as a user in the readonly-users group:
export KUBECONFIG=./readonly-users-kubeconfig.yamlLet’s start by listing the cluster nodes:
kubectl get nodesNAME STATUS ROLES AGE VERSIONip-10-50-102-69 Ready <none> 27d v1.31.2ip-10-50-62-80 Ready <none> 27d v1.31.2ip-10-50-90-105 Ready <none> 27d v1.31.2Let’s see whether we can list the pods in the kube-system namespace:
kubectl get pods -n kube-system kubectl get pods -n kube-systemNAME READY STATUS RESTARTS AGEcilium-548fj 1/1 Running 0 27dcilium-envoy-6jw85 1/1 Running 0 27dcilium-envoy-82kvq 1/1 Running 0 27dcilium-envoy-97qvx 1/1 Running 0 27dcilium-n75s9 1/1 Running 0 27dcilium-operator-5d59c9cd6d-j7g9v 1/1 Running 0 27dcilium-z7kpt 1/1 Running 0 27dcoredns-5658776d8b-gdf7p 1/1 Running 0 27dcoredns-5658776d8b-lff49 1/1 Running 0 27dimds-provider-ip-10-50-102-69 1/1 Running 0 27dimds-provider-ip-10-50-62-80 1/1 Running 0 27dimds-provider-ip-10-50-90-105 1/1 Running 0 27dkonnectivity-agent-655br 1/1 Running 0 6dkonnectivity-agent-b6hbf 1/1 Running 0 27dkonnectivity-agent-gs4m7 1/1 Running 0 27dkonnectivity-agent-ldqzc 1/1 Running 0 6dkonnectivity-agent-wlnp8 1/1 Running 0 6dkonnectivity-agent-wp29w 1/1 Running 0 27dmetrics-server-56478ff848-q7w4v 1/1 Running 0 27dosc-csi-node-bbdsj 3/3 Running 0 27dosc-csi-node-l25dn 3/3 Running 1 (27d ago) 27dosc-csi-node-mx75h 3/3 Running 0 27dsnapshot-controller-9c8bd95c5-8f9rw 1/1 Running 0 27dsnapshot-controller-9c8bd95c5-cmp24 1/1 Running 0 27dTry creating a pod in the default namespace:
kubectl run nginx --image=nginx --namespace defaultError from server (Forbidden): pods is forbidden: User "kube-user" cannot create resource "pods" in API group "" in the namespace "default"This is the expected result: our readonly-users role only allows us to list and view resources across the entire cluster, but not to create any resources.
Part 3: Securing kubeconfigs with encryption
Section intitulée « Part 3: Securing kubeconfigs with encryption »To strengthen security, you can encrypt kubeconfigs to prevent Man-in-the-Middle (MitM) attacks and ensure that only authorized people can access sensitive information.
3.1 Generate an encrypted kubeconfig
Section intitulée « 3.1 Generate an encrypted kubeconfig »To encrypt a kubeconfig, you can use the --nacl option with the oks-cli cluster kubeconfig command.
oks-cli cluster kubeconfig --cluster-name my-cluster --project-name my-project --user USER2 --nacl--nacl: This option ensures that your kubeconfig is retrieved using public-key encryption during transmission.
Conclusion
Section intitulée « Conclusion »In this lab, you learned how to use OKS CLI to manage access to a Kubernetes cluster through RBAC. You created roles such as namespace-admin and readonly-users, and generated kubeconfigs to provide controlled access to users. You also learned how to secure your kubeconfigs by encrypting them to mitigate Man-in-the-Middle attacks.
This process allows you to manage permissions with fine granularity and protect access to your Kubernetes clusters effectively and securely.