Skip to content

Kubernetes OIDC Authentication Setup Guide for Okta#

This setion explains how to configure k0rdent to use Okta as an OIDC provider for authentication. While the examples use KinD (Kubernetes in Docker) for demonstration purposes, the concepts and procedures are fully applicable to any Kubernetes environment that meets the minimum requirements for k0rdent.

Prerequisites#

Before you begin, ensure that your environment meets the following prerequisites.

1. Required Software#

Make sure your development machine has the following installed:

  • Docker: Container runtime to build and run containerized applications.
  • k0rdent Management Cluster: Although KinD is used in this guide, you may use any k0rdent management cluster (for example, Minikube, MicroK8s, or a cloud-based cluster) that supports deploying k0rdent.
  • Helm: A package manager for Kubernetes to install and manage applications.
  • Coreutils: Standard UNIX utilities for various file operations.
  • jq: A lightweight and flexible command-line JSON processor.
  • jwt: A CLI tool to decode and inspect JSON Web Tokens.

2. Okta Setup#

Prepare your Okta environment by completing the following steps:

  • Create an Okta Developer Account:
    Visit the Okta Developer Signup page and create an account if you don’t already have one.

  • Review Okta Configuration Guides:
    Familiarize yourself with the Okta user interface and setup procedures using guides such as the UI Guide. Although this guide focuses on Kubernetes, these resources provide valuable context on configuring your Okta organization, applications, and OIDC settings.

  • Obtain Okta Credentials:
    After setting up your Okta account, note the following:

  • Your Okta Domain (for example, https://your-okta-domain.okta.com)
  • The Authorization Server URL (typically something like https://your-okta-domain.okta.com/oauth2/default)
  • The Client ID generated when you register your Kubernetes application in Okta
  • Any additional scopes or API keys as required by your integration

Installation Steps#

Follow these steps to deloy Okta.

1. Install Krew (Kubectl Plugin Manager)#

Krew is a package manager for kubectl plugins. Installing it ensures you can manage the OIDC login plugin easily.

You can install Krew by running the following command in your terminal. This script detects your OS and architecture, downloads the latest Krew release, extracts it, and installs it:

(
  set -x; cd "$(mktemp -d)" &&
  OS="$(uname | tr '[:upper:]' '[:lower:]')" &&
  ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')" &&
  KREW="krew-${OS}_${ARCH}" &&
  curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" &&
  tar zxvf "${KREW}.tar.gz" &&
  ./"${KREW}" install krew
)

For additional details, troubleshooting tips, and instructions for Windows installations, see the official Krew Installation Guide.

2. Install the OIDC Login Plugin#

The OIDC login plugin for kubectl simplifies the process of obtaining and refreshing tokens from your Okta instance.

kubectl krew update
kubectl krew install oidc-login

3. Create the Structured Authentication Configuration#

This configuration file tells your Kubernetes API server how to validate JWT tokens issued by Okta. Create a file named authentication-config.yaml with the following content:

apiVersion: apiserver.config.k8s.io/v1beta1
kind: AuthenticationConfiguration
jwt:
  - issuer:
      url: "https://trial-***.okta.com/oauth2/***"
      audiences:
        - 0oa***697
    claimMappings:
      username:
        claim: email
        prefix: ""
      groups:
        claim: groups
        prefix: ""
    claimValidationRules:
      - expression: "has(claims.email)"
        message: "email claim must be present"
      - expression: "claims.email != ''"
        message: "email claim must be non-empty"
      - expression: "has(claims.groups)"
        message: "groups claim must be present"
      - expression: "type(claims.groups) == list ? size(claims.groups) > 0 : true"
        message: "groups list must be non-empty"
      - expression: "type(claims.groups) == string ? claims.groups.size() > 0 : true"
        message: "groups string must be non-empty"        
    userValidationRules:
      - expression: "!user.username.startsWith('system:')"
        message: "username cannot use reserved system: prefix"
      - expression: "user.groups.all(group, !group.startsWith('system:'))"
        message: "groups cannot use reserved system: prefix"

Note: Replace placeholder values (e.g., trial-***, 0oa***697) with the actual values from your Okta configuration.

4. Configure Your Kubernetes Cluster#

Below is an example KinD cluster configuration that mounts the authentication configuration file. Adapt these instructions if you are using another Kubernetes system.

Create the KinD Cluster Configuration#

Create a file named kind-config.yaml:

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
featureGates:
  "StructuredAuthenticationConfiguration": true
nodes:
  - role: control-plane
    kubeadmConfigPatches:
      - |
        kind: ClusterConfiguration
        apiServer:
          extraArgs:
            authentication-config: /etc/kubernetes/authentication-config.yaml
          extraVolumes:
            - name: authentication-config
              hostPath: /etc/kubernetes/authentication-config.yaml
              mountPath: /etc/kubernetes/authentication-config.yaml
              readOnly: true
              pathType: File
    extraMounts:
      - hostPath: ./authentication-config.yaml
        containerPath: /etc/kubernetes/authentication-config.yaml
        readOnly: true

For other Kubernetes distributions, the concept remains the same—you need to configure your API server to load the authentication-config.yaml file. Check your cluster’s documentation for mounting configuration files and setting extra API server arguments.

5. Cluster Management with KinD (Example)#

If you are using KinD, execute the following commands. Otherwise, adjust these steps to match your Kubernetes provider’s procedures.

Create the KinD Cluster#

kind create cluster --verbosity 99 --config kind-config.yaml --retain

Retrieve API Server Pod Information#

To inspect the API server configuration, use:

kubectl describe pod -n kube-system kube-apiserver-$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')

Debugging the Control Plane#

For troubleshooting, you can view logs and container status:

docker exec kind-control-plane ls /var/log/containers/
docker exec kind-control-plane crictl ps

RBAC Configuration#

For k0rdent to work properly with OIDC-authenticated users, configure RBAC policies. Below is a sample RoleBinding configuration that grants permissions to a specific group.

Create a file named rolebinding.yaml:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: kcm-ns-viewer
  namespace: kcm-system
subjects:
  - kind: Group
    name: kcm-ns-viewer
    apiGroup: rbac.authorization.k8s.io
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: kcm-namespace-viewer-role

Apply this configuration using:

kubectl apply -f rolebinding.yaml

Token Management#

Obtaining an Okta OIDC Token#

Use the kubectl oidc-login plugin to retrieve a token from your Okta instance. The token is used for authenticating with your Kubernetes API server.

export K8S_TOKEN=$(kubectl oidc-login get-token \
  --oidc-issuer-url=https://trial-***.okta.com/oauth2/*** \
  --oidc-client-id=0oa***697 \
  --listen-address=127.0.0.1:8000 \
  --skip-open-browser=true \
  --oidc-extra-scope=email \
  --force-refresh | jq -r '.status.token' \
) && echo $K8S_TOKEN | jwt decode -

Tip: Replace the placeholder values with your actual Okta configuration details. The command pipes the token to jwt decode so you can inspect its contents.

Debug Token Validation#

Validate the token by performing a simple API call that includes a higher verbosity level for debugging:

kubectl --token=$K8S_TOKEN get secrets -n kcm-system -v=9

Configuring Kubernetes CLI#

After obtaining your token, update your kubectl configuration to use these OIDC credentials.

1. Set User Credentials#

kubectl config set-credentials user --token=$K8S_TOKEN

2. Create a New Context#

Set up a context that references your cluster and the new user credentials. For KinD, you might use:

kubectl config set-context user --cluster="kind-$(kind get clusters | head -1)" --user=user --namespace=kcm-system

For other Kubernetes clusters, replace the cluster name appropriately.

3. Verify Access#

Confirm that your OIDC credentials provide the necessary access:

kubectl --context=user auth can-i get namespaces
kubectl --context=user auth can-i get secrets -n kcm-system
kubectl --context=user auth can-i get pods -n kcm-system

4. Switch Contexts#

Switch to the OIDC context when needed:

kubectl config use-context user

To revert to your default context, use the standard context name (for example, the KinD default):

kubectl config use-context "kind-$(kind get clusters | head -1)"

5. View Kubeconfig Details#

Inspect your current kubeconfig to confirm the setup:

kubectl config view --context=user

6. [DEBUG] Inspect API Server Logs#

For further troubleshooting, review the API server logs:

kubectl --context="kind-$(kind get clusters | head -1)" logs -n kube-system kube-apiserver-kind-control-plane | grep authentication.go

By following these instructions, you will have a fully functional OIDC authentication system integrated with your Kubernetes cluster, regardless of whether you’re using KinD or another deployment environment.