Kubernetes authentication
Kubernetes authentication mechanisms
- Initial assessments
kube-apiserverusers managementkubeadmauthentication strategieskubeconfigfiles- PKI provisioning with
kubeadm
- For simplicity's sake, this document will focus on built-in authentication strategies provided by
kubeadm init. - For advanced use cases, here is a guide detailing the security aspects of all supported authentication strategies.
- Authentication strategies used by complex organizations in large clusters (ex.
OIDC) are considered out of scope.
-
kube-apiserveronly recognizes users: no difference is made between admins and components requests. -
Successful authentication of a request produces a set of informations identifying the user :
field type managed by usernameString admin uidUUID k8s groupsString array admin + k8s extraString list map admin -
system:authenticatedis automatically added to thegroupsarray for all authenticated requests. -
Those informations are then associated with the request for subsequent evaluation by authorization policies.
-
Normal users
- Normal users are external processes (components or admins) authenticated to
kube-apiserver. - They have to authenticate using a configured authentication strategy.
- They are not managed as part of the cluster state and do not exist in the K8s API.
- Examples :
etcd,kubelet,kubernetes-admin, etc ...
- Normal users are external processes (components or admins) authenticated to
-
ServiceAccountusers-
ServiceAccountusers are cluster workloads (pods) authenticated tokube-apiserver. - They have to authenticate using the
ServiceAccountauthentication strategy. - They are managed automatically by
kube-apiserverand exist in the K8s API. - Examples :
kube-proxy,kubernetes-dashboard, etc ...
-
-
Anonymous users
- Any request not validated by the configured authentication strategies is considered anonymous.
- Anonymous authentication should be explicitly disabled using the
--anonymous-auth=falsecommand line option.
-
Compliant to the K8s model, user provisioning and management is granular and unopinionated.
-
kubeadm initautomatically provisions users for components and admins at bootstrapping time (see below). -
Outside of that, user provisioning is largely dependent on admins, through state updates or packages installation.
-
As a result, admins have to consider the following rules when manually provisioning users :
-
usernameshould be unique for the cluster and not conflict with existing users. -
groupsis unopinionated : it identifies and characterizes users the same waylabelsdoes with workloads. -
extrahas to be supported by dedicated authorization policies and usually can be left blank.
-
-
Notes :
- K8s does not support
Userobjects : user information is never written to the cluster state. - Authentication strategies provide ways to "encode" user information inside authentication assets.
- K8s does not support
Authentication strategies for kube-apiserver can be configured using command line options.
- This strategy uses PKI for requests authentication : this is the
kubeadmdefault for provisioning normal users. - Requests are authenticated using mutual certificate validation :
- Validate that the certificate was issued by the cluster CA (for instance
CN = kubernetes). - Read the certificate's subject to identify the user (for instance
O = kubeadm:cluster-admins, CN = kubernetes-admin).
- Validate that the certificate was issued by the cluster CA (for instance
- New users are provisioned automatically or manually through issuance of
*.crtcertificate files. - Sets of certificates can be stored in
kubeconfigfiles (see below).
- This strategy uses JWTs for requests authentication : this is the sole strategy available for
ServiceAccountusers. - Requests are authenticated using bearer tokens :
- Validate that the token was signed by a dedicated private key (usually
/etc/kubernetes/pki/sa.key). - Decode the token claims to identify the user (for instance
system:serviceaccount:kubernetes-dashboard:administrator).
- Validate that the token was signed by a dedicated private key (usually
- New users are provisioned by creating
ServiceAccountobjects bound to specificSecretobjects that store the JWT. - Tokens will be mounted into pods to allow workload processes to interact with
kube-apiserver.
- Bootstrap tokens are used by
kubeadmto provision PKI assets forkubeletwhen a node joins a cluster. - Requests are authenticated using bearer tokens :
- Match the token ID and secret against the
Secretdata. - User identity will be established once
kubeletupdates the cluster state with information about the new node.
- Match the token ID and secret against the
-
kubeadm initprovisions specificSecretobjects in thekube-systemnamespace to store bootstrap tokens. - Management of bootstrap tokens by admins isn't required as long as the token secret is not compromised.
- This strategy allows for delegation of request authentication to an external service.
- Proxied requests are authenticated using certificate validation :
- Validate that the certificate was issued by the authentication proxy CA (for instance
CN = front-proxy-ca). - Read the certificate's subject to identify the external service (for instance
CN = front-proxy-client). - User identity will be established by reading specific request headers.
- Validate that the certificate was issued by the authentication proxy CA (for instance
- Multiple external services can be configured with
--requestheader-allowed-namesprovided they present valid certificates. -
kubeadm initprovisions a specific chain of trust forfront-proxy(see below). - However, it is not relevant to basic use cases since it is used for extending the kubernetes API.
kubeconfig files
-
kubeconfigfiles are YAML files storing identities for users and clusters, andcontextsto associate them. - K8s clients wishing to authenticate as normal users with x509 certificates receive such a file as a parameter with
--kubeconfig:
apiVersion: v1
kind: Config
# current context for client using this config
current-context: user-name@cluster-name
# contexts list, include for each :
# name -> username@cluster
# context -> binds cluster to user
contexts:
- name: user-name@cluster-name
context:
cluster: cluster-name
user: user-name
# clusters list, include for each :
# name -> configured cluster name
# cluster -> control plane + cluster CA certificate
clusters:
- name: cluster-name
cluster:
certificate-authority-data: CLUSTER_CA_CRT
server: https://control.plane.endpoint.com:6443
# users list, include for each :
# name -> optionally prefixed with colon separated groups
# user -> private key + client certificate (issued by cluster CA)
users:
- name: user-name
user:
client-certificate: APISERVER_CLIENT_CRT
client-key: APISERVER_CLIENT_KEY- Here, the client authenticates to
https://control.plane.endpoint.com:6443using certificateAPISERVER_CLIENT_CRT. -
kubeconfigcertificates and private keys can either be base64 encoded files or file paths. -
kubeadm initprovisionskubeconfigfiles for components and admins (see below).
PKI provisioning with kubeadm
kubeadm init provisions multiple chains of trust as well as client and server certificates for components and admins.
-
Provisioned certificates and private keys are stored in
/etc/kubernetes/pki:certificate type authenticates to CA certificate apiserver.crtServer kube-apiserverall API clients ca.crtapiserver-kubelet-client.crtClient kube-apiserverkubeletca.crtapiserver-etcd-client.crtClient kube-apiserveretcdetcd/ca.crtfront-proxy-client.crtClient kube-apiserverfront-proxyfront-proxy-ca.crtetcd/server.crtServer etcdall API clients etcd/ca.crtetcd/peer.crtClient etcdetcdpeer nodesetcd/ca.crtetcd/healthcheck-client.crtClient etcdetcdetcd/ca.crtsa.pubN/A ServiceAccountkube-apiserverN/A -
sa.pubis used to verify thatServiceAccounttokens were signed usingsa.key.
-
Provisioned certificates and private keys are stored in
/var/lib/kubelet/pki:certificate type authenticates to CA certificate kubelet-client-current.pemClient kubeletkube-apiserverca.crtkubelet-server-current.crtServer kubeletall API clients ca.crt -
kubelet-client-current.pemauthenticateskubeletrequests tokube-apiserver. -
kubelet-server-current.pemauthenticates requests to thekubeletAPI.
-
Certificates and private keys provisioned in
kubeconfigfiles are stored in/etc/kubernetes:file type authenticates to CA certificate controller-manager.confClient kube-controller-managerkube-apiserverca.crtscheduler.confClient kube-schedulerkube-apiserverca.crtkubelet.confClient kubeletkube-apiserverca.crtadmin.confClient kubernetes-adminkube-apiserverca.crtsuper-admin.confClient kubernetes-super-adminkube-apiserverca.crt -
Using
ServiceAccountto authenticate control plane components is not possible sincekubeadmruns them as static pods. -
As a result,
kube-controller-managerandkube-schedulerwill be passed the relevantkubeconfigas a command line option. -
Command line options can be inspected for static pods to review actual config or PKI settings :
# print the kube-scheduler command arguments when running as a static pod
kubectl get -n kube-system pod "kube-scheduler-$(hostname)" -o jsonpath='{.spec.containers[0].command}' | jq -r '.[] | @text'