Beginning here with a disclaimer: Much of what you will read here is usually handled by your service provider.

As mentioned in a previous post you will probably not be asked to setup your K8s cluster from scratch. A service provider will provide you with a cluster.

The access permissions will also usually be handled by the service provider using IAM rules. In the end, though, the IAM rules must result in the creation of Roles and RoleBindings attached to the context of an IAM role.

Lets start with a few definitions.

Authentication

Any system which provides Role Based Access Control, must do Authentication as the first step of a 2 step process.

Authentication is the process of identifying a User or in other words, how do I know that you are You ?

Authorization

Now that I know who you are I need to allow you to do only the things that you are allowed to do. This is Authorization.

Account Types

There are 2 account types supported by Kubernetes.

  1. User Account: This type of account is for Humans. Probably used in conjunction with kubectl. Usually made such that all namespaces are available but additional config is required to give access to particular resources.
  2. Service Account: Meant for programmatic access to kube APIs. The authentication method is much simpler, usually Token based. They are usually restricted to namespaces. Every namespace, by default, has a default service account.

While the User Account is usually created by the Kubernetes provider, the service account is created by the Kubernetes system itself.

Alice’s Enlightenment

Going back to our previous post, you may remember that Alice and Bob hated each other. They were constantly bickering about the problems caused by the other’s team. You, as their boss, want this to stop, so you created namespaces, but engineers were still able to look across namespaces.

You have a chat with Alice and she realizes that she could earn valuable brownie points by just restricting her team from accessing Bob’s namespace. Lets see how she went about it.

Step 1 User Authentication

User Accounts are authenticated using certificates. Your Kubectl config (usually in <home dir>/.kube/config stores the details of your certificates and private keys to use for authentication. Public-Key Private Key cryptography is a rabbit-hole you need to go down on your own. (Maybe in another post)

Here is my config file

apiVersion: v1
clusters:
- cluster:
    certificate-authority: /home/param/.minikube/ca.crt
    server: https://192.168.99.100:8443
  name: minikube
contexts:
- context:
    cluster: minikube
    user: employee
  name: employee-context
- context:
    cluster: minikube
    user: minikube
  name: minikube
current-context: employee-context
kind: Config
preferences: {}
users:
- name: employee
  user:
    client-certificate: /home/param/.certs/employee.crt
    client-key: /home/param/.certs/employee.key
- name: minikube
  user:
    client-certificate: /home/param/.minikube/client.crt
    client-key: /home/param/.minikube/client.key

Note a couple of things

certificate-authority: this is the credential of the server which will validate the certificate sent by the kubectl client.
server: is the url of the API server
contexts: This is the kubectl contexts available for users
users: The user credentials to use for a user

In short, we need a client-certificate and client-key authorized (signed) by the certificate-authority for each user. Each user is connected to a context which is what we need to specify to kubectl.

Creating Client-Certificate

Create a private key for the user

$ openssl genrsa -out employee.key 2048                                                                                                                                     
Generating RSA private key, 2048 bit long modulus (2 primes)                                                                                                                                                 
...............+++++                                                                                                                                                                                         
.............................+++++                                                                                                                                                                           
e is 65537 (0x010001)                                                                                                                                                                                        

Create a Certificate Signing Request

Usually you will send your public key and a few other details to a Certificate Authority to receive your signed certificate. The standard format for that is CSR (Certificate Signing Request).

To generate a CSR from a private key we do

sudo openssl req -new -key employee.key -out employee.csr -subj "/CN=employee/O=alice"

Create Signed Certificate

As the Certificate Authority for Minikube is on our laptop and we have access to its credentials in ~/.minikube/ca.crt we can create a self signed certificate using the following command

openssl x509 -req -in employee.csr -CA ~/.minikube/ca.crt -CAkey ~/.minikube/ca.key -CAcreateserial -out employee.crt -days 500

Setting up Kubectl to use this certificate

At the end of this we should have employee.crt and employee.key. Now we can tell kubectl to use these files as credentials. Lets setup the context employee context for user employee using the following command

$ kubectl config set-credentials employee --client-certificate=/home/employee/.certs/employee.crt  --client-key=/home/employee/.certs/employee.key
User "employee" set.

Now create the context for this user.

kubectl config set-context employee-context --cluster=minikube --user=employee

Now you should see the new context available to you using the kubectl command…

$ kubectl config get-contexts
CURRENT   NAME               CLUSTER    AUTHINFO   NAMESPACE
          employee-context   minikube   employee   
*         minikube           minikube   minikube   

Lets switch to the new context

kubectl config use-context employee-context

(Or use kubectx command)

$ kubectl config get-contexts
CURRENT   NAME               CLUSTER    AUTHINFO   NAMESPACE
*         employee-context   minikube   employee   
          minikube           minikube   minikube   

(note the * now points to employee-context).

Authentication success but …

Lets get pod information using this context.

$ kubectl get pods
Error from server (Forbidden): pods is forbidden: User "employee" cannot list resource "pods" in API group "" in the namespace "default"

Oh NO! this user is forbidden from accessing anything! That’s because we have only authenticated the user so far. Kubernetes knows the user now, but doesn’t know what they are allowed to access. So they are not allowed to access anything. Next step Authorization. We will read about that in the next post.

Learnings

Authentication is the system finding out who your are.

Authorization is the system allowing you to do what you are allowed to do.

Authentication ultimately needs creation of credentials for users.

In a Managed Kubernetes cluster the Authentication credentials are created by the service provider and injected into your kubectl config in ~/.kube/config file.

Service providers use IAM permissions to configure Authorization in the Cluster.

There is RabbitHole waiting for you called Public Key/Private Key cryptography.

Authentication is useless without Authorization

Conclusion

This post is about Authentication, in the next post we talk about Authorization. Thankfully Authorization occurs within the ambit of Kubernetes. Its as easy as creating Resources.