{"id":22616,"date":"2024-05-25T21:35:43","date_gmt":"2024-05-25T18:35:43","guid":{"rendered":"https:\/\/kifarunix.com\/?p=22616"},"modified":"2024-05-26T09:57:19","modified_gmt":"2024-05-26T06:57:19","slug":"assign-roles-to-users-and-groups-in-kubernetes-cluster","status":"publish","type":"post","link":"https:\/\/kifarunix.com\/assign-roles-to-users-and-groups-in-kubernetes-cluster\/","title":{"rendered":"Assign Roles to Users and Groups in Kubernetes Cluster"},"content":{"rendered":"\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1071\" height=\"601\" src=\"https:\/\/kifarunix.com\/wp-content\/uploads\/2024\/05\/assign-roles-to-users-groups-kubernetes.png?v=1716706545\" alt=\"Assign Roles to Users and Groups in Kubernetes Cluster\" class=\"wp-image-22650\" title=\"\" srcset=\"https:\/\/kifarunix.com\/wp-content\/uploads\/2024\/05\/assign-roles-to-users-groups-kubernetes.png?v=1716706545 1071w, https:\/\/kifarunix.com\/wp-content\/uploads\/2024\/05\/assign-roles-to-users-groups-kubernetes-768x431.png?v=1716706545 768w\" sizes=\"(max-width: 1071px) 100vw, 1071px\" \/><\/figure>\n\n\n\n<p>In this tutorial, you will learn how to assign roles to users and groups in Kubernetes cluster. With Kubernetes becoming the de facto standard for container orchestration, managing access control is paramount to ensuring the security and integrity of your clusters. This guide will take you through how you control access to various resources by assigning necessary roles or permissions to users or respective groups in a Kubernetes cluster.<\/p>\n\n\n\n<div class=\"wp-block-rank-math-toc-block\" id=\"rank-math-toc\"><h2>Table of Contents<\/h2><nav><ul><li><a href=\"#assign-roles-to-users-and-groups-in-kubernetes-cluster\">Assign Roles to Users and Groups in Kubernetes Cluster<\/a><ul><li><a href=\"#introduction-to-role-based-access-control-in-kubernetes\">Introduction to Role-Based Access Control in Kubernetes<\/a><\/li><li><a href=\"#creating-user-accounts-in-kubernetes\">Creating User Accounts in Kubernetes<\/a><\/li><li><a href=\"#kubernetes-rbac-api-objects\">Kubernetes RBAC API Objects<\/a><\/li><li><a href=\"#creating-kubernetes-roles\">Creating Kubernetes Roles<\/a><ul><li><a href=\"#switch-to-cluster-admin-context\">Switch to Cluster Admin Context<\/a><\/li><li><a href=\"#create-user-role\">Create User Role<\/a><\/li><li><a href=\"#listing-roles\">Listing Roles<\/a><\/li><\/ul><\/li><li><a href=\"#assigning-roles-to-users-service-accounts\">Assigning Roles to Users\/Service Accounts<\/a><ul><li><a href=\"#create-kubernetes-role-bindings\">Create Kubernetes RoleBindings<\/a><\/li><li><a href=\"#listing-role-bindings\">Listing RoleBindings<\/a><\/li><li><a href=\"#verify-role-assignment-and-access-permissions\">Verify Role Assignment and Access Permissions<\/a><\/li><li><a href=\"#kubernetes-service-accounts-and-api-access-via-secrets-and-tokens\">Kubernetes Service Accounts and API Access (via Secrets and Tokens)<\/a><\/li><\/ul><\/li><li><a href=\"#assigning-roles-to-groups-in-kubernetes\">Assigning Roles to Groups in Kubernetes<\/a><\/li><li><a href=\"#create-and-assign-cluster-roles-to-users-and-groups\">Create and Assign ClusterRoles to Users and Groups<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"assign-roles-to-users-and-groups-in-kubernetes-cluster\">Assign Roles to Users and Groups in Kubernetes Cluster<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"introduction-to-role-based-access-control-in-kubernetes\">Introduction to Role-Based Access Control in Kubernetes<\/h3>\n\n\n\n<p>Kubernetes manages user access to its resources through Role-Based Access Control. Check the link below to read more on Kubernetes RBAC.<\/p>\n\n\n\n<p><a href=\"https:\/\/kifarunix.com\/introduction-to-role-based-access-control-rbac-in-kubernetes\/\" target=\"_blank\" rel=\"noreferrer noopener\">Introduction to Role-Based Access Control (RBAC) in Kubernetes<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"creating-user-accounts-in-kubernetes\">Creating User Accounts in Kubernetes<\/h3>\n\n\n\n<p>While Kubernetes does not natively support management of normal user accounts, it does support the management of service accounts.<\/p>\n\n\n\n<p>Read more about user management in Kubernetes by following the guide below.<\/p>\n\n\n\n<p><a href=\"https:\/\/kifarunix.com\/kubernetes-user-management-creating-users-groups-and-service-accounts\/\" target=\"_blank\" rel=\"noreferrer noopener\">Kubernetes User Management: Creating Users, Groups and Service Accounts<\/a><\/p>\n\n\n\n<p>As already stated that Kubernetes does not have objects which represent normal user accounts, we have created two users, <strong>alice<\/strong> and <strong>bob<\/strong>, on the cluster that depicts the native <a href=\"https:\/\/kifarunix.com\/kubernetes-user-management-creating-users-groups-and-service-accounts\/#create-x-509-client-certificates-for-normal-user-accounts\" target=\"_blank\" rel=\"noreferrer noopener\">user accounts using X509 certificate authentication strategy<\/a>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl config get-users<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>NAME\nalice\nbob\nkubernetes-admin\n<\/code><\/pre>\n\n\n\n<p>We have also <a href=\"https:\/\/kifarunix.com\/kubernetes-user-management-creating-users-groups-and-service-accounts\/#creating-service-accounts-in-kubernetes-cluster\" target=\"_blank\" rel=\"noreferrer noopener\">created a service account<\/a> called monitoring;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl get serviceaccounts<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>NAME         SECRETS   AGE\ndefault      0         5d21h\nmonitoring   0         21h\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"kubernetes-rbac-api-objects\">Kubernetes RBAC API Objects<\/h3>\n\n\n\n<p>There are four RBAC API objects in Kubernetes that are used to enforce access restriction in the cluster. These objects include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Role<\/strong>: The Role API object defines the rules representing a given set of permissions <strong>within a particular namespace<\/strong>. When creating, you need to specify the namespace on which the role apply to, otherwise, default namespace is selected. <\/li>\n\n\n\n<li><strong>ClusterRole<\/strong>: The ClusterRole on the other hand defines rules that represent a given set of permissions that applies <strong>cluster-wide<\/strong> rather than a specific namespace. <\/li>\n\n\n\n<li><strong>RoleBinding<\/strong>: The RoleBinding object binds (grants permissions defined in a role) the Role to a specific subject (user, group or a service account) within a specific namespace.<\/li>\n\n\n\n<li><strong>ClusterRoleBinding<\/strong>: The ClusterRoleBinding similarly grants permissions defined in the ClusterRole object to a subject in a cluster-wide manner.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"creating-kubernetes-roles\">Creating Kubernetes Roles<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"switch-to-cluster-admin-context\">Switch to Cluster Admin Context<\/h4>\n\n\n\n<p>To be able to create roles, you need to use the cluster admin context, or at least a user that has rights to create roles. To list the contexts;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl config get-contexts<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE\n          alice                         kubernetes   alice              default\n          bob                           kubernetes   bob                default\n*         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin   default\n<\/code><\/pre>\n\n\n\n<p>The * specifies your current context. In the above example, we are using the Cluster administrator context.<\/p>\n\n\n\n<p>You can switch to another context using the command;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl config use-context &lt;context-name&gt;<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"create-user-role\">Create User Role<\/h4>\n\n\n\n<p>In Kubernetes, you can create user roles imperatively via the <strong>kubectl create role<\/strong> command, or declaratively via the manifests file using <strong>kubectl apply<\/strong> command.<\/p>\n\n\n\n<p>To create a role, you need to specify;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>the <strong>name<\/strong> of the role itself<\/li>\n\n\n\n<li>the <strong>verb<\/strong>: the API request permissions like&nbsp;<strong>get<\/strong>,&nbsp;<strong>list<\/strong>,&nbsp;<strong>create<\/strong>,&nbsp;<strong>update<\/strong>,&nbsp;<strong>patch<\/strong>,&nbsp;<strong>watch<\/strong>,&nbsp;<strong>delete<\/strong>, and&nbsp;<strong>deletecollection<\/strong>.<\/li>\n\n\n\n<li>the <strong>resource<\/strong> object such <strong>Pod, Deployments, Services<\/strong>, <strong>ReplicaSets, PersistentVolume&#8230;<\/strong><\/li>\n<\/ul>\n\n\n\n<p>To imparatively create a role, that allows users to list pods and services;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create role &lt;name of the role&gt; --verb=&lt;list of permissions comma seperated&gt; --resource=&lt;list of resources comma seperated&gt;<\/code><\/pre>\n\n\n\n<p>For example to create a role called <strong>ReadOnly<\/strong> that allows users to <strong>list<\/strong> or <strong>get<\/strong> Pods and Services resource;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create role ReadOnly --verb=list,get --resource=pods,services<\/code><\/pre>\n\n\n\n<p>In essence:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>list<\/strong> permission allows you to get a quick inventory of all resources of a specific kind (e.g <strong>kubectl get pods<\/strong>).<\/li>\n\n\n\n<li><strong>get<\/strong> permission allows you to get details of a particular named resource (<strong>kubectl get pod &lt;name of the pod&gt;<\/strong>.<\/li>\n<\/ul>\n\n\n\n<p>For more options, check;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create role --help<\/code><\/pre>\n\n\n\n<p>You can also create a role using a manifest yaml file. For example, create a YAML file to define the role, verbs and resources.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vim readonly.yml<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>apiVersion: rbac.authorization.k8s.io\/v1\nkind: Role\nmetadata:\n  name: ReadOnly\n  namespace: default\nrules:\n- apiGroups:\n  - \"\"\n  resources:\n  - pods\n  - services\n  verbs:\n  - list\n  - get\n<\/code><\/pre>\n\n\n\n<p>Pods and Services are core Kubernetes resources do not have API groups associated with them, hence &#8221; &#8220;.<\/p>\n\n\n\n<p>To create the role using manifest yaml file, use <strong>kubectl apply -f &lt;manifest-file&gt;<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -f readonly.yaml --server-side<\/code><\/pre>\n\n\n\n<p>Read more on <strong>kubectl apply &#8211;help<\/strong>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"listing-roles\">Listing Roles<\/h4>\n\n\n\n<p>You can list namespaced roles using <strong>kubectl<\/strong> command as follows;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl get roles<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>NAME       CREATED AT\nReadOnly   2024-05-19T19:55:52Z\n<\/code><\/pre>\n\n\n\n<p>If you want to see more details;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl describe roles ReadOnly<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>Name:         ReadOnly\nLabels:       <none>\nAnnotations:  <none>\nPolicyRule:\n  Resources  Non-Resource URLs  Resource Names  Verbs\n  ---------  -----------------  --------------  -----\n  pods       []                 []              [list get]\n  services   []                 []              [list get]\n<\/code><\/pre>\n\n\n\n<p>You can also get the details in YAML format;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl get roles ReadOnly -o yaml<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>apiVersion: rbac.authorization.k8s.io\/v1\nkind: Role\nmetadata:\n  annotations:\n    kubectl.kubernetes.io\/last-applied-configuration: |\n      {\"apiVersion\":\"rbac.authorization.k8s.io\/v1\",\"kind\":\"Role\",\"metadata\":{\"name\":\"ReadOnly\",\"namespace\":\"default\"},\"rules\":[{\"apiGroups\":[\"\"],\"resources\":[\"pods\",\"services\"],\"verbs\":[\"list\",\"get\"]}]}\n  creationTimestamp: \"2024-05-19T19:55:52Z\"\n  name: ReadOnly\n  namespace: default\n  resourceVersion: \"1095342\"\n  uid: 6f391085-b7e8-4823-be99-cbfb62a932e4\nrules:\n- apiGroups:\n  - \"\"\n  resources:\n  - pods\n  - services\n  verbs:\n  - list\n  - get\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"assigning-roles-to-users-service-accounts\">Assigning Roles to Users\/Service Accounts<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"create-kubernetes-role-bindings\">Create Kubernetes RoleBindings<\/h4>\n\n\n\n<p>Now that you have roles with respective permissions in place, how can you assign them to users? To assign users to specific roles, use the command <strong>kubectl create rolebinding<\/strong>;<\/p>\n\n\n\n<p>To create a rolebinding, you need:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>name of the rolebinding<\/li>\n\n\n\n<li>role to assign<\/li>\n\n\n\n<li>Subject to assign the role (<strong>user (&#8211;user), group (&#8211;group) or serviceaccount (&#8211;serviceaccount)<\/strong>)<\/li>\n<\/ul>\n\n\n\n<p>In essence, here is the command line syntax of creating a rolebinding<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create rolebinding NAME --clusterrole=NAME|--role=NAME &#91;--user=username] &#91;--group=groupname]\n&#91;--serviceaccount=namespace:serviceaccountname] &#91;--dry-run=server|client|none] &#91;options]<\/code><\/pre>\n\n\n\n<p>For example, we want to assign a user names <strong>alice<\/strong> to the <strong>ReadOnly<\/strong> role created above;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create rolebinding ReadOnlyBind --role=ReadOnly --user=alice<\/code><\/pre>\n\n\n\n<p>You can also define your rolebinding in a manifest YAML file and install using <strong>kubectl apply<\/strong> command;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vim readonly-bind.yaml<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>apiVersion: rbac.authorization.k8s.io\/v1\nkind: RoleBinding\nmetadata:\n  name: ReadOnlyBind\n  namespace: default\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: Role\n  name: ReadOnly\nsubjects:\n- apiGroup: rbac.authorization.k8s.io\n  kind: User\n  name: bob\n<\/code><\/pre>\n\n\n\n<p>You can then apply the manifest;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -f readonly-bind.yaml<\/code><\/pre>\n\n\n\n<p>To assign a role to a group, for example;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create rolebinding &lt;bind name&gt; --role=&lt;role&gt; --group=devs<\/code><\/pre>\n\n\n\n<p>To assign a role to a service account;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create rolebinding &lt;bind name&gt; --role=&lt;role&gt; --serviceaccount=&lt;service account name&gt;<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"listing-role-bindings\">Listing RoleBindings<\/h4>\n\n\n\n<p>You can get a list of rolebindings using the command;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl get rolebindings<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>NAME           ROLE            AGE\nReadOnlyBind   Role\/ReadOnly   5m39s\n<\/code><\/pre>\n\n\n\n<p>To get more details;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl describe rolebindings ReadOnlyBind<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>Name:         ReadOnlyBind\nLabels:       <none>\nAnnotations:  <none>\nRole:\n  Kind:  Role\n  Name:  ReadOnly\nSubjects:\n  Kind  Name   Namespace\n  ----  ----   ---------\n  User  alice  \n\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"verify-role-assignment-and-access-permissions\">Verify Role Assignment and Access Permissions<\/h4>\n\n\n\n<p>As you can see in the command output above, user <strong>alice<\/strong> is given ReadOnly permissions (<strong>get<\/strong> and <strong>list<\/strong>) on all Pods\/Services resources.<\/p>\n\n\n\n<p>To verify that the user can access what is given via RBAC, this is how we will do the test!<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Either create a native Linux user account on the cluster, create Kubeconfig for the user and verify access to the cluster resources as per assigned roles. This is not scalable in production environment.<\/li>\n\n\n\n<li>As a cluster admin, switch to user&#8217;s context and check access.<\/li>\n\n\n\n<li>Create human user account as a service account and assign the roles as shown above, generate the service account token and use it remotely for API access to Kubernetes cluster from another system.<\/li>\n<\/ol>\n\n\n\n<p>To use the first method of creating user&#8217;s native Linux account and check access to cluster resources;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo useradd -m -s \/bin\/bash alice<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo passwd alice<\/code><\/pre>\n\n\n\n<p>Next, copy the <a href=\"https:\/\/kifarunix.com\/kubernetes-user-management-creating-users-groups-and-service-accounts\/#add-users-credentials-to-kubeconfig\" target=\"_blank\" rel=\"noreferrer noopener\">user&#8217;s credentials that were added to the Kubeconfig file<\/a>. See, we had already created alice credentials based on her X-509 certificate authentication method.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl config view<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>apiVersion: v1\nclusters:\n- cluster:\n    certificate-authority-data: DATA+OMITTED\n    server: https:\/\/192.168.122.60:6443\n  name: kubernetes\ncontexts:\n- context:\n    cluster: kubernetes\n    namespace: default\n    user: alice\n  name: alice\n- context:\n    cluster: kubernetes\n    namespace: default\n    user: bob\n  name: bob\n- context:\n    cluster: kubernetes\n    namespace: default\n    user: kubernetes-admin\n  name: kubernetes-admin@kubernetes\ncurrent-context: kubernetes-admin@kubernetes\nkind: Config\npreferences: {}\nusers:\n- name: alice\n  user:\n    client-certificate: users\/alice\/alice.crt\n    client-key: users\/alice\/alice.key\n- name: bob\n  user:\n    client-certificate: users\/bob\/bob.crt\n    client-key: users\/bob\/bob.key\n- name: kubernetes-admin\n  user:\n    client-certificate-data: DATA+OMITTED\n    client-key-data: DATA+OMITTED\n<\/code><\/pre>\n\n\n\n<p>So, create user&#8217;s kubeconfig directory and copy its credentials.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo mkdir \/home\/alice\/.kube\/<\/code><\/pre>\n\n\n\n<p>Generate a portable Kubeconfig file for the user.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl config view --flatten | sudo tee  \/home\/alice\/.kube\/config<\/code><\/pre>\n\n\n\n<p>Then edit it such that it only has credentials for the specific user, in this case, alice. See my updated kubeconfig file for the user <strong>alice<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo cat \/home\/alice\/.kube\/config<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>apiVersion: v1\nclusters:\n- cluster:\n    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURCVENDQWUyZ0F3SUJBZ0lJYU14STJpaWEzMDh3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TkRBMU1UTXlNRE0xTlRoYUZ3MHpOREExTVRFeU1EUXdOVGhhTUJVeApFekFSQmdOVkJBTVRDbXQxWW1WeWJtVjBaWE13Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLCkFvSUJBUURCK1JJUm9odVJTb0hBS2U4RXZ1TnpqODJvUEV6YzhxWGFzdlprV3FRZU9PS05zYWpWLy9CNTMxTEkKMFd0blNmaE5MRXhCU2dYdmRxYXI2NGJUWWgzbzV1MExNaVBXTzFWZ25SM0xGcVpuWkNpMUdRUnJwZndSaU45cwpUczdwQWNnMFBISy9zdWF1RUprbnJZeGUwcjZtMHlLSFdBZ2tSN1lHUmIzYmI3YWNTNlRiYWF5RTFlS0NUblhECkpzTlZGU2lzckd5LzJCaVE2NHNDSGRtL21SYm94dnpCZ1EvckszckdQSEdxVWNQd0YwVG9qaVB6UVJkZ242N0gKbXJ3NHRESFo3QzQveU5PZTNWY0hvd0dJZTEybHN2TU5PVkJwZFlhTVNTcUZjL24yNWQ3R2dYcWdGbDdjc3JsdQpkbnBZeENHdUg3c29YZHZMRDZHS2VPNlBlS2piQWdNQkFBR2pXVEJYTUE0R0ExVWREd0VCL3dRRUF3SUNwREFQCkJnTlZIUk1CQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJSODd2ZHhLV0Q4RWhMK3ozei9CUmdENWVJbEN6QVYKQmdOVkhSRUVEakFNZ2dwcmRXSmxjbTVsZEdWek1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQ2JZN0hwUVRNdwpFTVNnOWdWbjErTmJVRzUxWmlwUmNuQ2JDRXN3OFhBUFZVV2REallQekI4QitCdE9NU2NBY2l5QU5pZllMU01iClNOb2ZBeG95NnJUT0FtTDBHM2w2VUtvUEZUTExSSWxIR1hqdi9rQllHbTA1MWk0ZUVJdHBmblhuU3BCM0NSVnQKcWN5UFhqQmJVNFhIS2pVTzBibXNsMkVoZ1BPQm1oZ2k0VXRWYXk0eU9jcWN4ZS9MTFJjaE9DcS9DaEhYcmU5dQo1WEthRGVpUTZtZ081SDNYbFBqeGhtaThQcWUyTzJWdWQ3ZmMxeTg2d2lrRWhWU2ZNRTE4dk1ZV0VvLzhhckxmCmFuSGwveUJDY2c1dkg0RTdXYVJRajNPTTJkUTZjY0JiVlphd2w5MGVmTllZNFJ1OUFnbWNDd09qWVVFQWViK04KZlRzTnJDdytFV1lFCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K\n    server: https:\/\/192.168.122.60:6443\n  name: kubernetes\ncontexts:\n- context:\n    cluster: kubernetes\n    namespace: default\n    user: alice\n  name: alice\ncurrent-context: alice\nkind: Config\npreferences: {}\nusers:\n- name: alice\n  user:\n    client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNyRENDQVpRQ0ZIa2FOdkZCczEvUzJTSDhsMWJWUk9OSW05eEJNQTBHQ1NxR1NJYjNEUUVCQ3dVQU1CVXgKRXpBUkJnTlZCQU1UQ210MVltVnlibVYwWlhNd0hoY05NalF3TlRFNE1UY3pNVFUyV2hjTk1qVXdOVEU0TVRjegpNVFUyV2pBUU1RNHdEQVlEVlFRRERBVmhiR2xqWlRDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDCkFRb0NnZ0VCQUxMMGFqRk0yRWVuRGhEY3NhQlA4eDBaRDBpV2VqSG1WUk1veEQzejZqa0VKMDZCVnlUZTZlNmIKYmZPVEtRS0daUnh0Q1BsZXFSR3Y5a2tPUXhpYXpZSnpKeGlMaUh5bndvNVZpcFg1STBkNmUzNC92d2NhLzJ3cAorNmM1TDlpZThLWFhNZWcycW5ZT3NLWnZJcmFIbk16SWIvTVFwWmlHM0x6TTdJQUpJeHAzZGllSE1HMU02VWxCClc0YWxNd3FkZTZNY2xuWHdsUm52RFZEdjBta1pZQ3lCQTVTNVVZZkhOL1Nybk0rcVhmYk5qVlQxRG9FNzBEemwKRUowb2dtV1NTcENqR2krQWhqMktWenBacGo2NlhzUkg4dFE5eTdOTG91aGs3TGF4UFduQ2FvbDZaRFhPOUtVawp1eUF1SHRlWHROckhvQVVlNlZzWTJ2eFBPSitBamlrQ0F3RUFBVEFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBCnFBTlBDMkU4eWlBY2toZ2pzZTJlbzJVMXlJRGoxem1Yak9uZnpkdVVjUzVaeXNtU3llUGtqb2JMK2VsVmEzZmUKVktWSnh1Nkp0NWQ5eWtXLzRpWWxKWWpESFAxK3RZN1ZtMmU3Yi9vRkZSQXVVOFIwellHRVVzV2pveTI1a3BQMwpWMzIyYVhQL3hPNTlOTDRVN1ZMRnkyeTZPRWUvbXlUbjhHdHZUVnNOaTZ2WlBMcmEvcXA4S1B6cmZRdWJFYjRjCnpEWmNaOTV3aE95a1FtVEh5aGltaUROVWdnMDMwY2pFNzI1QytRaFhaRXRCd3RhQ2RGYmpzZmJHc1p1WldBREUKbUUzRVZtUE1PTzNjT3cwUEpoUTZuK2lhcml3ak9Ia1NGZThZZi9ldW5YMHhyeHBWUS9xL0ZkWTJQYStlTkEvUQo4U2Z2NUZlSVRwbUpUakc3akc5Vlh3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=\n    client-key-data: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ3k5R294VE5oSHB3NFEKM0xHZ1QvTWRHUTlJbG5veDVsVVRLTVE5OCtvNUJDZE9nVmNrM3VudW0yM3preWtDaG1VY2JRajVYcWtSci9aSgpEa01ZbXMyQ2N5Y1lpNGg4cDhLT1ZZcVYrU05IZW50K1A3OEhHdjlzS2Z1bk9TL1ludkNsMXpIb05xcDJEckNtCmJ5SzJoNXpNeUcvekVLV1lodHk4ek95QUNTTWFkM1luaHpCdFRPbEpRVnVHcFRNS25YdWpISloxOEpVWjd3MVEKNzlKcEdXQXNnUU9VdVZHSHh6ZjBxNXpQcWwzMnpZMVU5UTZCTzlBODVSQ2RLSUpsa2txUW94b3ZnSVk5aWxjNgpXYVkrdWw3RVIvTFVQY3V6UzZMb1pPeTJzVDFwd21xSmVtUTF6dlNsSkxzZ0xoN1hsN1RheDZBRkh1bGJHTnI4ClR6aWZnSTRwQWdNQkFBRUNnZ0VBQWNYS2lQcis4UndEZzBpUGpzaGR5TWpqZWdLOGZPWnkrNE93RUFGRWZnWDYKQmdxQ1YveTV2WkkySFNZMDZMcmswS1luWTBLU0VXcVZnYzlaZUhPakVwWFBwbzdLbHBuNUdDaVZSaE0wSDZpSQpnZExza1hYZzZsZTl1QWxGK3RQZ04zTnBlWVBkT09qelhyZTAzOVY1bVVHeC9Ta1lrVG5tWEd4bmRNNEZHN1hZCjFkNStsaGxYcitCcUxNN2drVjZiSFVUL0hQcURTN3RlZUg3UDh0OTVrUVA0cHlXOVdTNk0zejhvZEJDUXlrYTkKNDhlYWxoVU9LaDRmTWFmZ2lQb056VGlJZS9RQmhRVHQvQ0hQdGh3S2Y0KzVWN2ZycHVzUFNGdC9zTEVCdWpFUgp1WDM3alBkVjhKSk1VeHJMallOcHBVV3BRUld4bmxSVTZDQTJqOVFKYlFLQmdRRHlsV1ZRVnJUcUNmclNxbW9jCnJ1aUVjS09LY3FRV0hyQVc0dDFxZlV0Yms3bzIrTC8vMEF1MytONVNYVlprL3B0bjdsblVPV2RjbXJUODhyMWcKcDJqUUlubENDZ3VEN2dBakRYckZrYWtmZEhSSDA5NzBsOEhMRWhYWUFoR1RBVWEyMFo0S01CZERBTjZpcVhMMApwTnlob0RSQ2Jzdm01ZXFIWTZBY2ZDUWNJd0tCZ1FDODJpSmZMQ3ovczVvamc4NzNZNWZMdUxBZ201TWxML3YzCnBOcUptVU9OV3VrdW1QclROUy9FT3N1MUxxWjRvY0pKMERMWERRNDJBMXJuZGw3R2dNaDgreVFGMjFRNkVxMlUKdGNkYmVVSG9LT2JGRG9ySVNZM3BBMEsvUlZ0SE5vOWN3enRvR3BoaXpCbHduZFpMd1FDK25QbHJGWUZkNmp0cQpldEx3UlN5YlF3S0JnRFluRDVUZHBrbFFyUU4yTTNYdnZjeEM4TjhwTkdRVHVhK0NPWGRhUFFaV2RnMXJma0QzCkNvYXBNY2dsT2ZJVnZFOTVMK2htWUNLV0RxMGc2eEcyalhsWkdNU2JSWExRSUl1eXFLT09Icmo4NERCZ3BiYm8KWWNTWlp2THZrMGpEMGl0aG8rd1dURHNTNktCYlAyUkpvVThiV2s4eU9LWjAwT1FrWTB1NGtyOE5Bb0dBQmtncgpSSWN2cUFITmFza0RwVzhHcVp3bkg2Nk5JbnVLSWg2MXRrWUczVGpjOE5QZDVCQ3MyaFlxbUloSXVWS0lKL1JvCi9JWk9wclZOM00wdk1lTXV5Qm1DaFQ5YWVlUU5LaGt4M0hVWUlDVGNLRW5uaStvR2NtM05WcGQwQmRabXhtc28KR3JwbnYwR1N4eEE1QktRUzVrUktkNmxyZURoR2FiQlVPL0hSSGdrQ2dZRUF4T0RzMEdQNWFUL29kalJWQlZjcgo1QUhBRHQ5a0NNUHhIekJHRm5WM3JBMU9PZnJEeUtkNVNXQ1hBNGpkTmdwWm11QjNmRDYybjFzd2hZYWU1elJ1ClYzdDNVeFZ6cWxrZlF2MDlCZU1kVkxJcThQVGt5WnRhT0J0UVRFdzd4dW16S2ROMUFnS2xQQndWTmRHUmdsTkkKdFdwcUtrMFBna0tVZ2hBQmtYZ2ZzQXc9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K\n<\/code><\/pre>\n\n\n\n<p>Update ownership of user&#8217;s files\/directories;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo chown -R alice: \/home\/alice\/.kube\/<\/code><\/pre>\n\n\n\n<p>Switch to the user and check access to resources as defined in the roles;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo -u alice -i<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>alice@master:~$ pwd\n\/home\/alice<\/code><\/pre>\n\n\n\n<p>Confirm your credentials are in place;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>alice@master:~$ <strong>kubectl config view<\/strong><\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>apiVersion: v1\nclusters:\n- cluster:\n    certificate-authority-data: DATA+OMITTED\n    server: https:\/\/192.168.122.60:6443\n  name: kubernetes\ncontexts:\n- context:\n    cluster: kubernetes\n    namespace: default\n    user: alice\n  name: alice\ncurrent-context: alice\nkind: Config\npreferences: {}\nusers:\n- name: alice\n  user:\n    client-certificate-data: DATA+OMITTED\n    client-key-data: DATA+OMITTED\n<\/code><\/pre>\n\n\n\n<p>To check if you can access the resources defined in the role, use the <strong>kubectl auth can-i<\/strong> command;<\/p>\n\n\n\n<pre class=\"scroll-box\"><code>alice@master:~$ kubectl auth can-i get pods\nyes\nalice@master:~$ kubectl auth can-i list pods\nyes\nalice@master:~$ kubectl auth can-i list services\nyes\nalice@master:~$ kubectl auth can-i get services\nyes\n<\/code><\/pre>\n\n\n\n<p>As you can, <strong>yes<\/strong> confirms access to a resource. if <strong>no<\/strong>, then no access. See;<\/p>\n\n\n\n<pre class=\"scroll-box\"><code>alice@master:~$ kubectl auth can-i '*' '*'\nno\n<\/code><\/pre>\n\n\n\n<p>Read more on <strong>kubectl auth can-i &#8211;help<\/strong>.<\/p>\n\n\n\n<pre class=\"scroll-box\"><code>alice@master:~$ kubectl get pods --all-namespaces \nError from server (Forbidden): pods is forbidden: User \"alice\" cannot list resource \"pods\" in API group \"\" at the cluster scope\n<\/code><\/pre>\n\n\n\n<p>As you can see, if you have multiple users, managing this will be cumbersome!<\/p>\n\n\n\n<p>You can also switch to the user&#8217;s context as Kubernetes cluster administrator and verify access;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl config use-context &lt;context-name&gt;<\/code><\/pre>\n\n\n\n<p>E.g<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl config use-context alice<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl config get-contexts<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE\n*         alice                         kubernetes   alice              default\n          bob                           kubernetes   bob                default\n          kubernetes-admin@kubernetes   kubernetes   kubernetes-admin   default\n<\/code><\/pre>\n\n\n\n<p>Switch to user&#8217;s context;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl config use-context alice<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl config current-context<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>$ kubectl auth can-i '*' '*'\nno<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>$ kubectl auth can-i get '*'\nno<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>$ kubectl auth can-i list '*'\nno<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>$ kubectl auth can-i get 'pods'\nyes\n$ kubectl auth can-i get 'services'\nyes\n$ kubectl auth can-i list 'pods'\nyes\n$ kubectl auth can-i list 'services'\nyes<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"kubernetes-service-accounts-and-api-access-via-secrets-and-tokens\">Kubernetes Service Accounts and API Access (via Secrets and Tokens)<\/h4>\n\n\n\n<p>Similarly, if you want to access the cluster using API calls from another system, you can actually create the human user account as a service account as shown above. See our example;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl get serviceaccounts<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>NAME         SECRETS   AGE\nalice-svc    0         5h\n<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl describe roles alice-svc<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>Name:         alice-svc\nLabels:       <none>\nAnnotations:  <none>\nPolicyRule:\n  Resources  Non-Resource URLs  Resource Names  Verbs\n  ---------  -----------------  --------------  -----\n  pods       []                 []              [get list]\n  services   []                 []              [get list]\n<\/code><\/pre>\n\n\n\n<p>Next, create a service account secret. A secret is used to store confidential information, such as authentication credentials, tokens, API keys, or TLS certificates, that applications or users need to access securely.<\/p>\n\n\n\n<p>Recent versions of Kubernetes do not automatically generate secrets for a service account when created. You can confirm with the command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl describe sa alice-svc<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>Name:                alice-svc\nNamespace:           default\nLabels:              &lt;none>\nAnnotations:         &lt;none>\nImage pull secrets:  &lt;none>\nMountable secrets:   &lt;none>\nTokens:              &lt;none>\nEvents:              &lt;none>\n<\/code><\/pre>\n\n\n\n<p>Therefore, if you have a service account you need to use for API access, you can generate a secret and token for it. Note that there are two types of tokens based on their lifespan.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Long-lived tokens<\/strong> are associated with service accounts and have a prolonged lifespan, ideal for persistent processes needing continuous access to the Kubernetes API. These tokens persist until manually revoked, requiring careful management to mitigate security risks if compromised.<\/li>\n\n\n\n<li><strong>Time-limited\/short-lived<\/strong> tokens are automatically generated with a restricted lifespan. Typically used for temporary access, they&#8217;re suitable for short-lived tasks or processes. Once expired, these tokens become invalid, necessitating the generation of new tokens for further access.<\/li>\n<\/ul>\n\n\n\n<p>For our case, we will generate long-lived token for demo purposes.<\/p>\n\n\n\n<p>You can generate a secret imperatively using a command line or declarative via the manifest file.<\/p>\n\n\n\n<p>To create the secret using a manifest yaml file, simply run the command like below;<\/p>\n\n\n\n<pre class=\"scroll-box\"><code>kubectl apply -f - &lt;&lt;EOF\napiVersion: v1\nkind: Secret\nmetadata:\n  name: alice-svc-secret\n  annotations:\n    kubernetes.io\/service-account.name: alice-svc\ntype: kubernetes.io\/service-account-token\nEOF\n<\/code><\/pre>\n\n\n\n<p>This will create a Kubernetes secret named <strong>alice-svc-secret<\/strong>, which contains a token associated with the service account named <strong>alice-svc<\/strong>. This secret can be used for authentication purposes, allowing the service account <strong>alice-svc<\/strong> to access the Kubernetes API securely using the token stored in this secret.<\/p>\n\n\n\n<p>To achieve the same using command line, get a token and generate a secret using it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create secret generic &lt;name&gt; --from-literal=token=&lt;your-token&gt;<\/code><\/pre>\n\n\n\n<p>For testing purposes, let&#8217;s use a random base64-encoded string of 32 characters;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create secret generic alice-svc --from-literal=token=$(openssl rand -base64 32)<\/code><\/pre>\n\n\n\n<p>Note that there are different types of Kubernetes secrets:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Opaque<\/strong>: This is the most common type of secret in Kubernetes and is used hold arbitrary data, such as usernames, passwords, tokens, or any other sensitive information. Opaque secrets are stored as base64-encoded strings. When generting using <strong>kubectl<\/strong> command, you need to specify the <strong>generic<\/strong> option.<\/li>\n\n\n\n<li><strong>Service Account Tokens<\/strong>: These are used to store tokens that identifies a service account. They are used mostly to generate long-lived token, which is no longer recommended as from Kubernetes v1.22, which recommends use of short-live tokens. Note that also from K8S v1.22, these tokens are not automatically generated when you create a service account.<\/li>\n\n\n\n<li><strong>Docker config<\/strong>: These are the secrets that used to access Docker container image registry. When using <strong>kubectl<\/strong> command to generate the <strong>Docker config<\/strong> secret, you specify the command option, <strong>docker-registry<\/strong>.<\/li>\n\n\n\n<li><strong>TLS Secrets<\/strong>: These are used to store TLS certificates and private keys.<\/li>\n<\/ul>\n\n\n\n<p>There are other types of secrets such as <strong>basic authentication<\/strong> and <strong>ssh authentication<\/strong> secrets.<\/p>\n\n\n\n<p>Read more on <strong>kubectl create secret &#8211;help<\/strong>.<\/p>\n\n\n\n<p>Once you have created the secret, annotate with the service account name. This basically means to associate with the secret with the service account.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl annotate secret alice-svc-secret kubernetes.io\/service-account.name=alice-svc<\/code><\/pre>\n\n\n\n<p>Check more details about the secret;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl describe secrets alice-svc-secret<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>Name:         alice-svc-secret\nNamespace:    default\nLabels:       kubernetes.io\/legacy-token-last-used=2024-05-24\nAnnotations:  kubernetes.io\/service-account.name: alice-svc\n              kubernetes.io\/service-account.uid: b3ee12b4-175b-460b-8afe-b3bbb884e334\n\nType:  kubernetes.io\/service-account-token\n\nData\n====\ntoken:      eyJhbGciOiJSUzI1NiIsImtpZCI6InoyeTB4MmZuN0ZnM1Y4a043NXhVWGw0djNaX1VmZDBfN0xXWFVjMFh0em8ifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImFsaWNlLXN2Yy1zZWNyZXQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiYWxpY2Utc3ZjIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiYjNlZTEyYjQtMTc1Yi00NjBiLThhZmUtYjNiYmI4ODRlMzM0Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6YWxpY2Utc3ZjIn0.TnG9j6BVza-WdDxYh4g9sU3AbcMjSdv3x5Cbpug-dd5n04G7B7KtiilcUgpdB6pwrjPvN8QbF0uTDRtAK7p06Cn7eb0NBvRDYoh40Viv504F5MC2cb6nMoCZzlh6iOFiiMtccwfW4QgwM9IP1kSAP042CVn53HgXto8h11n8k6rcymEyniHwL-BmR64RmbEYOsiyiZQB-y9MqwXt8zVU6S_3w80a49PNxWrs-AjS9vtnyFTtaIEj4bC91V3W-7w1aerwY0x6mYjkWodz8dGqzKHWV0hPOra1fN7ult6JjZFkSf2r1_QMGky5myS_mQbViYhqxz302hZsfsGv9eqy1w\nca.crt:     1107 bytes\nnamespace:  7 bytes\n<\/code><\/pre>\n\n\n\n<p>You can now verify access to the cluster resources from another system via API.<\/p>\n\n\n\n<p>For this, you need to generate the user&#8217;s token. You can simply copy the value of the token in the command output above. However, you can also run this command to extract it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl get secret alice-svc-secret -o=jsonpath='{.data.token}' | base64 --decode<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>eyJhbGciOiJSUzI1NiIsImtpZCI6InoyeTB4MmZuN0ZnM1Y4a043NXhVWGw0djNaX1VmZDBfN0xXWFVjMFh0em8ifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImFsaWNlLXN2Yy1zZWNyZXQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiYWxpY2Utc3ZjIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiYjNlZTEyYjQtMTc1Yi00NjBiLThhZmUtYjNiYmI4ODRlMzM0Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6YWxpY2Utc3ZjIn0.TnG9j6BVza-WdDxYh4g9sU3AbcMjSdv3x5Cbpug-dd5n04G7B7KtiilcUgpdB6pwrjPvN8QbF0uTDRtAK7p06Cn7eb0NBvRDYoh40Viv504F5MC2cb6nMoCZzlh6iOFiiMtccwfW4QgwM9IP1kSAP042CVn53HgXto8h11n8k6rcymEyniHwL-BmR64RmbEYOsiyiZQB-y9MqwXt8zVU6S_3w80a49PNxWrs-AjS9vtnyFTtaIEj4bC91V3W-7w1aerwY0x6mYjkWodz8dGqzKHWV0hPOra1fN7ult6JjZFkSf2r1_QMGky5myS_mQbViYhqxz302hZsfsGv9eqy1w<\/code><\/pre>\n\n\n\n<p>Once you have the token, you can use it to authenticate your API calls. For example, you can use <code>curl<\/code> to make API calls to the Kubernetes API server.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -H \"Authorization: Bearer $TOKEN\" &lt;RESOURCE URI><\/code><\/pre>\n\n\n\n<p>For example, to check access from another system using the user&#8217;s secret above. Set the TOKEN variable to the token value above.<\/p>\n\n\n\n<pre class=\"scroll-box\"><code>TOKEN=eyJhbGciOiJSUzI1NiIsImtpZCI6InoyeTB4MmZuN0ZnM1Y4a043NXhVWGw0djNaX1VmZDBfN0xXWFVjMFh0em8ifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImFsaWNlLXN2Yy1zZWNyZXQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiYWxpY2Utc3ZjIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiYjNlZTEyYjQtMTc1Yi00NjBiLThhZmUtYjNiYmI4ODRlMzM0Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6YWxpY2Utc3ZjIn0.TnG9j6BVza-WdDxYh4g9sU3AbcMjSdv3x5Cbpug-dd5n04G7B7KtiilcUgpdB6pwrjPvN8QbF0uTDRtAK7p06Cn7eb0NBvRDYoh40Viv504F5MC2cb6nMoCZzlh6iOFiiMtccwfW4QgwM9IP1kSAP042CVn53HgXto8h11n8k6rcymEyniHwL-BmR64RmbEYOsiyiZQB-y9MqwXt8zVU6S_3w80a49PNxWrs-AjS9vtnyFTtaIEj4bC91V3W-7w1aerwY0x6mYjkWodz8dGqzKHWV0hPOra1fN7ult6JjZFkSf2r1_QMGky5myS_mQbViYhqxz302hZsfsGv9eqy1w\n<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -H \"Authorization: Bearer $TOKEN\" https:\/\/192.168.122.60:6443\/api\/v1\/pods -k<\/code><\/pre>\n\n\n\n<p>The command tries to list pods on all namespaces in the Kubernetes cluster. Remeber Alice permissions revolves only around listing Pods and Services in the default namespace.<\/p>\n\n\n\n<p>The command above will be denied! See;<\/p>\n\n\n\n<pre class=\"scroll-box\"><code>{\n  \"kind\": \"Status\",\n  \"apiVersion\": \"v1\",\n  \"metadata\": {},\n  \"status\": \"Failure\",\n  \"message\": \"pods is forbidden: User \\\"system:serviceaccount:default:alice-svc\\\" cannot list resource \\\"pods\\\" in API group \\\"\\\" at the cluster scope\",\n  \"reason\": \"Forbidden\",\n  \"details\": {\n    \"kind\": \"pods\"\n  },\n  \"code\": 403\n<\/code><\/pre>\n\n\n\n<p>List pods in the default namespace;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -H \"Authorization: Bearer $TOKEN\" https:\/\/192.168.122.60:6443\/api\/v1\/namespaces\/default\/pods -k<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>{\n  \"kind\": \"PodList\",\n  \"apiVersion\": \"v1\",\n  \"metadata\": {\n    \"resourceVersion\": \"1910734\"\n  },\n  \"items\": []\n<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -H \"Authorization: Bearer $TOKEN\" https:\/\/192.168.122.60:6443\/api\/v1\/namespaces\/default\/services -k<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>{\n  \"kind\": \"ServiceList\",\n  \"apiVersion\": \"v1\",\n  \"metadata\": {\n    \"resourceVersion\": \"1910774\"\n  },\n  \"items\": [\n    {\n      \"metadata\": {\n        \"name\": \"kubernetes\",\n        \"namespace\": \"default\",\n        \"uid\": \"70ed9dfa-c4ea-46b4-9874-5a8e170efb16\",\n        \"resourceVersion\": \"234\",\n        \"creationTimestamp\": \"2024-05-13T20:41:04Z\",\n        \"labels\": {\n          \"component\": \"apiserver\",\n          \"provider\": \"kubernetes\"\n        },\n        \"managedFields\": [\n          {\n            \"manager\": \"kube-apiserver\",\n            \"operation\": \"Update\",\n            \"apiVersion\": \"v1\",\n            \"time\": \"2024-05-13T20:41:04Z\",\n            \"fieldsType\": \"FieldsV1\",\n            \"fieldsV1\": {\n              \"f:metadata\": {\n                \"f:labels\": {\n                  \".\": {},\n                  \"f:component\": {},\n                  \"f:provider\": {}\n                }\n              },\n              \"f:spec\": {\n                \"f:clusterIP\": {},\n                \"f:internalTrafficPolicy\": {},\n                \"f:ipFamilyPolicy\": {},\n                \"f:ports\": {\n                  \".\": {},\n                  \"k:{\\\"port\\\":443,\\\"protocol\\\":\\\"TCP\\\"}\": {\n                    \".\": {},\n                    \"f:name\": {},\n                    \"f:port\": {},\n                    \"f:protocol\": {},\n                    \"f:targetPort\": {}\n                  }\n                },\n                \"f:sessionAffinity\": {},\n                \"f:type\": {}\n              }\n            }\n          }\n        ]\n      },\n      \"spec\": {\n        \"ports\": [\n          {\n            \"name\": \"https\",\n            \"protocol\": \"TCP\",\n            \"port\": 443,\n            \"targetPort\": 6443\n          }\n        ],\n        \"clusterIP\": \"10.96.0.1\",\n        \"clusterIPs\": [\n          \"10.96.0.1\"\n        ],\n        \"type\": \"ClusterIP\",\n        \"sessionAffinity\": \"None\",\n        \"ipFamilies\": [\n          \"IPv4\"\n        ],\n        \"ipFamilyPolicy\": \"SingleStack\",\n        \"internalTrafficPolicy\": \"Cluster\"\n      },\n      \"status\": {\n        \"loadBalancer\": {}\n      }\n    }\n  ]\n<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -H \"Authorization: Bearer $TOKEN\" https:\/\/192.168.122.60:6443\/api\/v1\/namespaces\/default\/services -sk | jq -r '&#91;\"NAME\", \"TYPE\", \"CLUSTER-IP\", \"EXTERNAL-IP\", \"PORT(S)\", \"AGE\"], (.items&#91;] | &#91;.metadata.name, .spec.type, .spec.clusterIP, \"&lt;none>\", (.spec.ports&#91;0].port | tostring) + \"\/\" + .spec.ports&#91;0].protocol, .metadata.creationTimestamp]) | @tsv'<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>NAME\tTYPE\tCLUSTER-IP\tEXTERNAL-IP\tPORT(S)\tAGE\nkubernetes\tClusterIP\t10.96.0.1\t<none>\t443\/TCP\t2024-05-13T20:41:04Z\n<\/code><\/pre>\n\n\n\n<p>And that is it!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"assigning-roles-to-groups-in-kubernetes\">Assigning Roles to Groups in Kubernetes<\/h3>\n\n\n\n<p>In our previous guide, we discussed <a href=\"https:\/\/kifarunix.com\/kubernetes-user-management-creating-users-groups-and-service-accounts\/#creating-groups-in-kubernetes\" target=\"_blank\" rel=\"noreferrer noopener\">how to create groups in Kubernetes<\/a>.<\/p>\n\n\n\n<p>While there is no native way of creating groups in a Kubernetes cluster itself, we used an example of <a href=\"https:\/\/kifarunix.com\/kubernetes-user-management-creating-users-groups-and-service-accounts\/#create-x-509-client-certificates-for-normal-user-accounts\" target=\"_blank\" rel=\"noreferrer noopener\">creating users with X509 certificate authentication<\/a>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>openssl x509 -in ~\/.kube\/users\/dave\/dave.crt -subject -noout<\/code><\/pre>\n\n\n\n<p>Output;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>subject=CN = dave, O = devops-int<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>openssl x509 -in ~\/.kube\/users\/carol\/carol.crt -subject -noout<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>subject=CN = carol, O = devops-int<\/code><\/pre>\n\n\n\n<p>As you can see, both users belong to <strong>devops-int<\/strong> group.<\/p>\n\n\n\n<p>Create a view-only role on Pods, Services and Deployments for <strong>devops-int<\/strong> group;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create role view-only --verb=get,list,watch --resource=pods,deployments,services<\/code><\/pre>\n\n\n\n<p>Assign the role to the group via role binding in the default namespace.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create rolebinding devops-view-only --group=devops-int --role=view-only<\/code><\/pre>\n\n\n\n<p>Verify that you can list or get pods, services, and deployments in the specified namespace.<\/p>\n\n\n\n<p>Switch to <strong>dave<\/strong> context!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl config use-context dave<\/code><\/pre>\n\n\n\n<p>Verify permissions;<\/p>\n\n\n\n<pre class=\"scroll-box\"><code>kubectl auth can-i '*' '*'\nno\nkubectl auth can-i get '*'\nno\nkubectl auth can-i list '*'\nno\nkubectl auth can-i list pods\nyes\nkubectl auth can-i get pods\nyes\nkubectl auth can-i list services\nyes\nkubectl auth can-i get services\nyes\nkubectl auth can-i list deployments\nyes\nkubectl auth can-i get deployments\nyes\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"create-and-assign-cluster-roles-to-users-and-groups\">Create and Assign ClusterRoles to Users and Groups<\/h3>\n\n\n\n<p>If you want to create roles that applies cluster-wide, you simply have to replace <strong>role<\/strong> option with <strong>clusterrole<\/strong> option in the <strong>kubectl create<\/strong> command as shown above.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create clusterrole &lt;name> --verb=&lt;permissions> --resource=&lt;resources><\/code><\/pre>\n\n\n\n<p>Before you can create your custom cluster role, you can view existing roles;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl get clusterroles<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>NAME                                                                   CREATED AT\nadmin                                                                  2024-05-13T20:41:04Z\napi-clusterrole                                                        2024-05-17T04:45:14Z\ncalico-cni-plugin                                                      2024-05-13T21:05:22Z\ncalico-kube-controllers                                                2024-05-13T21:05:22Z\ncalico-node                                                            2024-05-13T21:05:22Z\ncalico-typha                                                           2024-05-13T21:05:22Z\ncluster-admin                                                          2024-05-13T20:41:04Z\nedit                                                                   2024-05-13T20:41:04Z\nkubeadm:get-nodes                                                      2024-05-13T20:41:05Z\nsystem:aggregate-to-admin                                              2024-05-13T20:41:04Z\nsystem:aggregate-to-edit                                               2024-05-13T20:41:04Z\nsystem:aggregate-to-view                                               2024-05-13T20:41:04Z\nsystem:auth-delegator                                                  2024-05-13T20:41:04Z\nsystem:basic-user                                                      2024-05-13T20:41:04Z\nsystem:certificates.k8s.io:certificatesigningrequests:nodeclient       2024-05-13T20:41:04Z\nsystem:certificates.k8s.io:certificatesigningrequests:selfnodeclient   2024-05-13T20:41:04Z\nsystem:certificates.k8s.io:kube-apiserver-client-approver              2024-05-13T20:41:04Z\nsystem:certificates.k8s.io:kube-apiserver-client-kubelet-approver      2024-05-13T20:41:04Z\nsystem:certificates.k8s.io:kubelet-serving-approver                    2024-05-13T20:41:04Z\nsystem:certificates.k8s.io:legacy-unknown-approver                     2024-05-13T20:41:04Z\nsystem:controller:attachdetach-controller                              2024-05-13T20:41:04Z\nsystem:controller:certificate-controller                               2024-05-13T20:41:04Z\nsystem:controller:clusterrole-aggregation-controller                   2024-05-13T20:41:04Z\nsystem:controller:cronjob-controller                                   2024-05-13T20:41:04Z\nsystem:controller:daemon-set-controller                                2024-05-13T20:41:04Z\nsystem:controller:deployment-controller                                2024-05-13T20:41:04Z\nsystem:controller:disruption-controller                                2024-05-13T20:41:04Z\nsystem:controller:endpoint-controller                                  2024-05-13T20:41:04Z\nsystem:controller:endpointslice-controller                             2024-05-13T20:41:04Z\nsystem:controller:endpointslicemirroring-controller                    2024-05-13T20:41:04Z\nsystem:controller:ephemeral-volume-controller                          2024-05-13T20:41:04Z\nsystem:controller:expand-controller                                    2024-05-13T20:41:04Z\nsystem:controller:generic-garbage-collector                            2024-05-13T20:41:04Z\nsystem:controller:horizontal-pod-autoscaler                            2024-05-13T20:41:04Z\nsystem:controller:job-controller                                       2024-05-13T20:41:04Z\nsystem:controller:legacy-service-account-token-cleaner                 2024-05-13T20:41:04Z\nsystem:controller:namespace-controller                                 2024-05-13T20:41:04Z\nsystem:controller:node-controller                                      2024-05-13T20:41:04Z\nsystem:controller:persistent-volume-binder                             2024-05-13T20:41:04Z\nsystem:controller:pod-garbage-collector                                2024-05-13T20:41:04Z\nsystem:controller:pv-protection-controller                             2024-05-13T20:41:04Z\nsystem:controller:pvc-protection-controller                            2024-05-13T20:41:04Z\nsystem:controller:replicaset-controller                                2024-05-13T20:41:04Z\nsystem:controller:replication-controller                               2024-05-13T20:41:04Z\nsystem:controller:resourcequota-controller                             2024-05-13T20:41:04Z\nsystem:controller:root-ca-cert-publisher                               2024-05-13T20:41:04Z\nsystem:controller:route-controller                                     2024-05-13T20:41:04Z\nsystem:controller:service-account-controller                           2024-05-13T20:41:04Z\nsystem:controller:service-controller                                   2024-05-13T20:41:04Z\nsystem:controller:statefulset-controller                               2024-05-13T20:41:04Z\nsystem:controller:ttl-after-finished-controller                        2024-05-13T20:41:04Z\nsystem:controller:ttl-controller                                       2024-05-13T20:41:04Z\nsystem:controller:validatingadmissionpolicy-status-controller          2024-05-13T20:41:04Z\nsystem:coredns                                                         2024-05-13T20:41:05Z\nsystem:discovery                                                       2024-05-13T20:41:04Z\nsystem:heapster                                                        2024-05-13T20:41:04Z\nsystem:kube-aggregator                                                 2024-05-13T20:41:04Z\nsystem:kube-controller-manager                                         2024-05-13T20:41:04Z\nsystem:kube-dns                                                        2024-05-13T20:41:04Z\nsystem:kube-scheduler                                                  2024-05-13T20:41:04Z\nsystem:kubelet-api-admin                                               2024-05-13T20:41:04Z\nsystem:monitoring                                                      2024-05-13T20:41:04Z\nsystem:node                                                            2024-05-13T20:41:04Z\nsystem:node-bootstrapper                                               2024-05-13T20:41:04Z\nsystem:node-problem-detector                                           2024-05-13T20:41:04Z\nsystem:node-proxier                                                    2024-05-13T20:41:04Z\nsystem:persistent-volume-provisioner                                   2024-05-13T20:41:04Z\nsystem:public-info-viewer                                              2024-05-13T20:41:04Z\nsystem:service-account-issuer-discovery                                2024-05-13T20:41:04Z\nsystem:volume-scheduler                                                2024-05-13T20:41:04Z\ntigera-operator                                                        2024-05-13T20:53:51Z\nview                                                                   2024-05-13T20:41:04Z\n<\/code><\/pre>\n\n\n\n<p>To check permissions associated with <strong>view<\/strong> role;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl describe clusterrole view<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>Name:         view\nLabels:       kubernetes.io\/bootstrapping=rbac-defaults\n              rbac.authorization.k8s.io\/aggregate-to-edit=true\nAnnotations:  rbac.authorization.kubernetes.io\/autoupdate: true\nPolicyRule:\n  Resources                                    Non-Resource URLs  Resource Names  Verbs\n  ---------                                    -----------------  --------------  -----\n  bindings                                     []                 []              [get list watch]\n  configmaps                                   []                 []              [get list watch]\n  endpoints                                    []                 []              [get list watch]\n  events                                       []                 []              [get list watch]\n  limitranges                                  []                 []              [get list watch]\n  namespaces\/status                            []                 []              [get list watch]\n  namespaces                                   []                 []              [get list watch]\n  persistentvolumeclaims\/status                []                 []              [get list watch]\n  persistentvolumeclaims                       []                 []              [get list watch]\n  pods\/log                                     []                 []              [get list watch]\n  pods\/status                                  []                 []              [get list watch]\n  pods                                         []                 []              [get list watch]\n  replicationcontrollers\/scale                 []                 []              [get list watch]\n  replicationcontrollers\/status                []                 []              [get list watch]\n  replicationcontrollers                       []                 []              [get list watch]\n  resourcequotas\/status                        []                 []              [get list watch]\n  resourcequotas                               []                 []              [get list watch]\n  serviceaccounts                              []                 []              [get list watch]\n  services\/status                              []                 []              [get list watch]\n  services                                     []                 []              [get list watch]\n  controllerrevisions.apps                     []                 []              [get list watch]\n  daemonsets.apps\/status                       []                 []              [get list watch]\n  daemonsets.apps                              []                 []              [get list watch]\n  deployments.apps\/scale                       []                 []              [get list watch]\n  deployments.apps\/status                      []                 []              [get list watch]\n  deployments.apps                             []                 []              [get list watch]\n  replicasets.apps\/scale                       []                 []              [get list watch]\n  replicasets.apps\/status                      []                 []              [get list watch]\n  replicasets.apps                             []                 []              [get list watch]\n  statefulsets.apps\/scale                      []                 []              [get list watch]\n  statefulsets.apps\/status                     []                 []              [get list watch]\n  statefulsets.apps                            []                 []              [get list watch]\n  horizontalpodautoscalers.autoscaling\/status  []                 []              [get list watch]\n  horizontalpodautoscalers.autoscaling         []                 []              [get list watch]\n  cronjobs.batch\/status                        []                 []              [get list watch]\n  cronjobs.batch                               []                 []              [get list watch]\n  jobs.batch\/status                            []                 []              [get list watch]\n  jobs.batch                                   []                 []              [get list watch]\n  endpointslices.discovery.k8s.io              []                 []              [get list watch]\n  daemonsets.extensions\/status                 []                 []              [get list watch]\n  daemonsets.extensions                        []                 []              [get list watch]\n  deployments.extensions\/scale                 []                 []              [get list watch]\n  deployments.extensions\/status                []                 []              [get list watch]\n  deployments.extensions                       []                 []              [get list watch]\n  ingresses.extensions\/status                  []                 []              [get list watch]\n  ingresses.extensions                         []                 []              [get list watch]\n  networkpolicies.extensions                   []                 []              [get list watch]\n  replicasets.extensions\/scale                 []                 []              [get list watch]\n  replicasets.extensions\/status                []                 []              [get list watch]\n  replicasets.extensions                       []                 []              [get list watch]\n  replicationcontrollers.extensions\/scale      []                 []              [get list watch]\n  ingresses.networking.k8s.io\/status           []                 []              [get list watch]\n  ingresses.networking.k8s.io                  []                 []              [get list watch]\n  networkpolicies.networking.k8s.io            []                 []              [get list watch]\n  poddisruptionbudgets.policy\/status           []                 []              [get list watch]\n  poddisruptionbudgets.policy                  []                 []              [get list watch]\n<\/code><\/pre>\n\n\n\n<p>If you want to create your custom role, here is an example that allows you to view all resources.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create clusterrole view-only --verb=get,list,watch --resource=*<\/code><\/pre>\n\n\n\n<p>To assign a roles to user\/service account or a group, you use <strong>clusterrolebinding<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create clusterrolebinding bob-view-cluster --clusterrole=view --user=bob<\/code><\/pre>\n\n\n\n<p>For a service account, replace <strong>&#8211;user<\/strong> with <strong>&#8211;serviceaccount<\/strong> and<strong> &#8211;group<\/strong> for group.<\/p>\n\n\n\n<p>To confirm, either switch to user&#8217;s context or try API access with tokens.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl config use-context bob<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>\/sbin\/ipkubectl auth can-i '*' '*'\nno\n\/sbin\/ipkubectl auth can-i list '*'\nno\n\/sbin\/ipkubectl auth can-i list services\nyes\n\/sbin\/ipkubectl auth can-i list deployments\nyes\n\n<\/code><\/pre>\n\n\n\n<p>And that is it on how to create Kubernetes roles, assign them to the users\/groups and verify.<\/p>\n\n\n\n<p>Read more on Kubernetes <a href=\"https:\/\/kubernetes.io\/docs\/reference\/access-authn-authz\/\" target=\"_blank\" rel=\"noreferrer noopener\">API Access Control<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, you will learn how to assign roles to users and groups in Kubernetes cluster. With Kubernetes becoming the de facto standard for<\/p>\n","protected":false},"author":10,"featured_media":22650,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"rank_math_lock_modified_date":false,"footnotes":""},"categories":[1668,1076,121],"tags":[7505,7504,7506,7508,7510,7503,7507,7509],"class_list":["post-22616","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-kubernetes","category-containers","category-howtos","tag-assign-roles-to-groups-in-kubernetes","tag-assign-roles-to-users","tag-assign-roles-to-users-in-kuberntes","tag-clusterole","tag-clusterrolebinding","tag-create-user-roles-in-kubernetes","tag-role","tag-rolebinding","generate-columns","tablet-grid-50","mobile-grid-100","grid-parent","grid-50","resize-featured-image"],"_links":{"self":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts\/22616"}],"collection":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/comments?post=22616"}],"version-history":[{"count":29,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts\/22616\/revisions"}],"predecessor-version":[{"id":22652,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts\/22616\/revisions\/22652"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/media\/22650"}],"wp:attachment":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/media?parent=22616"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/categories?post=22616"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/tags?post=22616"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}