Kubernetes uses three steps — Authentication, Authorization, and Admission — to enforce secure access and permissions. In this article, we’ll start with Authentication.

The first consideration in authentication is Identity.

Introduction to Identity Authentication

Kubernetes assumes that “user” is managed outside of Kubernetes. In a production environment, LDAP (Lightweight Directory Access Protocol), SSO (single sign-on), Kerberos, or SAML (Security Assertion Markup Language) can be used for authentication management. Other authentication policies may also be used in development or test environments.

There is no object in Kubernetes that represents ordinary users, so ordinary users cannot be added to the cluster through the API.

Authentication Policy Overview

Kubernetes authenticates API requests using authentication proxies, bearer Tokens, client certificates, or HTTP basic authorization through authentication plug-ins. When making an HTTP request to the API Server, the plug-in tries to associate the following attributes with the request:

  • Username: identifies the end user
  • UID: A string that identifies the end user and tries to be more consistent than username, while each UID is unique.
  • Groups: A set of strings that associates a user with a common group of users
  • Extra fields: A mapping of strings that holds additional information that the grantor thinks may be useful.

All of these values are opaque to the authentication system and only make sense if the Authorizer interprets them. Kubernetes administrators typically enable multiple authentication methods. The two most basic methods required are the Service Account token for the service account plus at least one other user authentication method.

X509 client certificate

  • Starting with Kubernetes 1.4, client certificates can use the certificate organization field to indicate a user’s group membership.
  • To allow a user to have multiple group memberships, you need to include multiple organization fields in the certificate.
  • Enable client certificate authentication by passing the –client-ca-file= option to the API Server.
  • The referenced file must contain one or more certificate authorities to validate customer certificates submitted to API Server.
  • If the client certificate is presented and authenticated, the common name of the principal is used as the user name of the request.

For example, using the Openssl command line tool to generate a certificate signing request:

openssl req -new -key <pem_file>.pem -out <out-csr-file>.pem -subj "/CN=admin/O=prod/O=dev/O=uat"
Copy the code

This will create a CSR (Certificate Signing Request) for the user name admin, which belongs to three groups: Prod, dev, and UAT.

Static Token file

When given the –token-auth-file= option on the command line, API Server reads bearer tokens from files. Today, tokens exist indefinitely and the list of tokens cannot be changed without restarting the API Server. The Token file is a CSV file with at least three columns: Token, user name, user UID, and optionally group name after it.

token, user, uid,"prod,dev,uat"

Note: If you have more than 1 group, the column must be in double quotes.

Put a bearer token in the request

When using bearer Token authentication from an HTTP client, the API Server expects the value of the authorization request header to be bearer. Bearer Token must bea sequence of characters that can be placed in the value of an HTTP request header using only HTTP encoding and referencing capabilities. For example, if Bearer Token is AD644F3F-BFCH-295B-75BK-H9G8NGF36HB6, then it would appear in the HTTP request header as follows:

Authorization: Bearer ad644f3f-bfch-295b-75bk-h9g8ngf36hb6
Copy the code

Static password file

Enable basic authentication by passing the –basic-auth-file= option to the API Server. Now, the basic authentication credentials continue indefinitely, and the password cannot be changed without restarting the API Server.

The basic Auth file is a CSV file with at least three columns: password, username, and user ID. In Kubernetes 1.6 and later, you can specify an optional fourth column with comma-separated group names. If you have more than one group, you must enclose the value of column 4 in double quotes (“).

password,user,uid,"group1,group2,group3"
Copy the code

When using basic authentication from an HTTP client, the API Server expects the value of Authorizationheader to be:

Basic BASE64ENCODED(USER:PASSWORD)

Service Account Token

The service account is an automatically enabled identity authenticator that uses a signed bearer token to verify requests. The plug-in requires two optional flags:

--service-account-key-file

A file containing a PEM-encoded key used to sign bearer tokens. If not specified, the TLS key of the API Server is used.

--service-account-lookip

If enabled, tokens removed from API Sever will be revoked.

Service accounts are usually automatically created by API Server and associated with pods running in the cluster through ServiceAccount access controllers.

Bearer tokens are mounted into pods in well-known locations and allow in-cluster processes to talk to API servers. Accounts can be explicitly associated with pods using the serviceAccountName field of PodSpec.

Note that serviceAccountName is usually omitted because this is done automatically.

Practice: Use the ServiceAccount Token

To create a ServiceAccount, run the following command:

kubectl create serviceaccount testuser

The key created contains the API Server’s public CA and the signed JSON Web Token (JWT). The following command displays the YAML that reveals the relevant key:

kubectl get serviceaccount testuser -o yaml
Copy the code

The following command displays the available tokens:

kubectl get secrets

To get encoded token data, enter:

kubectl get secret testuser-token-mgtnp -o yaml

Copy the code

You can copy and paste the encoded token data into jwt. IO/to see the payload. Use the editor of your choice to enter the following YAMl file (test-pod.yaml) to run a POD:

apiVersion: v1 kind: pod metadata: name: test-pod spec: serviceAccountName: testuser container: - name: Alpine :3.7 Command: - "sh" - "-c" - "sleep 100"Copy the code

Then use the following command to start pod:

kubectl apply -f test-pod.yaml

Copy the code

Use describe to see more details:

kubectl describe test-pod

Now we have a running POD called test-pod, let’s go into interactive mode and run a shell:

kubectl exec -it test-pod — sh

If you want to run a shell inside a Docker container, the command is similar to the docker command. At this point, we’ll be prompted to enter the Alpine Linux system, which runs inside a container in pod. To open tokens that are copied to the container, you need to run the following command:

cat /var/run/sercrets/kubernetes.io/serviceaccount/token
Copy the code

Copy the output and paste the token in the Encoded section on jwt. IO /. …

This shows you in an almost intuitive way how Kubernetes does authentication payloads in tokens.

The author:

Sudip Sengupta link: dzone.com/articles/ku…