OIDC Authentication
KSail provides native OIDC (OpenID Connect) authentication support. When configured, KSail:
- Injects OIDC flags into the Kubernetes API server at cluster creation time (per-distribution).
- Acts as an exec credential plugin (
ksail oidc get-token) â replacing the need for kubelogin. - Auto-configures kubeconfig with an OIDC user and context after cluster creation.
Prerequisites
Section titled âPrerequisitesâ- KSail CLI installed
- Docker running
- An OIDC provider (e.g., Dex) â either already deployed or planned for deployment via GitOps
Quick Start
Section titled âQuick Startâ-
Initialize a cluster with OIDC
Terminal window ksail cluster init \--oidc-issuer-url https://dex.example.com \--oidc-client-id kubectl \--oidc-extra-scope email \--oidc-extra-scope groupsOr add OIDC configuration to an existing
ksail.yaml:spec:cluster:oidc:issuerURL: https://dex.example.comclientID: kubectlextraScopes:- email- profile- groups -
Create the cluster
Terminal window ksail cluster createKSail automatically:
- Configures the API server with
--oidc-*flags - Adds an
oidc-<cluster-name>user to your kubeconfig (exec-based, pointing toksail oidc get-token) - Adds an
oidc@<cluster-name>context
- Configures the API server with
-
Deploy your OIDC provider
Deploy your OIDC provider (e.g., Dex) as a workload. Once itâs running, the OIDC context becomes usable:
Terminal window kubectl --context oidc@<cluster-name> get podsOn first use,
ksail oidc get-tokenopens your browser for authentication.
Configuration Reference
Section titled âConfiguration ReferenceâAll OIDC settings live under spec.cluster.oidc in ksail.yaml. See the Declarative Configuration reference for the full schema.
| Field | Type | Default | Description |
|---|---|---|---|
issuerURL | string | â | OIDC provider issuer URL. Setting this enables OIDC. |
clientID | string | â | OIDC client ID for kubectl authentication. |
extraScopes | []string | â | Additional OIDC scopes beyond openid. |
usernameClaim | string | email | JWT claim for Kubernetes username. |
usernamePrefix | string | oidc: | Prefix prepended to OIDC usernames. |
groupsClaim | string | groups | JWT claim for Kubernetes group membership. |
groupsPrefix | string | oidc: | Prefix prepended to OIDC group names. |
caFile | string | â | Path to CA certificate for self-signed OIDC providers. |
CLI Flags
Section titled âCLI FlagsâOIDC can also be configured via CLI flags on ksail cluster init, ksail cluster create, and ksail cluster update:
--oidc-issuer-url OIDC provider issuer URL--oidc-client-id OIDC client ID--oidc-extra-scope Additional OIDC scopes (repeatable)--oidc-username-claim JWT claim for Kubernetes username--oidc-username-prefix Prefix for OIDC usernames--oidc-groups-claim JWT claim for Kubernetes groups--oidc-groups-prefix Prefix for OIDC groups--oidc-ca-file Path to CA certificateHow It Works
Section titled âHow It WorksâAPI Server Configuration
Section titled âAPI Server ConfigurationâKSail injects the following flags into the Kubernetes API server based on spec.cluster.oidc:
--oidc-issuer-url=<issuerURL>--oidc-client-id=<clientID>--oidc-username-claim=<usernameClaim>--oidc-username-prefix=<usernamePrefix>--oidc-groups-claim=<groupsClaim>--oidc-groups-prefix=<groupsPrefix>--oidc-ca-file=<caFile> # only when caFile is setEach distribution handles this differently:
| Distribution | Mechanism |
|---|---|
| Vanilla (Kind) | kubeadm ClusterConfiguration patch with apiServer.extraArgs |
| K3s (K3d) | --kube-apiserver-arg=--oidc-* flags |
| Talos | cluster.apiServer.extraArgs machine config patch |
| VCluster | controlPlane.distro.k8s.apiServer.extraArgs Helm values |
Exec Credential Plugin
Section titled âExec Credential Pluginâksail oidc get-token implements the Kubernetes exec credential plugin protocol. The authentication flow:
- Check token cache (
~/.ksail/oidc/cache/) â return if still valid - If expired, attempt token refresh using the stored refresh token
- If no valid token, start authorization code flow with PKCE:
- Start a local HTTP callback server
- Open browser to the OIDC authorize endpoint
- User authenticates (e.g., via GitHub, Google, LDAP â depends on provider configuration)
- Receive callback with authorization code
- Exchange code for tokens
- Cache tokens and output
ExecCredentialJSON to stdout
Kubeconfig Layout
Section titled âKubeconfig LayoutâAfter ksail cluster create, your kubeconfig contains both admin and OIDC entries:
# Admin user (certificate-based, always works)users:- name: <cluster-name> user: client-certificate-data: ...
# OIDC user (exec-based, requires OIDC provider to be running)- name: oidc-<cluster-name> user: exec: apiVersion: client.authentication.k8s.io/v1 command: ksail args: - oidc - get-token - --issuer-url=https://dex.example.com - --client-id=kubectl - --extra-scope=email - --extra-scope=groups interactiveMode: IfAvailable
contexts:# Admin context (default)- name: kind-<cluster-name> context: cluster: kind-<cluster-name> user: <cluster-name>
# OIDC context- name: oidc@<cluster-name> context: cluster: kind-<cluster-name> user: oidc-<cluster-name>The admin context remains the default. Switch to the OIDC context explicitly:
kubectl --context oidc@<cluster-name> get pods# orkubectl config use-context oidc@<cluster-name>Chicken-and-Egg: OIDC Provider Deployment
Section titled âChicken-and-Egg: OIDC Provider DeploymentâThe API server OIDC flags reference an OIDC provider that is deployed after cluster creation. This is expected:
- The admin context (certificate-based) always works, regardless of OIDC provider state.
- The OIDC context becomes usable once the OIDC provider is running.
- Deploy your OIDC provider via GitOps (
ksail workload apply, Flux, or ArgoCD).
Self-Signed OIDC Providers (Local Development)
Section titled âSelf-Signed OIDC Providers (Local Development)âFor local development with self-signed certificates (e.g., mkcert):
spec: cluster: oidc: issuerURL: https://dex.platform.lan clientID: kubectl caFile: /path/to/rootCA.pem extraScopes: - email - groupsThe caFile field specifies a host path to the CA certificate. KSail automatically handles mounting it into the cluster:
- Kind/Vanilla: Mounted as a read-only
extraMountinto all nodes at/etc/kubernetes/pki/oidc-ca.crt - K3d/K3s: Mounted as a volume into server nodes at
/etc/kubernetes/pki/oidc-ca.crt - Talos: CA content is embedded via
machine.filesonto the node filesystem at/etc/kubernetes/pki/oidc-ca.crt - VCluster: Mounted via a
hostPathvolume from the host Kubernetes node into the VCluster control plane pod
The CA file path is also passed to ksail oidc get-token via kubeconfig exec args for client-side token verification.
RBAC Integration
Section titled âRBAC IntegrationâOIDC usernames and groups are available in Kubernetes RBAC. With the default prefixes:
apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: name: oidc-adminroleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-adminsubjects: # Bind to a specific OIDC user - kind: User name: "oidc:user@example.com" # Or bind to an OIDC group - kind: Group name: "oidc:platform-admins"Related
Section titled âRelatedâ- Declarative Configuration â full
ksail.yamlschema reference - Secret Management â encrypting secrets with SOPS
- Kubernetes OIDC documentation â upstream reference