DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • 7 Microservices Best Practices for Developers
  • Zero-Downtime Deployments for Java Apps on Kubernetes
  • Self-Hosted Inference Doesn’t Have to Be a Nightmare: How to Use GPUStack
  • Your API Authentication Isn’t Broken; It’s Quietly Failing in These 6 Ways

Trending

  • Build a GitHub Slack Bot With AWS Bedrock and MCP, Part 2
  • Optimizing High-Volume REST APIs Using Redis Caching and Spring Boot (With Load Testing Code)
  • Zero-Downtime Deployments for Java Apps on Kubernetes
  • Building a DevOps-Ready Internal Developer Platform: A Hands-On Guide to Golden Paths, Self-Service, and Automated Delivery Pipelines
  1. DZone
  2. Software Design and Architecture
  3. Cloud Architecture
  4. Kubernetes Authentication

Kubernetes Authentication

By 
Sudip Sengupta user avatar
Sudip Sengupta
DZone Core CORE ·
Jul. 10, 20 · Tutorial
Likes (10)
Comment
Save
Tweet
Share
15.5K Views

Join the DZone community and get the full member experience.

Join For Free

There are three steps that Kubernetes uses to enforce security access and permissions — Authentication, Authorization and Admission. In this article we are going to consider Authentication first.

              The Authentication, Authorization and Admission Control Process

The first thing in Authentication is Identity.

Identity

Kubernetes assumes that "users" are managed outside of Kubernetes. In production environments, it can be LDAP (Lightweight Directory Access Protocol), SSO (Single-Sign On), Kerberos or SAML (Security Assertion Markup Language) for identity management.

In development or test environments, other Authentication Strategies may be employed. 

Kubernetes does not have a notion of a human user.

Authentication Strategies

Kubernetes uses authenticating proxy, bearer tokens, client certificates, or HTTP basic authorization to authenticate API requests through authentication plugins. As HTTP requests are made to the API Server, plugins attempt to associate the following attributes with the request:

  • Username: A string which identifies the end-user.
  • UID: A string which identifies the end-user and attempts to be more consistent and unique than a username.
  • Groups: A set of string which associate users with a set of commonly grouped users.
  • Extra fields: A map of strings that holds additional information Authorizers might find useful.

All of these values are opaque to the authentication system and only hold significance when interpreted by an authorizer. Kubernetes administrators typically enable multiple authentication methods. The two minimal methods required are - Service account tokens for service accounts and at least one other method of user authentication.

X509 Client Certificates

  • As of Kubernetes 1.4, client certificates can also indicate a user's group memberships using the certificate's organization fields.
  • To include multiple group memberships for a user, include multiple organization fields in the certificate.
  • Client certificate authentication is enabled by passing the --client-ca-file=<FILE> option to the API server.
  • The referenced file must contain one or more certificate authorities to use to validate client certificates presented to the API server.
  • If a client certificate is presented and verified, the common name of the subject is used as the user name for the request.

For instance, using the openssl command line tool to generate a certificate signing request:

Shell
xxxxxxxxxx
1
 
1
openssl req -new -key <pem_file>.pem -out <out-csr-file>.pem -subj "/CN=admin/O=prod/O=dev/O=uat"


This would create a CSR (Certificate Signing Request) for the username admin, belonging to three groups: prod, dev and uat

Static Token File

The API server reads bearer tokens from a file when given the --token-auth-file=<FILENAME> option on the command line. Today, tokens last indefinitely, and the token list cannot be changed without restarting the API server. The token file is a CSV file with a minimum of 3 columns: token, user name, user uid, followed by optional group names.

Plain Text
xxxxxxxxxx
1
 
1
token, user, uid,"prod,dev,uat"


Note: If you have more than one group, the column must be double quoted.

Putting a Bearer Token in a Request

When using bearer token authentication from an HTTP client, the API server expects an Authorization header with a value of Bearer <Token>. The bearer token must be a character sequence that can be put in an HTTP header value using no more than the encoding and quoting facilities of HTTP. For instance, if the bearer token is ad644f3f-bfch-295b-75bk-h9g8ngf36hb6, then it would appear in an HTTP header as shown below:

Plain Text
xxxxxxxxxx
1
 
1
Authorization: Bearer ad644f3f-bfch-295b-75bk-h9g8ngf36hb6


Static Password File

Basic authentication is enabled by passing the --basic-auth-file=<FILENAME> option to the API server. Now, the basic auth credentials last indefinitely, and the password cannot be changed without restarting the API server.

The basic auth file is a csv file with a minimum of 3 columns: password, user name, user id. In Kubernetes version 1.6 and later, you can specify an optional 4th column containing comma-separated group names. If you have more than one group, you must enclose the 4th column value in double quotes ("):

Plain Text
xxxxxxxxxx
1
 
1
password,user,uid,"group1,group2,group3"


When using basic authentication from an HTTP client, the API server expects an Authorizationheader with a value of:

Plain Text
xxxxxxxxxx
1
 
1
Basic BASE64ENCODED(USER:PASSWORD)


Service Account Tokens

A service account is an automatically enabled authenticator that uses signed bearer tokens to verify requests. The plugin takes 2 optional flags:

Shell
xxxxxxxxxx
1
 
1
--service-account-key-file

A file containing a PEM-encoded key for signing bearer tokens. If unspecified, the API server's TLS private key will be used


Shell
xxxxxxxxxx
1
 
1
--service-account-lookip

If enabled, tokens which are deleted from the API server will be revoked


Service accounts are usually created automatically by the API server and associated with pods running in the cluster through the ServiceAccount Admission Controller.

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

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

Exercise

Working With ServiceAccount Tokens

The following command may be used to create a ServiceAccount:

Shell
xxxxxxxxxx
1
 
1
kubectl create serviceaccount testuser


The created secret holds the public CA of the API server and a signed JSON Web Token (JWT). To display the yaml revealing the associated secret:

Shell
xxxxxxxxxx
1
 
1
kubectl get serviceaccount testuser -o yaml


The command to display available tokens is:

Shell
xxxxxxxxxx
1
 
1
kubectl get secrets


To obtain the encoded token data, you may enter:

Shell
xxxxxxxxxx
1
 
1
kubectl get secret testuser-token-mgtnp -o yaml


You can take the encoded token data and copy-and-paste it at https://jwt.io/ to see the payload. To run a pod, use the editor of your choice to input the following yaml file (test-pod.yaml)

YAML
xxxxxxxxxx
1
12
 
1
apiVersion: v1 
2
kind: pod 
3
metadata:  
4
  name: test-pod 
5
spec:  
6
  serviceAccountName: testuser  
7
  container:  
8
  - name: alpine:3.7    
9
    command:    
10
    - "sh"    
11
    - "-c"    
12
    - "sleep 100"


Then launch the pod with the following command:

Shell
xxxxxxxxxx
1
 
1
kubectl apply -f test-pod.yaml


Use the describe verb to look at it more closely:

Shell
xxxxxxxxxx
1
 
1
kubectl describe test-pod


Now, that we have a running pod named test-pod, let's get in to the interactive mode and run a shell:

Shell
xxxxxxxxxx
1
 
1
kubectl exec -it test-pod -- sh


This is similar to a docker command if you want to run a shell within a docker container. At that point, we are going to have a prompt and we are inside our Alpine Linux system that is running in a container that is within our pod. In order to open the Token that was copied into the container you have to run the following command:

Shell
xxxxxxxxxx
1
 
1
cat /var/run/sercrets/kubernetes.io/serviceaccount/token


Copy the output and paste that token in the Encoded side on https://jwt.io/. On another side you will get the type of token, namespace, ServiceAccount name, Secret name, etc.

This pretty much illustrates to you in a very visual way how Kubernetes is carrying the identification and authentication payload in the token.

Kubernetes authentication

Published at DZone with permission of Sudip Sengupta. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • 7 Microservices Best Practices for Developers
  • Zero-Downtime Deployments for Java Apps on Kubernetes
  • Self-Hosted Inference Doesn’t Have to Be a Nightmare: How to Use GPUStack
  • Your API Authentication Isn’t Broken; It’s Quietly Failing in These 6 Ways

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook