OIDC Login to Kubernetes and Kubectl with Keycloak

A commonly cited pain point for teams working with Kubernetes clusters is managing the configuration to connect to the cluster. All to often this ends up being either sending KUBECONFIG files with hardcoded credentials back and forth or fragile custom shell scripts wrapping the AWS or GCP cli's.

In this post we'll integrate Kubernetes with Keycloak so that when we execute a kubectl or helm command, if the user is not already authenticated, they'll be presented with a keycloak browser login where they can enter their credentials. No more sharing KUBECONFIG files and forgetting to export different KUBECONFIG paths!

We'll also configure group based access control, so we can, for example create a KubernetesAdminstrators group, and have all users in that group given cluster-admin access automatically.

When we remove a user from Keycloak (or remove them from the relevant groups within Keycloak) they will then lose access to the cluster (subject to token expiry).

For this we'll be using OpenID Connect, more here on how this works.

By default, configuring Kubernetes to support OIDC auth requires passing flags to the kubelet API server. The challenge with this approach is that only one such provider can be configured and managed Kubernetes offerings - e.g. GCP or AWS - use this for their proprietary IAM systems.

To address this we will use kube-oidc-proxy, a tool from Jetstack which allows us to connect to a proxy server which will manage OIDC authentication and use impersonation to give the authenticating user the required permissions. This approach has the benefit of being universal across clusters, so we don't have to follow different approaches for our managed vs unmanaged clusters.

This post is part of a series on single sign on for Kubernetes.

Web application authentication and authorization with Keycloak and OAuth2 Proxy on Kubernetes using Nginx Ingress

In this post we'll setup a generic solution which allows us to add authentication via Keycloak to any application, simply by adding an ingress annotation. This gives us a much more extendable and secure alternative to basic auth.

Comprehensive docker registry on Kubernetes with Harbor and Keycloak for single sign on

In this post we'll install a feature rich but lightweight docker registry and integrate login and authorization with Keycloak users and groups.

Harbor is an open source registry which can serve multiple types of cloud artifacts and secure them using fine grained access control. In this case we'll be focussed on using harbor as a docker image registry and linking it's authentication with Keycloak but it is also capable of serving multiple other types of artifact, including helm charts.

This post is part of a series on single sign on for Kubernetes.

Docker Registry Authentication on Kubernetes with Keycloak

In this post we'll cover how to use Keycloak to provide a simple authentication layer for a Docker registry. Simple meaning that in order to push and pull images to the registry, the user will first need to docker login as any valid user in the provided Keycloak realm. Note that there is no additional access control, so all Keycloak users have the ability to perform any action on any image once authenticated. For more fine grained controls, see the section on using Harbour.

This post is part of a series on single sign on for Kubernetes.

Gitea SSO with Keycloak, OpenLDAP and OpenID Connect

Gitea is a lightweight open source git service. As an aside, Gitea - especially when combined with Drone CI - is one of my favourite pieces of open source software!

It's minimal footprint and easy to use interface make it perfect for running on clusters to facilitate git push deploys and CI.

Here we'll configure OpenLDAP for centralised user management and single sign on. We'll optionally configure OpenID Connect but with several caveats on its usage.

This post is part of a series on single sign on for Kubernetes.

Keycloak and OpenLDAP on Kubernetes

In this post we'll cover how - having installed Keycloak and OpenLDAP separately on Kubernetes - to link the two together so that Keycloak uses OpenLDAP as it's primary store for user data.

This post is part of a series on single sign on for Kubernetes.

Installing OpenLDAP on Kubernetes with Helm

In this post we cover how to install OpenLDAP on Kubernetes and how to test that it is working using the command line.

LDAP while an older - and in some ways more challenging to work with - approach to SSO than something like OIDC, is still the de-facto standard.

There are many popular applications which don't support OIDC but do support LDAP. This is likely to be the case for many years to come so for now, any robust SSO solution is likely to need to support LDAP.

This post is part of a series on single sign on for Kubernetes

Installing Keycloak on Kubernetes

Keycloak is a widely used open source identity and access management system. Think Okta but open source. This is where users will actually enter their username and password for services and where we'll configure which users can login to which applications. It will also provide users with a single directory of applications they can login to.

In this post - as part of the larger series on Kubernetes SSO - we cover how to install Keycloak on Kubernetes.

Useful Links when Setting up SSO on Kubernetes

While creating the comprehensive guide to Kubernetes SSO, I leant heavily on many great pieces of existing content, a lot of them are included here.

Automated remote Debian development environment for VSCode with Ansible

One of the things VSCode has done extremely well is creating a seamless remote development experience. Using the remote extension pack, specifically the SSH development extension, it's possible to run VSCode locally, while performing all actions on a remote server completely seamlessly. This allows us to use a local VM for much faster docker development on macOS. It also means we are free to spin up powerful Cloud VM's with many cores and plenty of RAM when we're working on more intensive tasks.

With this setup I seamlessly switch between fully local development using a Virtualbox VM and a 16 core cloud VM with 64GB of RAM when I need more horsepower. In both environments this provides the level of Docker performance I associate with developing directly on Linux machines.

This is streamlined using an Ansible playbook which automatically sets up Debian VM's with sensible defaults for development, including a beautiful default ZSH configuration (inc auto-completions) and easy language version management with asdf. This post starts with the practical steps required for this setup, and then goes on to explain what's being installed and how it works.

tmux, docker and SSH agent forwarding when developing remotely with VSCode

SSH agent forwarding is kind of like magic. Say you're using VSCode remote development to develop on a remote VM and you want to pull from a private repository. By default you might either generate a new keypair on the remote machine and add them to Github. Or you might copy your existing private key to the remote development machine. The former is fiddly and the latter raises some security concerns. With SSH Agent Forwarding you can allow the remote machine to authenticate requests using the keys on your local machine, without the keys ever leaving your local machine.

One hiccup with this is that if you're a tmux user, you'll find that this works initially but then stops working in subsequent sessions. This post offers a simple solution to this.

Automating MacOS Development setup with Ansible

Manual repetitive tasks are my nemesis and setting up a new Macbook from scratch is a prime example of this. Using Ansible we can completely automate this process. This is valuable both for individual efficiency and for facilitating standardised "team setups" so that new joiners avoid spending their first days googling obscure node version errors.

Ansible is a tool most commonly associated with the setup of servers and infrastructure. But more broadly it's an excellent tool for automating the setup of any computer, including laptops and workstations. Of all the configuration management tools out there it's by far the easiest one to use - requiring no devops background at all - and has an amazing community supporting it.

This posts outlines the setup I've evolved over the previous few years which means setting up a new Macbook pro for fairly broad development (Rails, Javascript, Elixir, Python, Android & iOS) now takes just a couple of commands. This includes loading all my shell customisations and GUI apps like Chrome, Office, Virtualbox etc.

Cloudformation - NodeGroup failed to stabilize: Internal Failure

A recent change to AWS NodeGroup behaviour means that some CloudFormation stacks which create EKS NodeGroups may start to fail with the error Nodegroup the-nodegroup-name failed to stabilize: Internal Failure. Googling currently doesn't return much. The problem is related to this change relating to whether or not public IP's are assigned to nodes.

90 Days of Learning

An area I’m keen to experiment with batching strategies for is learning. Specifically getting “over the hump” with things that require a substantial upfront commitment before a return is delivered. Today I'm kicking off a 90 day experiment of batching together learning three such things.

Habits and Batching

One of the most high leverage tools available to us is habit. We are the sum of the things we do, our habits tend to be the things we do most and therefore we tend towards being the sum of our habits. Charles Duhigg's The Power of Habit is a great primer on this. An interplay I'm increasingly interested in is the one between habits and batching (or habits of batching).