Understanding Kubernetes Authentication and Authorization

Authentication and authorization are two very important requirements when setting up a production Kubernetes cluster. In this article let’s go through some details which will help you to plan your Kubernetes environment.
The basic authentication and authorization flow in a Kubernetes cluster can be understood from the following figure:

kube-auth

 

Let’s say you fired the command to create a POD by passing a yaml file to kubectl (kubectl create -f pod.yaml).
The command is sent to the secured api-server port (https://) and the authentication flow kicks in. Note that authentication doesn’t apply if you are using insecure port (http://) for your api-server. Insecure port (http://) should ideally be avoided in a production setup.

Following are the authentication methods available in Kubernetes as of this writing.

Client Certificate Authentication
In order to use this scheme, the api-server needs to be started with the –client-ca-file=<PATH_TO_CA_CERTIFICATE_FILE> option.
The CA_CERTIFICATE_FILE must contain one or more certificates authorities that can be used to validate client certificates presented to the api-server. The /CN of the client certificate is used as the username.

Token based Authentication
In order to use this scheme, the api-server needs to be started with the –token-auth-file=<PATH_TO_TOKEN_FILE> option. The TOKEN_FILE is a csv file and every user entry have the following format: token, user, userid, group
The group name is optional.
Example token file:

[snip]
XK3f2Bxj5jyP9P2A1VPmKPPsm2XKgH08,pradipta,pradipta
aKPweaKhrOplvc7L0Tzv0P4vCbyPZ8V1,system:dns,system:dns
[snip]

A very simple way to generate tokens is by running the following command:

# echo `dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64 | tr -d "=+/" | dd bs=32 count=1 2>/dev/null`

The challenge with token based authentication is that the tokens last indefinitely, and any change to the token list requires restarting the api-server.

HTTP Basic Authentication
In order to use this scheme, the api-server needs to be started with the –basic-auth-file=<PATH_TO_HTTP_AUTH_FILE> option. The HTTP_AUTH_FILE is a csv file and every user entry have the following format: password, user name, userid
Currently any changes to the AUTH_FILE will require a restart of the api-server.

Open ID
OpenID support is also available but experimental.

Keystone
Keystone support is also available but experimental. If you plan to integrate with LDAP or Active Directory services then Keystone authentication method needs to be used. In order to use this scheme, the api-server needs to be started with the –experimental-keystone-url=<KEYSTONE_URL> option.

After successful authentication the next step is to find out what operations are allowed for the authenticated user. Kubernetes supports 4 types of authorization policy schemes as of today. The api-server needs to be started with the –authorization-mode=<AUTHORIZATION_POLICY_NAME> option.

AlwaysDeny
This policy denies all the requests.

AlwaysAllow
This policy allows all the requests.

Attribute Based Access Control (ABAC)
ABAC allows for flexible user specific authorization policies. An ABAC policy file needs to be specified when starting the api-server using the –authorization-policy-file=<PATH_TO_ABAC_POLICY_FILE> option. Currently any changes to policy file will require a restart of the api-server.
A sample ABAC policy file looks like the following:

[snip]
#user 'pradipta' has complete access to namespace 'pradipta
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"pradipta", "namespace": "pradipta", "resource": "*", "apiGroup": "*", "nonResourcePath": "*" }}
#user 'admin' has complete access to all the namespaces
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"admin", "namespace": "*", "resource": "*", "apiGroup": "*", "nonResourcePath": "*" }}
#All users have readonly access to the entire cluster
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"*", "namespace": "*", "resource": "*", "apiGroup": "*", "nonResourcePath": "*", "readonly":true }}
#All Serviceaccount users have  full access to the entire cluster
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group":"system:serviceaccounts", "namespace": "*", "resource": "*", "apiGroup": "*", "nonResourcePath": "*"}}
[snip]

Each line in the policy file like the above example, is a JSON object and specifies a policy. Here is a brief description of the policy object from the Kubernetes documentation page.

Versioning properties – Allows versioning and conversion of the policy format.

apiVersion, type string : valid values are “abac.authorization.kubernetes.io/v1beta1”.
kind, type string : valid values are “Policy”.

Spec properties – is a map with the following properties:

Subject-matching properties:

user, type string :  The user-string is either from the –token-auth-file or common name (CN) from the certificate file. If you specify user, it must match the username of the authenticated user. * matches all requests.
group, type string : If you specify group, it must match one of the groups of the authenticated user. * matches all requests.

Resource-matching properties:

apiGroup, type string : an API group, such as extensions. * matches all API groups.
namespace, type string : a namespace string. * matches all resource requests.
resource, type string : a resource, such as pods. * matches all resource requests.

Non-resource-matching properties:

nonResourcePath, type string : matches the non-resource request paths (like /version and /apis). * matches all non-resource requests. /foo/* matches /foo/ and all of its subpaths.

readonly, type boolean: when true, means that the policy only applies to get, list, and watch operations.

Webhook
Calls out to an external RESTful authorization service.

The actual choice of authentication and authorization mechanism will depend on your requirements. However in my experience I have found that a combination of certificate based authentication method for the kubelets, keystone (LDAP) based authentication method for users and ABAC based authorization policies, provides the required functionalities with needed flexibility for bringing up a Kubernetes environment.

For more details on authentication and authorization I would advise going through the following two links:
Authentication – http://kubernetes.io/docs/admin/authentication/
Authorization – http://kubernetes.io/docs/admin/authorization

Pradipta Kumar Banerjee

I'm a Cloud and Linux/ OpenSource enthusiast, with 16 years of industry experience at IBM. You can find more details about me here - Linkedin

You may also like...