Kubernetes access with your yubikey

Security software engineer
Kubernetes access with your yubikey
KubiKey as a project started out with one main goal: streamline and make more secure the process of accessing the kubernetes cluster used by Tweede golf.

Kubikey was David's introductory project when he started with us. Check out David’s first weeks at Tweede golf

We use the Google kubernetes engine as one of the tools for hosting products. The default, Google supported way of accessing such a cluster from the command line is through logging in via the Google Cloud SDK, and letting it configure kubectl for you. When used as intended, this provides a relatively low-friction way to access the cluster.

Unfortunately, the authentication process with the Google Cloud SDK leads to the creation of access tokens on the computers harddrive with very long lifetimes. This leads to risks of stolen credentials should a computer be lost whilst its Google Cloud SDK is still logged in. It is possible to manually log out the SDK after use, but as this is a user initiated process, it comes with the risk of a user forgetting to do this. Furthermore, the process of logging in the Google Cloud SDK, whilst not overly complicated, still requires a number of steps to be completed by the user, leading to friction when forced to log in often.

KubiKey aims to solve this by providing shorter-lived access tokens for our main use case, kubernetes access, whilst at the same time reducing friction by integrating the login flow into the user experience of kubectl. It achieves this by utilizing a private key stored in a yubikey secure hardware token, and using this to generate kubernetes access tokens when running kubectl. The yubikey's pin, when needed, can be fetched in-terminal during the kubectl command execution as needed, significantly reducing login flow friction for end users at the same time.

How it works

KubiKey is built to provide access to gcloud service accounts. This was chosen as Google only allows external private key access for gcloud service accounts, enforcing standard google authentication for normal gcloud user accounts. This service account is configured with the public key from the yubikey's authentication (slot 9a) key.

For our cluster, kubectl is configured to use KubiKey as its authentication provider. When running a command, when it needs an access token for the cluster it invokes KubiKey to get one.

At this point, KubiKey first asks the user for a pin to unlock the yubikey, and then proceeds to sign a user token. This user token is not usable directly as authentication for kubernetes, so it then sends it to the Google authentication servers to obtain a one-hour valid access token for the kubernetes cluster.

KubiKey returns this token to kubectl, which is then able to use it to access the cluster. Kubectl also takes care of caching this token for us, enabling the user to run multiple commands in short succession without having to enter his pin each and every time.


It can be concluded that KubiKey is a successful project for internal use at Tweede golf. If you want to try out KubiKey check out its readme, or take a look at how the above described process is implemented under the hood, KubiKey can be found on github.

We work on a lot of cool projects here at Tweede golf. If you are interested in what we do, take a look at our open source work and other blog posts to get to know more!

Stay up-to-date

Stay up-to-date with our work and blog posts?

Related articles

When sudo-rs development started, we added several dependencies using Rust’s crates ecosystem to quickly ramp up development. During development we accrued approximately 135 transitive (direct and indirect) dependencies. Once this was identified, we managed to reduce our total dependencies down to three. In this blog, we explain why and how we did this.
Thanks to funding from NLNet and ISRG, the sudo-rs team was able to request an audit from Radically Open Security (ROS). In this post, we'll share the findings of the audit and our response to those findings.
Sending documents over the internet can be a pain. Email providers generally support attachments with a maximum size between 10 and 50 MB, for larger files one would need to find another way. Most people would probably use one of the many public cloud or file sender solutions. But what if the files to be sent contain personal information, medical information or are private family photos? And how do you know that only the recipient can access and download these files?