User authentication in Kubernetes: a primer
Captured source
source ↗User authentication in Kubernetes: a primer Build • Eli Holderness • 19/04/23 • 5 min read
Administering a Kubernetes cluster safely and efficiently is hard, and it’s even harder if there’s only one of you. However, if you want to share the load, you’ll need to make sure you’re doing it securely. If your cluster is going to accept configuration changes from multiple people, it needs to know who those people are, and to make them prove their identity. In other words, it needs to be able to authenticate them.
Authn vs. authz
There are two concepts you’ll often hear mentioned in the same breath: authentication (often abbreviated to ‘ authn ’ or a12n ) and authorization (similarly, ‘ authz ’ or a11n ). They’re closely related, but subtly different, and mixing them up can get you into hot water. So, what does each one actually mean?
Authentication relates to who you are , and it can get pretty philosophical - it’s essentially an abstraction over identity. How does a piece of software know who you are? Most mechanisms rely on you, as a user, providing some kind of trusted proxy for your identity. Depending on your authn method, this proxy could be anything from a password that only you know, a cryptographically signed bearer token that only you should have, or physical ownership of a piece of hardware like a YubiKey.
Authorization relates to what you can do , and almost always comes after authentication when you’re talking about software. Once you’ve authenticated with your K8s cluster, that’s where K8s’ Role-Based Access Control (RBAC) mechanism comes into play. This is your cluster’s built-in method for determining whether a given user is allowed to perform certain actions, such as modifying configuration or accessing data. Even if a user is able to authenticate, they may not have any permissions granted to them by your cluster’s RBAC system.
Authentication flows in K8s
Let’s say a user wants to configure something about a K8s cluster. What does that look like? Well, first, they’ll make a request. That could be over HTTP, through a web UI, or on the command-line, using kubectl . For the purposes of this article, these can all be considered equivalently.
Then, once the request is received by your deployment, your cluster has to figure out who the request has come from. Kubernetes provides a few built-in mechanisms for doing this, and you also have the option to integrate third-party authentication systems. In other words, your cluster can either decide for itself, or delegate the decision to a trusted third party.
This description is (of course) an oversimplification — in fact, later in this article we’ll discuss an authentication flow in which the incoming request does not go directly to the cluster — but broadly speaking it’s a useful way to think about how authentication happens.
Kubernetes-native authentication methods
Kubernetes comes with three built-in methods of user authentication, which allow a cluster to identify the originator of a request all by itself (NB: this article doesn’t cover service account authentication, since service accounts aren’t users!)
Static bearer tokens
When you start your cluster’s API server, you have the option to give it a CSV file of static tokens corresponding to known users . That way, when a known user wants to make a configuration change, they include the token along with their request, and the API server can check that token against its file of known and trusted users. ‘Including the token’ could mean putting it into an HTTP header, or passing it in explicitly on the command line.
Since the list of known good tokens is a file that forms part of the API server, tokens cannot be revoked or updated without restarting it; tokens also cannot expire. This makes it hard to revoke access to a given user on the fly.
This method of authentication is extremely simple, but it comes with the standard risks associated with bearer tokens : if they’re leaked, you have to revoke them entirely, and that could mean downtime while you restart the API server.
For more info, see the K8s docs on static bearer files .
X509 Client certificates
Kubernetes also provides native support for X509 certificates, a well-established method of authentication used to provide HTTPS. To set this up in your cluster, you need to provide a certificate authority (or CA) file to your API server upon start. This certificate authority doesn’t have to be an existing one, like that provided by LetsEncrypt; you can generate a self-signed one yourself .
Then, you can use that certificate authority to generate new client certificates. These are files which are cryptographically signed by the CA, and your cluster can use the CA to determine whether or not a given client certificate is valid.
In practice, this authentication flow is pretty similar to using static bearer tokens; when you make a request to your cluster, you include the client certificate, and the cluster can use its certificate authority to determine the validity of your request. Similarly to static bearer tokens, in order to revoke a certificate, you’ll have to restart your API server to remove the certificate authority that issued it.
However, certificates can have expiry dates, meaning that if one gets leaked there’s an automatic time limit on it. There’s also tooling like cert-manager, allowing you to use existing X509 entities like LetsEncrypt for your clusters and streamline the process of managing your client certificates.
For more info, see the K8s docs on X509 client certificates .
Bootstrap tokens
Including bootstrap tokens in a primer about authentication is a bit cheeky, because I would argue that they’re actually about authorization. Bootstrap tokens can be created when you initialize a cluster with kubeadm init ; they’re tokens that give the bearer access to a lot of permissions. They’re intended for use during the initial configuration of a cluster, before you’ve set up any other authentication methods.
Bootstrap tokens work exactly like static bearer tokens in practice; you attach them to any request you make, and you will be granted access. However, static bearer tokens configured in a file within the API server also contain information about who you are, whereas all the information a bootstrap token conveys about your identity is ‘bootstrapper’ — hence my argument that they’re actually about what you can do, not who you are, and are therefore authorization tokens rather than…
Excerpt shown — open the source for the full document.