Skip to content

fix(info): use root-host for Keycloak OIDC issuer URL in tenant kubeconfig - #2704

Merged
Aleksei Sviridkin (lexfrei) merged 1 commit into
mainfrom
fix/info-kubeconfig-oidc-issuer-url
May 26, 2026
Merged

fix(info): use root-host for Keycloak OIDC issuer URL in tenant kubeconfig#2704
Aleksei Sviridkin (lexfrei) merged 1 commit into
mainfrom
fix/info-kubeconfig-oidc-issuer-url

Conversation

@myasnikovdaniil

@myasnikovdaniil myasnikovdaniil commented May 21, 2026

Copy link
Copy Markdown
Contributor

What this PR does

The kubeconfig generated by the info package for non-root tenants pointed --oidc-issuer-url at keycloak.<TENANT>.<ROOT-DOMAIN>, but Keycloak's ingress and cert live at keycloak.<ROOT-DOMAIN> (built from _cluster.root-host). kubectl oidc-login then failed TLS verification against the nginx-ingress default fake cert, so the auto-generated kubeconfig was unusable for any non-root tenant.

$host was being sourced from _namespace.host (tenant-specific subdomain) with a lookup-based override that tried to read tenant-root's spec.values.host. That override has been dead since #1787 migrated tenant-root to valuesFrom (Secret-backed) — spec.values is now always empty, so the override never fires.

Source $host from _cluster.root-host directly, matching what packages/system/dashboard/templates/gatekeeper.yaml already does for the same Keycloak realm.

Verified with helm template tenant1 packages/extra/info -n tenant-tenant1 --set-string _namespace.host=tenant1.example.org --set-string _cluster.root-host=example.org ... — issuer URL is now https://keycloak.example.org/realms/cozy regardless of the per-namespace host.

Release note

fix(info): use root-host for the Keycloak OIDC issuer URL in tenant kubeconfigs so `kubectl oidc-login` succeeds against the real Keycloak cert on non-root tenants

Summary by CodeRabbit

  • Chores
    • Updated kubeconfig generation to consolidate host configuration handling, now using a single authoritative source instead of multiple fallback mechanisms.

Review Change Stack

…onfig

The kubeconfig generated for non-root tenants pointed
`--oidc-issuer-url` at `keycloak.<TENANT>.<ROOT-DOMAIN>` because
`$host` was sourced from `_namespace.host` (tenant-specific
subdomain). Keycloak's ingress and cert live at
`keycloak.<ROOT-DOMAIN>` (built from `_cluster.root-host`), so
`kubectl oidc-login` failed TLS verification against the
nginx-ingress default fake cert.

The existing lookup-based override that tried to read
`tenant-root`'s `spec.values.host` no longer triggers since
PR #1787 migrated tenant-root to `valuesFrom` (Secret-backed),
leaving `spec.values` empty.

Use `_cluster.root-host` directly, matching what the dashboard
gatekeeper template already does for the same Keycloak realm.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
@github-actions github-actions Bot added area/uncategorized PR auto-labeler could not map title scope to a known area/*; please review kind/bug Categorizes issue or PR as related to a bug size/XS This PR changes 0-9 lines, ignoring generated files labels May 21, 2026
@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c7af69b9-7406-4389-b746-e4865d4b00a8

📥 Commits

Reviewing files that changed from the base of the PR and between ce8e738 and 65ce407.

📒 Files selected for processing (1)
  • packages/extra/info/templates/kubeconfig.yaml

📝 Walkthrough

Walkthrough

The kubeconfig Helm template is simplified to resolve the host exclusively from cluster-level configuration. The template removes fallback logic that previously defaulted to namespace values and eliminates a conditional lookup of Flux HelmRelease resources that could override the host.

Changes

Kubeconfig Host Resolution Simplification

Layer / File(s) Summary
Host resolution logic simplification
packages/extra/info/templates/kubeconfig.yaml
$host is assigned directly from Values._cluster["root-host"] without fallbacks. Conditional Flux HelmRelease lookup that could override $host is removed. Template proceeds linearly after defining $k8sCa.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Poem

🐰 The kubeconfig now stands tall and clear,
No tangled paths or fallbacks here,
Just cluster root from the single source,
A simpler flow, a cleaner course!

🚥 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 and specifically identifies the main change: switching from using per-tenant namespace host to using root-host for the Keycloak OIDC issuer URL in kubeconfig templates.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/info-kubeconfig-oidc-issuer-url

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 and usage tips.

@dosubot dosubot Bot added area/extra Issues or PRs related to tenant-specific modules (packages/extra/) backport Should change be backported on previous release labels May 21, 2026
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request resolves an issue where auto-generated kubeconfigs for non-root tenants were failing TLS verification during OIDC login. By standardizing the OIDC issuer URL to use the cluster's root-host, the configuration now correctly points to the valid Keycloak ingress, and redundant, non-functional lookup logic has been cleaned up to simplify the template.

Highlights

  • OIDC Issuer URL Fix: Updated the kubeconfig generation to use the root-host for the Keycloak OIDC issuer URL, ensuring compatibility with valid TLS certificates on non-root tenants.
  • Removed Stale Lookup Logic: Removed dead code that attempted to look up host configurations from HelmRelease values, which had become non-functional following previous architectural changes.
New Features

🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment Gemini (@gemini-code-assist) Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on Gemini (@gemini-code-assist) comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request simplifies the kubeconfig.yaml template by removing a FluxCD-specific lookup block and streamlining the $host variable assignment. The feedback suggests improving code clarity by moving the $host definition inside the OIDC conditional block and applying defensive programming practices to handle potentially missing keys in .Values._cluster.

@@ -1,4 +1,4 @@
{{- $host := .Values._namespace.host | default (index .Values._cluster "root-host") }}
{{- $host := index .Values._cluster "root-host" }}

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.

low

The variable $host is now only used within the OIDC configuration block (line 38) and is no longer reassigned since the lookup block was removed. To improve code clarity and keep the scope tight, consider moving its definition inside the {{- if $oidcEnabled }} block, consistent with other OIDC-specific variables like $apiServerEndpoint and $k8sCa. Additionally, following the defensive programming guidelines in the style guide, it is safer to provide a default or check for the existence of _cluster (e.g., index (.Values._cluster | default dict) "root-host") to avoid template errors if the key is missing.

References
  1. Enforce defensive programming: ensure appropriate null/nil checks or other language-idiomatic guards exist before object property accesses. (link)

@lexfrei Aleksei Sviridkin (lexfrei) removed the area/uncategorized PR auto-labeler could not map title scope to a known area/*; please review label May 25, 2026

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.

LGTM — surgical fix, +1/-7. The bug is real, the dead-code removal claim checks out, and the fix matches the established pattern elsewhere in the chart tree.

Verified:

  • Bug is real: pre-PR, $host defaulted to .Values._namespace.host (e.g. tenant1.example.org), so the rendered OIDC issuer URL was https://keycloak.tenant1.example.org/realms/cozy. But Keycloak's ingress and TLS cert live at keycloak.<root-host> (e.g. keycloak.example.org), so oidc-login hit nginx-ingress's default fake cert and failed TLS verification on every non-root tenant.
  • Cross-reference accurate: packages/system/dashboard/templates/gatekeeper.yaml uses exactly this shape — {{- $host := index .Values._cluster "root-host" }} followed by --oidc-issuer-url=https://keycloak.{{ $host }}/realms/cozy. The info kubeconfig now matches the same realm in the same way, so a tenant user and the dashboard both authenticate against the same issuer URL.
  • Dead-code claim accurate: tenant-root.yaml uses valuesFrom: Secret name: cozystack-values (verified in packages/system/cozystack-basics/templates/tenant-root.yaml), so tenantRoot.spec.values is the empty struct, the and $tenantRoot $tenantRoot.spec $tenantRoot.spec.values $tenantRoot.spec.values.host chain always short-circuits, and the override has been a no-op since #1787 (merged 2026-01-05) migrated tenants to the Secret-backed valuesFrom mechanism. Removing the block matches the post-#1787 reality.
  • Codex finds no regression. CI is green (Build + E2E + pre-commit + Verify generated all pass).

Bot finding is cosmetic, not a blocker:

  • Gemini (low): "$host is now only used inside the $oidcEnabled block; consider moving it inside." Pure style nit, can be deferred — keeping the host at the top mirrors the dashboard gatekeeper.yaml shape, which is consistent.

Non-blocking follow-up (not gating this fix): packages/extra/info/ has no tests/ directory, so the contract "OIDC issuer URL renders from _cluster.root-host, not _namespace.host" isn't pinned. Neighbouring extra packages do ship helm-unittest (packages/extra/{ingress,etcd,gateway}/tests/). Adding a minimal info/tests/kubeconfig_test.yaml that asserts the rendered Secret contains https://keycloak.<root-host>/realms/cozy and explicitly not the namespace host would pin this regression vector for next time. Out of scope for a 1-line backport-tagged fix; worth a separate task once the info package gets its test scaffolding.

@lexfrei
Aleksei Sviridkin (lexfrei) merged commit edb3eeb into main May 26, 2026
14 checks passed
@lexfrei
Aleksei Sviridkin (lexfrei) deleted the fix/info-kubeconfig-oidc-issuer-url branch May 26, 2026 10:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/extra Issues or PRs related to tenant-specific modules (packages/extra/) backport Should change be backported on previous release kind/bug Categorizes issue or PR as related to a bug size/XS This PR changes 0-9 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants