Kubernetes Authentication & Authorization (Workflow)

Kubernetes Authentication and authorization play a very vital role in securing applications. These two terms are often used interchangeably but are very different. Authentication validates the identity of a user. Once the identity is validated, authorization is used to check whether the user has the privileges to perform the desired action. Authentication uses something the user knows to verify their identity; in the simplest form, this is a username and password. Once the application verifies the user's identity, it checks what resources the user has access to. In most cases, this is a variation of an access control list. Access control lists for the user are compared with the request attributes to allow or deny an action.

 

Kubernetes Authentication

In the following figure you can see how the API server conceptually performs authentication by using one of the available strategies represented by the authentication plug-ins:

Advertisement
Beginners guide on Kubernetes Authentication & Authorization
Authentication concepts

The flow Kubernetes uses to authenticate a client’s request is as follows:

  • The client presents its credentials to the API server.
  • The API server uses one of the configured authentication plug-ins (you can enable multiple) to establish the identity with an identity provider.
  • The identity provider verifies the request information, including username and group membership.
  • If the credentials are in order, the API server moves on to check permissions as described in Chapter 4. Otherwise, it returns an HTTP 401 Unauthorized client error status response code, and with that the request fails.

 

Authentication Strategies

A couple of authentication strategies are available in Kubernetes, represented by authentication plug-ins. Depending on the size of the deployment, the target users (human versus processes), and organizational policies, you as a cluster admin can choose one or more of the following:

Client certificates

Using X509 Certificate Authority (CA) certificates is the most common authentication strategy in Kubernetes. It can be enabled by passing --client-ca-file=file_path to the server. The file passed to the API server has a list of CAs, which creates and validates client certificates in the cluster.

 

Static tokens

The API server uses a static file to read the bearer tokens. This static file is passed to the API server using --token-auth-file=<path>. The token file is a comma-separated file consisting of secret, user, uid, group1, and group2.

The token is passed as an HTTP header in the request:

Authorization: Bearer 66e6a781-09cb-4e7e-8e13-34d78cb0dab6

The tokens persist indefinitely, and the API server needs to be restarted to update the tokens.

Advertisement

 

Basic authentication

The API server uses a static file to read the bearer tokens. This static file is passed to the API server using --token-auth-file=<path>. The token file is a comma-separated file consisting of secret, user, uid, group1, and group2.

The username and password are passed as an authentication header in the request:

Authentication: Basic base64(user:password)

Similar to static tokens, basic authentication passwords cannot be changed without restarting the API server.

 

Bootstrap tokens

These are an improvisation over the static tokens and are the default authentication method used in Kubernetes. They are dynamically managed and stored as secrets in kube-system. To enable bootstrap tokens use --enable-bootstrap-token-auth in the API server.

 

Service account tokens

The service account authenticator is automatically enabled. It verifies signed bearer tokens. The signing key is specified using --service-account-key-file. Service accounts are created by the kube-apiserver and are associated with the pods.

 

Authentication proxy

kube-apiserver can be configured to identify users using the X-Remote request header. You can enable this method by adding the following arguments to the API server:

  • --requestheader-username-headers=X-Remote-User
  • --requestheader-group-headers=X-Remote-Group
  • --requestheader-extra-headers-prefix=X-Remote-Extra

 

Webhook tokens

In webhook mode, Kubernetes makes a call to a REST API outside the cluster to determine the user's identity. Webhook mode for authentication can be enabled by passing --authorization-webhook-config-file=<path> to the API server.

 

Example - Using client certificates

The kubectl command uses the certificates that are stored in ~/.kube/config or /etc/kubernetes/admin.conf. When using curl for direct API access then these certificates must be used.

Advertisement

For example here we try to access our API server i.e.

[root@controller ~]# kubectl config view | grep server
    server: https://192.168.43.48:6443

using the curl command without using any certificates:

[root@controller ~]# curl https://192.168.43.48:6443
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

As expected it failed because curl couldn't find the certificates required to connect to the API server.

Let's manually use the content of ~/.kube/config or /etc/kubernetes/admin.conf to create the certificates required to access the API server manually:

Here I have exported different certificates into respective variables

[root@controller ~]# export client=$(grep client-cert /etc/kubernetes/admin.conf | cut -d " " -f 6)
[root@controller ~]# export key=$(grep client-key-data /etc/kubernetes/admin.conf | cut -d " " -f 6)
[root@controller ~]# export auth=$(grep certificate-authority-data /etc/kubernetes/admin.conf | cut -d " " -f 6)

Later we will convert these certificates using base64 and create new certificate file:

[root@controller ~]# echo $client | base64 -d - > client.pem
[root@controller ~]# echo $key | base64 -d - > client-key.pem
[root@controller ~]# echo $auth | base64 -d - > ca.pem

Now we can access our Kubernetes API server using curl with these certificates:

[root@controller ~]# curl --cert client.pem --key client-key.pem --cacert ca.pem  https://192.168.43.48:6443
{
  "paths": [
    "/api",
    "/api/v1",
    "/apis",
    "/apis/",
    "/apis/admissionregistration.k8s.io",
    "/apis/admissionregistration.k8s.io/v1",
    "/apis/admissionregistration.k8s.io/v1beta1",
    "/apis/apiextensions.k8s.io",
    "/apis/apiextensions.k8s.io/v1",
    "/apis/apiextensions.k8s.io/v1beta1",
    "/apis/apiregistration.k8s.io",
    "/apis/apiregistration.k8s.io/v1",
    "/apis/apiregistration.k8s.io/v1beta1",
    "/apis/apps",
    "/apis/apps/v1",
....
    "/readyz/poststarthook/start-apiextensions-informers",
    "/readyz/poststarthook/start-cluster-authentication-info-controller",
    "/readyz/poststarthook/start-kube-aggregator-informers",
    "/readyz/poststarthook/start-kube-apiserver-admission-initializer",
    "/readyz/shutdown",
    "/version"
  ]
}

 

Kubernetes Authorization

Authorization in Kubernetes verifies whether a certain action (such as “list pods” or “create a secret”) is allowed by a certain user or application, and if it is allowed, performs that action or otherwise rejects it and potentially logs the attempt.

Advertisement

Kubernetes authorizes API requests by using the API server, evaluating the request attributes against the policies and subsequently allowing or denying the request. By default, permissions are denied, unless explicitly allowed by a policy.

Following diagram explains how Kubernetes Authorization works:

Beginners guide on Kubernetes Authentication & Authorization
Authorization concepts

The authorization flow is as follows:

  • The client’s request is authenticated
  • If the authentication was successful, the credentials are taken as one input of the authorization module.
  • The second input to the authorization module is a vector containing the request path, resource, verb, and namespace (and other secondary attributes).
  • If the user or application is permitted to execute a certain action on a certain resource, the request is passed on further to the next component in the chain, the admission controller. If not, the authorization module returns an HTTP 403 Forbidden client error status response code, and with that the request fails.

 

Authorization Modes

Kubernetes offers multiple ways to enforce permissions, represented by various authorization modes and modules:

 

Node

Node authorization mode grants permissions to kubelets to access services, endpoints, nodes, pods, secrets, and persistent volumes for a node. The kubelet is identified as part of the system:nodes group with a username of system:node:<name> to be authorized by the node authorizer. This mode is enabled by default in Kubernetes.

 

ABAC

With ABAC, requests are allowed by validating policies against the attributes of the request. ABAC authorization mode can be enabled by using --authorization-policy-file=<path> and --authorization-mode=ABAC with the API server. The API server uses the --authorization-mode=Node flag to use the node authorization module:

The policies include a JSON object per line. Each policy consists of the following:

  • Version: The API version for the policy format.
  • Kind: The Policy string is used for policies.
  • Spec: This includes the user, group, and resource properties, such as apiGroup, namespace, and nonResourcePath (such as /version, /apis, readonly) to allow requests that don't modify the resource.

 

RBAC

With RBAC, access to resources is regulated using roles assigned to users. RBAC is enabled by default in many clusters since v1.8. To enable RBAC, start the API server with --authorization-mode=RBAC

 

Webhooks

Similar to webhook mode for authentication, webhook mode for authorization uses a remote API server to check user permissions. Webhook mode can be enabled by using --authorization-webhook-config-file=<path>

 

Conclusion

In this tutorial we learned about the importance of authentication and authorization in Kubernetes. We discussed the different modules available for authentication and authorization. I also shared an example of client certificate based authentication used to access the API server. The API calls generated by kubectl can actually be monitored by specifying a verbosity level such as kubectl get pods -v10 which is giving you a lot of information about the call commands that are happening in the background. Alternatively, the kubectl proxy command can be used to run a proxy that takes care of passing authenticated requests to the kube-apiserver.

Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

Leave a Comment