Skip to content

docs(oidc): document private CA and staging trust - #650

Open
myasnikovdaniil wants to merge 1 commit into
mainfrom
docs/oidc-private-ca
Open

docs(oidc): document private CA and staging trust#650
myasnikovdaniil wants to merge 1 commit into
mainfrom
docs/oidc-private-ca

Conversation

@myasnikovdaniil

@myasnikovdaniil myasnikovdaniil commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

What this PR does

Replaces the self-signed leaf-pinning guide with an end-to-end OIDC trust guide for private CAs and Let's Encrypt staging. It documents wildcard certificate options, cert-manager CA bootstrap for disposable development environments, Talos TrustedRootsConfig and StaticHostConfig, the explicit kube-apiserver CA mount, browser and kubelogin trust, Keycloak trust boundaries, bootstrap behavior, verification, troubleshooting, and safe CA rotation order.

Also updates the OIDC enable page to reflect that Dashboard and LINSTOR backend requests use the internal Keycloak Service by default.

Validation

  • Hugo extended 0.160.1 preview build with next/ content
  • All documented YAML examples parsed with yq
  • Talos 1.13.6 control-plane configuration validated with talosctl validate --mode metal --strict
  • git diff --check
Document private CA and Let's Encrypt staging trust for OIDC.

Downstream repositories

Not applicable: this PR changes website documentation only and does not modify a Cozystack runtime contract.

Summary by CodeRabbit

  • Documentation
    • Updated OIDC guidance to explain internal Keycloak routing and external browser redirects.
    • Documented how to override the internal Keycloak URL.
    • Expanded certificate guidance for private CAs, Let’s Encrypt staging, wildcard certificates, and cert-manager.
    • Added instructions for trusting certificates across Talos, the Kubernetes API, browsers, and kubelogin.
    • Added verification, CA rotation, and troubleshooting guidance.

Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
Assisted-By: Claude <noreply@anthropic.com>
Assisted-By: GPT-5 <noreply@openai.com>
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The OIDC documentation now covers internal Keycloak routing, private and staging certificates, wildcard issuance, cluster trust configuration, client setup, verification, CA rotation, and troubleshooting.

Changes

OIDC certificate and routing documentation

Layer / File(s) Summary
Certificate sources and issuance
content/en/docs/next/operations/oidc/self-signed-certificates.md
The guide now covers private CAs, Let's Encrypt staging, wildcard certificates, and cert-manager development certificates.
Cluster trust integration
content/en/docs/next/operations/oidc/self-signed-certificates.md
The guide replaces legacy certificate handling with Talos, kube-apiserver, and OIDC issuer trust configuration.
OIDC routing and client configuration
content/en/docs/next/operations/oidc/enable_oidc.md, content/en/docs/next/operations/oidc/self-signed-certificates.md
The documentation describes internal Keycloak routing and TLS settings for dashboard, LINSTOR, oauth2-proxy, browsers, and kubelogin.
Verification, rotation, and troubleshooting
content/en/docs/next/operations/oidc/self-signed-certificates.md
The guide adds verification commands, CA rotation procedures, outage conditions, and troubleshooting diagnostics.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: kvaps

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: documenting private CA and staging trust for OIDC.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/oidc-private-ca

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@netlify

netlify Bot commented Aug 12, 2026

Copy link
Copy Markdown

Deploy Preview for cozystack ready!

Name Link
🔨 Latest commit 6331409
🔍 Latest deploy log https://app.netlify.com/projects/cozystack/deploys/6a7cc4989d2fff00094347bd
😎 Deploy Preview https://deploy-preview-650--cozystack.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@content/en/docs/next/operations/oidc/self-signed-certificates.md`:
- Around line 272-276: The kube-apiserver inspection commands only examine the
first pod via .items[0]. Update both kubectl jsonpath expressions to iterate
over .items[*] and include each pod’s name in the output, so OIDC arguments and
ca-certificates mounts are checked across every control-plane node.
- Around line 77-96: Update the development-root-ca Certificate manifest to
explicitly disable renewal using spec.renewal.policy: Disabled when supported by
the deployed cert-manager version. If that field is unavailable, document the
existing CA overlap procedure and instruct operators to follow it before
renewal; do not rely on privateKey.rotationPolicy to control certificate
renewal.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f16b32e4-e307-41f7-9947-5a85b9738dc6

📥 Commits

Reviewing files that changed from the base of the PR and between 1e21c76 and 6331409.

📒 Files selected for processing (2)
  • content/en/docs/next/operations/oidc/enable_oidc.md
  • content/en/docs/next/operations/oidc/self-signed-certificates.md

Comment on lines 77 to +96
```yaml
machine:
network:
extraHostEntries:
- ip: <KEYCLOAK_INGRESS_IP>
aliases:
- keycloak.example.org
files:
- content: |
-----BEGIN CERTIFICATE-----
<YOUR_CERTIFICATE_CONTENT>
-----END CERTIFICATE-----
permissions: 0o644
path: /var/oidc-ca.crt
op: create
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: development-root-ca
namespace: cozy-cert-manager
spec:
isCA: true
commonName: Cozystack development root CA
subject:
organizations:
- Cozystack development
secretName: development-root-ca
duration: 87600h
privateKey:
algorithm: ECDSA
size: 256
issuerRef:
name: selfsigned-cluster-issuer
kind: ClusterIssuer

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

kubectl -n cozy-cert-manager get certificate development-root-ca \
  -o jsonpath='{.spec.duration}{"\n"}{.spec.renewBefore}{"\n"}{.spec.renewal.policy}{"\n"}{.status.renewalTime}{"\n"}'

Repository: cozystack/website

Length of output: 200


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

file="content/en/docs/next/operations/oidc/self-signed-certificates.md"

printf '%s\n' '--- target section ---'
sed -n '60,110p' "$file"

printf '%s\n' '--- rotation and renewal references ---'
rg -n -C 5 'development-root-ca|renew|rotation|overlap|281|291' "$file"

printf '%s\n' '--- repository references to cert-manager renewal fields ---'
rg -n -S 'renewBefore|renewalPolicy|renewal\.policy|rotationPolicy|privateKey:' . \
  -g '*.md' -g '*.yaml' -g '*.yml' -g '*.json' || true

Repository: cozystack/website

Length of output: 5339


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

file="content/en/docs/next/operations/oidc/self-signed-certificates.md"

printf '%s\n' '--- target section ---'
sed -n '60,110p' "$file"

printf '%s\n' '--- rotation and renewal references ---'
rg -n -C 5 'development-root-ca|renew|rotation|overlap' "$file"

printf '%s\n' '--- repository references to cert-manager renewal fields ---'
rg -n -S 'renewBefore|renewalPolicy|renewal\.policy|rotationPolicy|privateKey:' . \
  -g '*.md' -g '*.yaml' -g '*.yml' -g '*.json' || true

Repository: cozystack/website

Length of output: 5339


🌐 Web query:

cert-manager Certificate disable automatic renewal renewal policy self-signed CA duration renewBefore official documentation

💡 Result:

In cert-manager, you can manage and disable automatic certificate renewal using the Certificate resource's specification [1]. To disable automatic renewal for a Certificate, you can set the renewal policy to Disabled in your manifest [1]: spec: renewal: policy: Disabled This setting prevents cert-manager from automatically renewing the certificate [1]. It is often used for manually managed root or intermediate CA certificates where automatic rotation is not desired [1]. Key concepts regarding renewal and duration: Renewal Policy and Timing: cert-manager determines when to renew a certificate based on its duration and the configured renewal window [1][2]. By default, renewal occurs at 2/3 of the certificate's duration [3]. You can control this timing using: - renewBefore: Specifies the absolute duration before expiry to trigger renewal [4][2]. - renewBeforePercentage: Specifies a relative percentage of the certificate's total duration before expiry to trigger renewal [4]. Self-Signed CA Duration: When using a SelfSigned issuer to bootstrap a CA, you define the duration in the Certificate spec (e.g., spec: duration: 87600h) [1]. Note that cert-manager does not provide automatic rotation for CA certificates stored in Secrets [5]. If you use a long-lived self-signed CA, you must plan for manual rotation or replacement [5][6]. If a CA certificate is near expiry, leaf certificates signed by it will not automatically be re-issued unless you manually trigger the process or manage the rotation carefully [5]. Manual Reissue: Even when automatic renewal is disabled (via policy or other means), you can still manually trigger a certificate reissue by deleting the associated Secret or using tools like cmctl [1][7][8]. Note: Ensure your duration and renewBefore values are specified using valid Go duration strings (e.g., 8760h, 30m, 1h), avoiding unsupported suffixes like 'd' for days [2][9]. The minimum accepted renewBefore value is 5 minutes [4][2].

Citations:


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

for url in \
  'https://cert-manager.io/docs/usage/certificate/' \
  'https://cert-manager.io/docs/configuration/ca/' \
  'https://cert-manager.io/docs/reference/api-docs/' \
  'https://raw.githubusercontent.com/cert-manager/cert-manager/master/deploy/crds/crd-certmanager.io_certificates.yaml'
do
  printf '\n--- %s ---\n' "$url"
  curl -L --fail --silent --show-error "$url" |
    rg -in -C 3 'renewal policy|renewBefore|renewalPolicy|rotationPolicy|automatically renew|CA certificate|does not.*renew|isCA' |
    head -n 120 || true
done

Repository: cozystack/website

Length of output: 50374


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

tmp="$(mktemp)"
trap 'rm -f "$tmp"' EXIT

curl -L --fail --silent --show-error \
  'https://raw.githubusercontent.com/cert-manager/cert-manager/master/deploy/crds/crd-certmanager.io_certificates.yaml' \
  >"$tmp"

printf '%s\n' '--- renewal schema ---'
python3 - "$tmp" <<'PY'
import sys, yaml

with open(sys.argv[1]) as f:
    crd = yaml.safe_load(f)

schema = crd["spec"]["versions"][0]["schema"]["openAPIV3Schema"]
props = schema["properties"]["spec"]["properties"]
print(yaml.safe_dump(props.get("renewal", {}), sort_keys=False))
PY

printf '%s\n' '--- official documentation matches ---'
for url in \
  'https://cert-manager.io/docs/usage/certificate/' \
  'https://cert-manager.io/docs/configuration/ca/'
do
  printf '\n%s\n' "$url"
  curl -L --fail --silent --show-error "$url" |
    tr '<' '\n' |
    rg -i -m 30 -C 2 'renewal policy|renewBefore|rotation policy|CA certificates|automatically renew|root certificate|self.?signed' || true
done

Repository: cozystack/website

Length of output: 206


🌐 Web query:

site:cert-manager.io/docs/reference/api-docs CertificateRenewal RenewalPolicy Disabled RenewBefore cert-manager

💡 Result:

There is no CertificateRenewal policy option called Disabled in cert-manager [1]. The cert-manager Certificate API allows for renewal configuration through the renewal field, which supports the RenewBefore policy [1]. The renewBefore field defines an absolute duration before the certificate expiry when renewal should be attempted, while the renewBeforePercentage field allows defining this threshold as a percentage of the total certificate lifetime [1]. If renewBefore is not explicitly set, cert-manager defaults the renewal threshold to one-third of the issued certificate's lifetime [1]. There is no documented parameter to disable the automatic renewal process entirely through a policy setting [1].

Citations:


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

for url in \
  'https://raw.githubusercontent.com/cert-manager/cert-manager/master/pkg/apis/certmanager/v1/types_certificate.go' \
  'https://raw.githubusercontent.com/cert-manager/cert-manager/master/pkg/controller/certificates/sync.go' \
  'https://raw.githubusercontent.com/cert-manager/cert-manager/master/pkg/controller/certificates/trigger/trigger_controller.go'
do
  printf '\n--- %s ---\n' "$url"
  curl -L --fail --silent --show-error "$url" |
    rg -n -C 4 'Renewal|renewal|isCA|SelfSigned|renewBefore|nextPrivateKeySecretName' |
    head -n 160 || true
done

Repository: cozystack/website

Length of output: 10471


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- cert-manager trigger sources ---'
curl -L --fail --silent --show-error \
  'https://api.github.com/repos/cert-manager/cert-manager/contents/pkg/controller/certificates/trigger' |
  jq -r '.[].download_url' |
  while read -r url; do
    [ "$url" = "null" ] && continue
    printf '\n--- %s ---\n' "$url"
    curl -L --fail --silent --show-error "$url" |
      rg -n -C 5 'CertificateRenewalPolicyDisabled|Disabled|renewal policy|isCA|SelfSigned' |
      head -n 120 || true
  done

printf '%s\n' '--- cert-manager version references in the repository ---'
rg -n -i -S 'cert-manager|certmanager.io/v1' . \
  -g '*.md' -g '*.yaml' -g '*.yml' -g '*.json' |
  head -n 200 || true

Repository: cozystack/website

Length of output: 50374


Define the development root CA renewal policy.

cert-manager renews Certificate resources by default. If renewBefore is unset, renewal starts at one-third of the issued lifetime. A renewed self-signed root can replace the Secret and invalidate clients that trust the previous root. If the deployed cert-manager version supports spec.renewal.policy: Disabled, set it for this disposable root. Otherwise, document and follow the existing CA overlap procedure before renewal. privateKey.rotationPolicy does not disable certificate renewal.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@content/en/docs/next/operations/oidc/self-signed-certificates.md` around
lines 77 - 96, Update the development-root-ca Certificate manifest to explicitly
disable renewal using spec.renewal.policy: Disabled when supported by the
deployed cert-manager version. If that field is unavailable, document the
existing CA overlap procedure and instruct operators to follow it before
renewal; do not rely on privateKey.rotationPolicy to control certificate
renewal.

Comment on lines +272 to +276
kubectl get pod -n kube-system -l component=kube-apiserver \
-o jsonpath='{range .items[0].spec.containers[0].command[*]}{.}{"\n"}{end}' | grep oidc

kubectl get pod -n kube-system -l component=kube-apiserver \
-o jsonpath='{range .items[0].spec.containers[0].volumeMounts[*]}{.name}{"\t"}{.mountPath}{"\n"}{end}' | grep ca-certificates

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Inspect every kube-apiserver pod.

Both commands query .items[0]. In a multi-control-plane cluster, a missing OIDC argument or CA mount on another node remains undetected. Iterate over .items[*] and print the pod name, or run the check once per control-plane node.

</review_comment>

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@content/en/docs/next/operations/oidc/self-signed-certificates.md` around
lines 272 - 276, The kube-apiserver inspection commands only examine the first
pod via .items[0]. Update both kubectl jsonpath expressions to iterate over
.items[*] and include each pod’s name in the output, so OIDC arguments and
ca-certificates mounts are checked across every control-plane node.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant