Skip to content

OAuth2 and OpenID Connect

Back we we created the k0sctl.yaml file, we set some parameters to talk to an OpenID Connect server:

oidc-issuer-url: https://auth.mydomain
oidc-client-id: k0s
oidc-username-claim: email
oidc-groups-claim: groups
If you were paying attention, you put a hostname to an existing OIDC server in there and you're wondering how it works. If you blindly put in our sample values, that's okay we'll get there together.

Setting up a full blown OIDC RP at this point is a bit beyond the scope of this tutorial so far, so if you have one you can configure great! And if not, skip around until we get to setting up Authelia then come back here.

kubectl, krew and oidclogin

We'll start by using krew, a plugin manager for kubectl to install kubelogin. kubelogin is a helper for OIDC and kubectl.

kubectl krew install oidc-login
Updated the local copy of plugin index.
Installing plugin: oidc-login
Installed plugin: oidc-login
\
 | Use this plugin:
 |  kubectl oidc-login
 | Documentation:
 |  https://github.com/int128/kubelogin
 | Caveats:
 | \
 |  | You need to setup the OIDC provider, Kubernetes API server, role binding and kubeconfig.
 | /
/
WARNING: You installed plugin "oidc-login" from the krew-index plugin repository.
   These plugins are not audited for security by the Krew maintainers.
   Run them at your own risk.

Setup oidc-login

From your OIDC RP admin, get the client issuers url, client id and client secret. The redirect_uri you'll need to provide to them is localhost:8000 and localhost:18000.

kubectl oidc-login \
  setup \
  --oidc-issuer-url=https://auth.mydomain \
  --oidc-client-id=402acfd0-fad4-42fd-bfe7-69e7827ec5b3 \
  --oidc-client-secret=kJFj6X8d7XGpohi24syTDqUippKx9e5U0YBkLCLAPul1PLjc4xqxTik0PGdF3qC4uLqutMnv

Once you run that, it will pop open a browser window for you to login according to your server's requirements. Once that's doen your terminal will display further instructions to complete the setup.

## 2. Verify authentication

You got a token with the following claims:

{
  "amr": [
    "pwd",
    "hwk",
    "user",
    "pin",
    "mfa"
  ],
  "at_hash": "PiSwyfuxGa0qyw1Gx5iGMQ",
  "aud": [
    "402acfd0-fad4-42fd-bfe7-69e7827ec5b3"
  ],
  "auth_time": 1709275307,
  "azp": "402acfd0-fad4-42fd-bfe7-69e7827ec5b3",
  "client_id": "402acfd0-fad4-42fd-bfe7-69e7827ec5b3",
  "exp": 1709346271,
  "iat": 1709342671,
  "iss": "https://auth.mydomain",
  "jti": "e94d1f18-7815-471f-b0c2-fde720a1a647",
  "nonce": "gPiTxw8WT8UvBlnl5dEDw3BwCk6YjcNZJPUfi-qpAso",
  "rat": 1709342671,
  "sub": "97277ad0-356d-4e2a-8448-ad8b5d1c024f"
}

## 3. Bind a cluster role

Run the following command:

    kubectl create clusterrolebinding oidc-cluster-admin --clusterrole=cluster-admin --user='https://auth.mydomain#97277ad0-356d-4e2a-8448-ad8b5d1c024f'

## 4. Set up the Kubernetes API server

Add the following options to the kube-apiserver:

    --oidc-issuer-url=https://auth.mydomain
    --oidc-client-id=402acfd0-fad4-42fd-bfe7-69e7827ec5b3

## 5. Set up the kubeconfig

Run the following command:

    kubectl config set-credentials oidc \
      --exec-api-version=client.authentication.k8s.io/v1beta1 \
      --exec-command=kubectl \
      --exec-arg=oidc-login \
      --exec-arg=get-token \
      --exec-arg=--oidc-issuer-url=https://auth.mydomain \
      --exec-arg=--oidc-client-id=402acfd0-fad4-42fd-bfe7-69e7827ec5b3 \
      --exec-arg=--oidc-client-secret=kYWetlqktCObArnE.13a9MYgpRSylAnXxIwyvPpsj0Jj_V~rK3XMVuf.AtlJ98kBBOK4s2gY

## 6. Verify cluster access

Make sure you can access the Kubernetes cluster.

    kubectl --user=oidc get nodes

You can switch the default context to oidc.

    kubectl config set-context --current --user=oidc

You can share the kubeconfig to your team members for on-boarding.

Configure Kubernetes

So let's do what the instructions say:

kubectl create clusterrolebinding oidc-cluster-admin --clusterrole=cluster-admin --user='https://auth.mydomain#97277ad0-356d-4e2a-   8448-ad8b5d1c024f'

Verify access

kubectl config set-credentials oidc \
  --exec-api-version=client.authentication.k8s.io/v1beta1 \
  --exec-command=kubectl \
  --exec-arg=oidc-login \
  --exec-arg=get-token \
  --exec-arg=--oidc-issuer-url=https://auth.mydomain \
  --exec-arg=--oidc-client-id=402acfd0-fad4-42fd-bfe7-69e7827ec5b3 \
  --exec-arg=--oidc-client-secret=kYWetlqktCObArnE.13a9MYgpRSylAnXxIwyvPpsj0Jj_V~rK3XMVuf.AtlJ98kBBOK4s2gY

kubectl --user=oidc get nodes
NAME   STATUS   ROLES           AGE     VERSION
cn1    Ready    control-plane   3h45m   v1.29.2+k0s
cn2    Ready    control-plane   3h44m   v1.29.2+k0s
cn3    Ready    control-plane   3h44m   v1.29.2+k0s

Set the OIDC user to be our default user

kubectl config set-context --current --user=oidc

See the asciicast below,