Skip to content

Commit 2d43914

Browse files
authored
docs(oidc): add self-signed certificates configuration guide (#443)
## Summary - Add documentation for configuring OIDC authentication with Keycloak when using self-signed certificates - Cover Talos machine configuration with certificate mounting and host entries - Include kubelogin setup instructions and troubleshooting section ## Test plan - [ ] Verify documentation renders correctly in Hugo - [ ] Check all links work properly <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added comprehensive guides for configuring Kubernetes OIDC authentication with self-signed certificates, covering prerequisites, Talos control plane configuration, kubelogin setup, kubectl credential configuration, and troubleshooting steps. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2 parents 4e210dd + 11753cf commit 2d43914

2 files changed

Lines changed: 315 additions & 0 deletions

File tree

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
---
2+
title: "Self-Signed Certificates"
3+
linkTitle: "Self-Signed Certificates"
4+
description: "How to configure OIDC with self-signed certificates"
5+
weight: 60
6+
---
7+
8+
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.
9+
10+
## Prerequisites
11+
12+
- Cozystack cluster with OIDC enabled (see [Enable OIDC Server](../enable_oidc/))
13+
- Talos Linux control plane nodes
14+
- `talosctl` configured for your cluster
15+
- `kubelogin` installed
16+
17+
## Step 1: Retrieve the Keycloak Certificate
18+
19+
Get the certificate from the ingress controller:
20+
21+
```bash
22+
echo | openssl s_client -connect <KEYCLOAK_INGRESS_IP>:443 \
23+
-servername keycloak.example.org 2>/dev/null | openssl x509
24+
```
25+
26+
Replace `<KEYCLOAK_INGRESS_IP>` with your ingress controller IP address, and `keycloak.example.org` with your actual Keycloak domain.
27+
28+
Save the output (the certificate between `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----`) for the next step.
29+
30+
## Step 2: Configure Talos Control Plane Nodes
31+
32+
For each control plane node, add the following to your machine configuration:
33+
34+
```yaml
35+
machine:
36+
network:
37+
extraHostEntries:
38+
- ip: <KEYCLOAK_INGRESS_IP>
39+
aliases:
40+
- keycloak.example.org
41+
files:
42+
- content: |
43+
-----BEGIN CERTIFICATE-----
44+
<YOUR_CERTIFICATE_CONTENT>
45+
-----END CERTIFICATE-----
46+
permissions: 0o644
47+
path: /var/oidc-ca.crt
48+
op: create
49+
50+
cluster:
51+
apiServer:
52+
extraArgs:
53+
oidc-issuer-url: https://keycloak.example.org/realms/cozy
54+
oidc-client-id: kubernetes
55+
oidc-username-claim: preferred_username
56+
oidc-groups-claim: groups
57+
oidc-ca-file: /etc/kubernetes/oidc/ca.crt
58+
extraVolumes:
59+
- hostPath: /var/oidc-ca.crt
60+
mountPath: /etc/kubernetes/oidc/ca.crt
61+
```
62+
63+
Apply the configuration to each control plane node:
64+
65+
```bash
66+
talosctl apply-config -n <NODE_IP> -f nodes/<node>.yaml
67+
```
68+
69+
{{% alert color="info" %}}
70+
The `extraHostEntries` configuration ensures that the Keycloak domain resolves correctly within the cluster, which is essential when using internal ingress IPs.
71+
{{% /alert %}}
72+
73+
## Step 3: Configure kubelogin
74+
75+
Install kubelogin if you haven't already:
76+
77+
```bash
78+
# Homebrew (macOS and Linux)
79+
brew install int128/kubelogin/kubelogin
80+
81+
# Krew (macOS, Linux, Windows and ARM)
82+
kubectl krew install oidc-login
83+
84+
# Chocolatey (Windows)
85+
choco install kubelogin
86+
```
87+
88+
Save the CA certificate from Step 1 to a file on your local machine:
89+
90+
```bash
91+
# Save the certificate to a file (e.g., ~/.kube/oidc-ca.pem)
92+
cat > ~/.kube/oidc-ca.pem <<EOF
93+
-----BEGIN CERTIFICATE-----
94+
<YOUR_CERTIFICATE_CONTENT>
95+
-----END CERTIFICATE-----
96+
EOF
97+
```
98+
99+
Set up OIDC login (this will open a browser for authentication):
100+
101+
```bash
102+
kubectl oidc-login setup \
103+
--oidc-issuer-url=https://keycloak.example.org/realms/cozy \
104+
--oidc-client-id=kubernetes \
105+
--certificate-authority=~/.kube/oidc-ca.pem
106+
```
107+
108+
Configure kubectl credentials:
109+
110+
```bash
111+
kubectl config set-credentials oidc \
112+
--exec-api-version=client.authentication.k8s.io/v1 \
113+
--exec-interactive-mode=IfAvailable \
114+
--exec-command=kubectl \
115+
--exec-arg=oidc-login \
116+
--exec-arg=get-token \
117+
--exec-arg="--oidc-issuer-url=https://keycloak.example.org/realms/cozy" \
118+
--exec-arg="--oidc-client-id=kubernetes" \
119+
--exec-arg="--certificate-authority=~/.kube/oidc-ca.pem"
120+
```
121+
122+
Switch to the OIDC user and verify:
123+
124+
```bash
125+
kubectl config set-context --current --user=oidc
126+
kubectl get nodes
127+
```
128+
129+
{{% alert color="info" %}}
130+
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.
131+
{{% /alert %}}
132+
133+
{{% alert color="warning" %}}
134+
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.
135+
{{% /alert %}}
136+
137+
## Troubleshooting
138+
139+
### Check API Server OIDC Logs
140+
141+
```bash
142+
kubectl logs -n kube-system -l component=kube-apiserver --tail=50 | grep oidc
143+
```
144+
145+
### Verify OIDC Flags Are Applied
146+
147+
```bash
148+
kubectl get pods -n kube-system -l component=kube-apiserver \
149+
-o jsonpath='{.items[0].spec.containers[0].command}' | tr ',' '\n' | grep oidc
150+
```
151+
152+
### Common Issues
153+
154+
- **Certificate not found**: Ensure the certificate file path in `extraVolumes` matches the path specified in `oidc-ca-file`.
155+
- **Domain resolution fails**: Verify that `extraHostEntries` is correctly configured on all control plane nodes.
156+
- **Authentication fails**: Check that the user exists in Keycloak and has the required group memberships (see [Users and Roles](../users_and_roles/)).
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
---
2+
title: "Self-Signed Certificates"
3+
linkTitle: "Self-Signed Certificates"
4+
description: "How to configure OIDC with self-signed certificates"
5+
weight: 60
6+
aliases:
7+
- /docs/oidc/self-signed-certificates
8+
- /docs/operations/oidc/self-signed-certificates
9+
---
10+
11+
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.
12+
13+
## Prerequisites
14+
15+
- Cozystack cluster with OIDC enabled (see [Enable OIDC Server](../enable_oidc/))
16+
- Talos Linux control plane nodes
17+
- `talosctl` configured for your cluster
18+
- `kubelogin` installed
19+
20+
## Step 1: Retrieve the Keycloak Certificate
21+
22+
Get the certificate from the ingress controller:
23+
24+
```bash
25+
echo | openssl s_client -connect <KEYCLOAK_INGRESS_IP>:443 \
26+
-servername keycloak.example.org 2>/dev/null | openssl x509
27+
```
28+
29+
Replace `<KEYCLOAK_INGRESS_IP>` with your ingress controller IP address, and `keycloak.example.org` with your actual Keycloak domain.
30+
31+
Save the output (the certificate between `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----`) for the next step.
32+
33+
## Step 2: Configure Talos Control Plane Nodes
34+
35+
For each control plane node, add the following to your machine configuration:
36+
37+
```yaml
38+
machine:
39+
network:
40+
extraHostEntries:
41+
- ip: <KEYCLOAK_INGRESS_IP>
42+
aliases:
43+
- keycloak.example.org
44+
files:
45+
- content: |
46+
-----BEGIN CERTIFICATE-----
47+
<YOUR_CERTIFICATE_CONTENT>
48+
-----END CERTIFICATE-----
49+
permissions: 0o644
50+
path: /var/oidc-ca.crt
51+
op: create
52+
53+
cluster:
54+
apiServer:
55+
extraArgs:
56+
oidc-issuer-url: https://keycloak.example.org/realms/cozy
57+
oidc-client-id: kubernetes
58+
oidc-username-claim: preferred_username
59+
oidc-groups-claim: groups
60+
oidc-ca-file: /etc/kubernetes/oidc/ca.crt
61+
extraVolumes:
62+
- hostPath: /var/oidc-ca.crt
63+
mountPath: /etc/kubernetes/oidc/ca.crt
64+
```
65+
66+
Apply the configuration to each control plane node:
67+
68+
```bash
69+
talosctl apply-config -n <NODE_IP> -f nodes/<node>.yaml
70+
```
71+
72+
{{% alert color="info" %}}
73+
The `extraHostEntries` configuration ensures that the Keycloak domain resolves correctly within the cluster, which is essential when using internal ingress IPs.
74+
{{% /alert %}}
75+
76+
## Step 3: Configure kubelogin
77+
78+
Install kubelogin if you haven't already:
79+
80+
```bash
81+
# Homebrew (macOS and Linux)
82+
brew install int128/kubelogin/kubelogin
83+
84+
# Krew (macOS, Linux, Windows and ARM)
85+
kubectl krew install oidc-login
86+
87+
# Chocolatey (Windows)
88+
choco install kubelogin
89+
```
90+
91+
Save the CA certificate from Step 1 to a file on your local machine:
92+
93+
```bash
94+
# Save the certificate to a file (e.g., ~/.kube/oidc-ca.pem)
95+
cat > ~/.kube/oidc-ca.pem <<EOF
96+
-----BEGIN CERTIFICATE-----
97+
<YOUR_CERTIFICATE_CONTENT>
98+
-----END CERTIFICATE-----
99+
EOF
100+
```
101+
102+
Set up OIDC login (this will open a browser for authentication):
103+
104+
```bash
105+
kubectl oidc-login setup \
106+
--oidc-issuer-url=https://keycloak.example.org/realms/cozy \
107+
--oidc-client-id=kubernetes \
108+
--certificate-authority=~/.kube/oidc-ca.pem
109+
```
110+
111+
Configure kubectl credentials:
112+
113+
```bash
114+
kubectl config set-credentials oidc \
115+
--exec-api-version=client.authentication.k8s.io/v1 \
116+
--exec-interactive-mode=IfAvailable \
117+
--exec-command=kubectl \
118+
--exec-arg=oidc-login \
119+
--exec-arg=get-token \
120+
--exec-arg="--oidc-issuer-url=https://keycloak.example.org/realms/cozy" \
121+
--exec-arg="--oidc-client-id=kubernetes" \
122+
--exec-arg="--certificate-authority=~/.kube/oidc-ca.pem"
123+
```
124+
125+
Switch to the OIDC user and verify:
126+
127+
```bash
128+
kubectl config set-context --current --user=oidc
129+
kubectl get nodes
130+
```
131+
132+
{{% alert color="info" %}}
133+
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.
134+
{{% /alert %}}
135+
136+
{{% alert color="warning" %}}
137+
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.
138+
{{% /alert %}}
139+
140+
## Troubleshooting
141+
142+
### Check API Server OIDC Logs
143+
144+
```bash
145+
kubectl logs -n kube-system -l component=kube-apiserver --tail=50 | grep oidc
146+
```
147+
148+
### Verify OIDC Flags Are Applied
149+
150+
```bash
151+
kubectl get pods -n kube-system -l component=kube-apiserver \
152+
-o jsonpath='{.items[0].spec.containers[0].command}' | tr ',' '\n' | grep oidc
153+
```
154+
155+
### Common Issues
156+
157+
- **Certificate not found**: Ensure the certificate file path in `extraVolumes` matches the path specified in `oidc-ca-file`.
158+
- **Domain resolution fails**: Verify that `extraHostEntries` is correctly configured on all control plane nodes.
159+
- **Authentication fails**: Check that the user exists in Keycloak and has the required group memberships (see [Users and Roles](../users_and_roles/)).

0 commit comments

Comments
 (0)