Skip to content

feat(oidc-discovery): add OIDC discovery server chart - #3

Open
fabian-albrecht wants to merge 9 commits into
mainfrom
feat/gateway-chart
Open

fabian-albrecht wants to merge 9 commits into
mainfrom
feat/gateway-chart

Conversation

@fabian-albrecht

@fabian-albrecht fabian-albrecht commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Description

Adds the oidc-discovery Helm chart — the API-server OIDC discovery server for Greenhouse. It exposes the Kubernetes discovery endpoints (/.well-known/openid-configuration and /openid/v1/jwks) through an externally provided Gateway (Gateway API), so clients can locate the issuer and fetch the JWKS used to verify tokens.

What type of PR is this?

  • 🍕 Feature

Charts affected

  • Chart(s): oidc-discovery (new)
  • New chart at version: 0.1.0
  • No impact on existing charts

What's in the chart

Rendered resources (all gated on discovery.enabled):

  • ListenerSet — an HTTPS :443 listener that attaches to an externally provided Gateway via discovery.parentRefName
  • HTTPRoute — routes /.well-known/openid-configuration and /openid/v1/jwks to the API server
  • Backend + BackendTLSPolicy — the static API-server target (discovery.apiserverHostname) and its TLS policy
  • TrafficPolicy — the OIDC traffic policy
  • RBAC (ClusterRoleBinding) + _helpers.tpl, and a ci/test-values.yaml fixture for chart-testing

Key values (discovery.*): enabled, subDomain/hostname, apiserverHostname, parentRefName (required — the external Gateway to attach to), parentRefNamespace, listenerSetAnnotations, httpRouteAnnotations, tls.secretName.

How was this tested?

  • helm template renders exactly the 6 discovery resources (no Gateway/GatewayParameters)
  • Omitting discovery.parentRefName fails fast with a clear "required" message
  • ct lint passes for the chart (uses the new ci/test-values.yaml)

Added to documentation?

  • 💬 values.yaml keys documented with comments
  • 🧪 ci/test-values.yaml fixture added

Notes

  • The central Gateway is intentionally not part of this chart; the discovery server is designed to attach to a Gateway owned elsewhere.
  • Gateway-API resources depend on their CRDs (gateway.networking.k8s.io/v1, gateway.kgateway.dev/v1alpha1) being installed on the cluster; the templates render unconditionally and rely on those CRDs being present (install fails loudly if absent, rather than silently skipping required resources).

Copilot AI balanced review requested due to automatic review settings October 30, 2026 08:53
@fabian-albrecht
fabian-albrecht requested a review from a team as a code owner October 30, 2026 08:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Incomplete API capability guards can cause installation failures and unresolved GatewayParameters references, while Selector mode lacks the namespace selector needed to control ListenerSet attachment.

4 open issues
What changed in this PR

Adds a standalone Helm chart for Greenhouse’s central Gateway and API-server OIDC discovery endpoints, supporting migration from Ingress to Gateway API.

Changes:

  • Introduces the central Gateway with optional static IP and kgateway-specific autoscaling.
  • Adds discovery routing, backend TLS validation, response transformation, and access permissions.
  • Provides configurable values, shared naming helpers, and chart-testing values.
File Description
charts/​gateway/​values.yaml Defines Gateway, autoscaling, and discovery settings.
charts/​gateway/​templates/​trafficpolicy-oidc.yaml Rewrites the discovery response’s JWKS URL.
charts/​gateway/​templates/​rbac.yaml Grants unauthenticated access to discovery endpoints.
charts/​gateway/​templates/​listenerset.yaml Adds the discovery HTTPS listener.
charts/​gateway/​templates/​httproute.yaml Routes discovery and JWKS requests to the API server.
charts/​gateway/​templates/​gatewayparameters.yaml Configures kgateway proxy autoscaling.
charts/​gateway/​templates/​gateway.yaml Defines the central Gateway and migration options.
charts/​gateway/​templates/​backendtlspolicy.yaml Configures API-server TLS validation.
charts/​gateway/​templates/​backend.yaml Defines the static API-server backend.
charts/​gateway/​templates/​_helpers.tpl Supplies naming, labels, hostname, and HPA helpers.
charts/​gateway/​ci/​test-values.yaml Supplies discovery-enabled chart-testing values.
charts/​gateway/​Chart.yaml Declares the new application chart.

Review effort: Balanced

SPDX-License-Identifier: Apache-2.0
*/}}

{{- if and .Values.discovery.enabled (.Capabilities.APIVersions.Has "gateway.networking.k8s.io/v1") -}}
Comment thread charts/gateway/templates/gateway.yaml Resolved
Comment thread charts/gateway/templates/gateway.yaml Outdated
namespaces:
from: {{ .Values.gateway.allowedListenersFrom }}
{{- end }}
{{- $hpaEnabled := include "gateway.hpaEnabled" . }}
SPDX-License-Identifier: Apache-2.0
*/}}

{{- if .Values.discovery.enabled -}}
…ery server

Introduce a self-contained charts/gateway chart that bundles two
Gateway-API concerns behind independent enable flags:

- gateway.enabled renders the central Gateway resource (GatewayClass,
  allowedListeners, a default HTTP :80 base listener to satisfy the
  CRD minItems:1 requirement, overridable via gateway.listeners).
- discovery.enabled renders the API-server OIDC discovery server:
  a ListenerSet + HTTPRoute that proxy /.well-known/openid-configuration
  and /openid/v1/jwks through the Gateway, a kgateway Static Backend and
  BackendTLSPolicy targeting the API server, a TrafficPolicy that rewrites
  jwks_uri to the external hostname, and a ClusterRoleBinding granting
  unauthenticated access to the discovery endpoint.

The discovery ListenerSet defaults its parentRef to this chart's own
Gateway (<release>-gateway), so a single install with gateway.enabled=true
yields a coherent Gateway + ListenerSet pair; discovery.parentRefName can
override it to attach to an externally managed Gateway. Setting
discovery.enabled=false deploys only the Gateway.

Gateway and BackendTLSPolicy are guarded on the gateway.networking.k8s.io/v1
capability so the chart renders cleanly where the CRDs are absent.

Signed-off-by: Fabian Albrecht <fabian.albrecht01@sap.com>
The gateway chart had no ci/ folder, so ct lint/install rendered it with
defaults where global.dnsDomain (and gateway.className when the gateway is
enabled) are required-but-empty, failing the render.

Add ci/test-values.yaml supplying global.dnsDomain and exercising the central
Gateway together with the OIDC discovery server, matching the sibling charts'
ci/ fixtures.

Signed-off-by: Fabian Albrecht <fabian.albrecht01@sap.com>
Signed-off-by: Fabian Albrecht <fabian.albrecht01@sap.com>
Add gateway.address to pin the Gateway's LoadBalancer IP via the kgateway
spec-native spec.addresses field (type: IPAddress). Setting it to an existing
Ingress's IP preserves that address when migrating ingress -> gateway. Empty
by default, so the provider assigns a dynamic IP (unchanged behavior).

Signed-off-by: Fabian Albrecht <fabian.albrecht01@sap.com>
Add Horizontal Pod Autoscaling for the Gateway proxy via a GatewayParameters
resource, linked from the Gateway through spec.infrastructure.parametersRef.

HPA is a kgateway-specific feature, so it is gated on gateway.hpa.enabled AND
gateway.className == "kgateway" (via the gateway.hpaEnabled helper); it is off
by default. The GatewayParameters resource is additionally CRD-gated on
gateway.kgateway.dev/v1alpha1.

New values under gateway.hpa: enabled, minReplicas, maxReplicas, and a
pass-through HPA v2 metrics list (defaults to CPU @ 80%).

Signed-off-by: Fabian Albrecht <fabian.albrecht01@sap.com>
The chart advertised Selector as an allowed value for gateway.allowedListenersFrom
but rendered 'from: Selector' with no selector, which the API rejects.

Add gateway.allowedListenersNamespaceSelector and a gateway.allowedNamespaces
helper that renders the required selector block when Selector is chosen, failing
fast if the selector is missing. The placeholder HTTP :80 listener (present only
to satisfy the Gateway API minItems: 1 requirement) is pinned to 'from: Same'
since nothing routes through it.

Addresses a Copilot review comment on #3.

Signed-off-by: Fabian Albrecht <fabian.albrecht01@sap.com>
Remove the .Capabilities.APIVersions.Has checks from the Gateway,
BackendTLSPolicy, and GatewayParameters templates. The chart's CRDs are a hard
prerequisite, so the resources now always render (gated only on their functional
conditions) and a missing CRD fails the install loudly instead of silently
skipping required resources. This also keeps the HPA parametersRef and the
GatewayParameters resource on the same guard, so they can no longer diverge.

Signed-off-by: Fabian Albrecht <fabian.albrecht01@sap.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

The templates lack the advertised CRD capability checks, so enabled resources are submitted even when required CRDs are absent, causing Helm to fail with “no matches for kind.”

4 open issues
1 resolved since last review

Review effort: Balanced

Comment thread charts/gateway/templates/gateway.yaml Outdated
SPDX-License-Identifier: Apache-2.0
*/}}

{{- if .Values.gateway.enabled -}}
Revert the consolidation of the discovery server into a broader gateway chart.
The central Gateway API resource and its kgateway HPA (GatewayParameters) are
removed; the chart now contains only the OIDC discovery server and is renamed
back to oidc-discovery.

- delete gateway.yaml and gatewayparameters.yaml
- remove the gateway: values block (className, address, allowedListeners*,
  listeners, annotations, infrastructureAnnotations, hpa.*) and the dead
  hpaEnabled / allowedNamespaces helpers
- discovery.parentRefName is now required (no in-chart Gateway to default to);
  the discovery server attaches to an externally provided Gateway
- rename the chart dir, Chart.yaml name/description, and all gateway.* helper
  identifiers to oidc-discovery.*

Signed-off-by: Fabian Albrecht <fabian.albrecht01@sap.com>
@fabian-albrecht fabian-albrecht changed the title feat(gateway): add gateway chart with central Gateway, OIDC discovery, and ingress-migration support feat(oidc-discovery): add OIDC discovery server chart Nov 3, 2026
Add a PluginDefinition CR describing the oidc-discovery chart to the Greenhouse
platform, referencing the chart in the GHCR OCI registry. Expose the chart's
user-facing values as plugin options (global.dnsDomain and
discovery.parentRefName required; parentRefNamespace and apiserverHostname
optional).

The plugindefinition.yaml lives in the chart dir but is excluded from the
packaged chart via .helmignore, since it is platform metadata, not a rendered
manifest.

Signed-off-by: Fabian Albrecht <fabian.albrecht01@sap.com>
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.

2 participants