From 1d5911c0011ad9855e0702495e3590d98fb858c4 Mon Sep 17 00:00:00 2001 From: "ohotnikov.ivan" Date: Tue, 10 Feb 2026 02:27:49 +0300 Subject: [PATCH 1/2] docs(oidc): add self-signed certificates configuration guide Add documentation for configuring OIDC authentication with Keycloak when using self-signed certificates (default in Cozystack). Covers Talos machine configuration, certificate mounting, and kubelogin setup. Signed-off-by: ohotnikov.ivan --- .../oidc/self-signed-certificates.md | 143 ++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 content/en/docs/operations/oidc/self-signed-certificates.md diff --git a/content/en/docs/operations/oidc/self-signed-certificates.md b/content/en/docs/operations/oidc/self-signed-certificates.md new file mode 100644 index 00000000..293e28f6 --- /dev/null +++ b/content/en/docs/operations/oidc/self-signed-certificates.md @@ -0,0 +1,143 @@ +--- +title: "Self-Signed Certificates" +linkTitle: "Self-Signed Certificates" +description: "How to configure OIDC with self-signed certificates" +weight: 60 +aliases: + - /docs/oidc/self-signed-certificates +--- + +This guide explains how to configure Kubernetes API server for OIDC authentication with Keycloak when using self-signed certificates (default in Cozystack). + +## Prerequisites + +- Cozystack cluster with OIDC enabled (see [Enable OIDC Server](../enable_oidc/)) +- Talos Linux control plane nodes +- `talosctl` configured for your cluster +- `kubelogin` installed + +## Step 1: Retrieve the Keycloak Certificate + +Get the certificate from the ingress controller: + +```bash +echo | openssl s_client -connect :443 \ + -servername keycloak.example.org 2>/dev/null | openssl x509 +``` + +Replace `` with your ingress controller IP address, and `keycloak.example.org` with your actual Keycloak domain. + +Save the output (the certificate between `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----`) for the next step. + +## Step 2: Configure Talos Control Plane Nodes + +For each control plane node, add the following to your machine configuration: + +```yaml +machine: + network: + extraHostEntries: + - ip: + aliases: + - keycloak.example.org + files: + - content: | + -----BEGIN CERTIFICATE----- + + -----END CERTIFICATE----- + permissions: 0o644 + path: /var/oidc-ca.crt + op: create + +cluster: + apiServer: + extraArgs: + oidc-issuer-url: https://keycloak.example.org/realms/cozy + oidc-client-id: kubernetes + oidc-username-claim: preferred_username + oidc-groups-claim: groups + oidc-ca-file: /etc/kubernetes/oidc/ca.crt + extraVolumes: + - hostPath: /var/oidc-ca.crt + mountPath: /etc/kubernetes/oidc/ca.crt +``` + +Apply the configuration to each control plane node: + +```bash +talosctl apply-config -n -f nodes/.yaml +``` + +{{% alert color="info" %}} +The `extraHostEntries` configuration ensures that the Keycloak domain resolves correctly within the cluster, which is essential when using internal ingress IPs. +{{% /alert %}} + +## Step 3: Configure kubelogin + +Install kubelogin if you haven't already: + +```bash +# Homebrew (macOS and Linux) +brew install int128/kubelogin/kubelogin + +# Krew (macOS, Linux, Windows and ARM) +kubectl krew install oidc-login + +# Chocolatey (Windows) +choco install kubelogin +``` + +Set up OIDC login (this will open a browser for authentication): + +```bash +kubectl oidc-login setup \ + --oidc-issuer-url=https://keycloak.example.org/realms/cozy \ + --oidc-client-id=kubernetes \ + --insecure-skip-tls-verify +``` + +Configure kubectl credentials: + +```bash +kubectl config set-credentials oidc \ + --exec-api-version=client.authentication.k8s.io/v1 \ + --exec-interactive-mode=Never \ + --exec-command=kubectl \ + --exec-arg=oidc-login \ + --exec-arg=get-token \ + --exec-arg="--oidc-issuer-url=https://keycloak.example.org/realms/cozy" \ + --exec-arg="--oidc-client-id=kubernetes" \ + --exec-arg="--insecure-skip-tls-verify=true" +``` + +Switch to the OIDC user and verify: + +```bash +kubectl config set-context --current --user=oidc +kubectl get nodes +``` + +{{% alert color="warning" %}} +The `--insecure-skip-tls-verify` flag is used because kubelogin runs on your local machine, which doesn't have the self-signed certificate in its trust store. The API server itself uses the certificate file mounted in Step 2 for secure communication with Keycloak. +{{% /alert %}} + +## Troubleshooting + +### Check API Server OIDC Logs + +```bash +kubectl logs -n kube-system -l component=kube-apiserver --tail=50 | grep oidc +``` + +### Verify OIDC Flags Are Applied + +```bash +kubectl get pods -n kube-system -l component=kube-apiserver \ + -o jsonpath='{.items[0].spec.containers[0].command}' | tr ',' '\n' | grep oidc +``` + +### Common Issues + +- **Certificate not found**: Ensure the certificate file path in `extraVolumes` matches the path specified in `oidc-ca-file`. +- **Domain resolution fails**: Verify that `extraHostEntries` is correctly configured on all control plane nodes. +- **Authentication fails**: Check that the user exists in Keycloak and has the required group memberships (see [Users and Roles](../users_and_roles/)). From a7a20e4abfc0a37a943794680b112c779b6b34d4 Mon Sep 17 00:00:00 2001 From: "ohotnikov.ivan" Date: Fri, 13 Feb 2026 13:57:17 +0300 Subject: [PATCH 2/2] fix(docs): replace insecure-skip-tls-verify with certificate-authority approach Address review feedback: use --certificate-authority flag as the default approach instead of --insecure-skip-tls-verify, clarify that LetsEncrypt is the default in Cozystack (not self-signed), and document insecure skip as a temporary workaround only. Signed-off-by: ohotnikov.ivan --- .../oidc/self-signed-certificates.md | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/content/en/docs/operations/oidc/self-signed-certificates.md b/content/en/docs/operations/oidc/self-signed-certificates.md index 293e28f6..330e5cbd 100644 --- a/content/en/docs/operations/oidc/self-signed-certificates.md +++ b/content/en/docs/operations/oidc/self-signed-certificates.md @@ -7,7 +7,7 @@ aliases: - /docs/oidc/self-signed-certificates --- -This guide explains how to configure Kubernetes API server for OIDC authentication with Keycloak when using self-signed certificates (default in Cozystack). +This guide explains how to configure Kubernetes API server for OIDC authentication with Keycloak when using self-signed certificates. By default, Cozystack issues certificates via LetsEncrypt, but some environments (e.g., air-gapped or private enterprise networks) may use a custom CA instead. ## Prerequisites @@ -87,13 +87,24 @@ kubectl krew install oidc-login choco install kubelogin ``` +Save the CA certificate from Step 1 to a file on your local machine: + +```bash +# Save the certificate to a file (e.g., ~/.kube/oidc-ca.pem) +cat > ~/.kube/oidc-ca.pem < +-----END CERTIFICATE----- +EOF +``` + Set up OIDC login (this will open a browser for authentication): ```bash kubectl oidc-login setup \ --oidc-issuer-url=https://keycloak.example.org/realms/cozy \ --oidc-client-id=kubernetes \ - --insecure-skip-tls-verify + --certificate-authority=~/.kube/oidc-ca.pem ``` Configure kubectl credentials: @@ -101,13 +112,13 @@ Configure kubectl credentials: ```bash kubectl config set-credentials oidc \ --exec-api-version=client.authentication.k8s.io/v1 \ - --exec-interactive-mode=Never \ + --exec-interactive-mode=IfAvailable \ --exec-command=kubectl \ --exec-arg=oidc-login \ --exec-arg=get-token \ --exec-arg="--oidc-issuer-url=https://keycloak.example.org/realms/cozy" \ --exec-arg="--oidc-client-id=kubernetes" \ - --exec-arg="--insecure-skip-tls-verify=true" + --exec-arg="--certificate-authority=~/.kube/oidc-ca.pem" ``` Switch to the OIDC user and verify: @@ -117,8 +128,12 @@ kubectl config set-context --current --user=oidc kubectl get nodes ``` +{{% alert color="info" %}} +If your organization's CA is already installed in the system trust store (common in enterprise environments), you can omit the `--certificate-authority` flag entirely — kubelogin will use the system CA bundle automatically. +{{% /alert %}} + {{% alert color="warning" %}} -The `--insecure-skip-tls-verify` flag is used because kubelogin runs on your local machine, which doesn't have the self-signed certificate in its trust store. The API server itself uses the certificate file mounted in Step 2 for secure communication with Keycloak. +Avoid using `--insecure-skip-tls-verify`. If you cannot install the CA certificate on your machine or pass it via `--certificate-authority`, you can use `--insecure-skip-tls-verify` as a temporary workaround, but this disables TLS verification and is not recommended for production use. {{% /alert %}} ## Troubleshooting