--- # oauth2-proxy — forward-auth for apps WITHOUT usable OIDC (PiHole, *arr UIs, qBittorrent, Homepage, # Prometheus, Alertmanager, Hubble UI — ADR-0014). Authenticates users against the Keycloak `homelab` # realm, then the Gateway ext-auth lets the request through only for an authenticated session # (R-IDP-02: no management UI unauthenticated). Chart image is quay.io/oauth2-proxy (not Bitnami). apiVersion: helm.toolkit.fluxcd.io/v2 kind: HelmRelease metadata: name: oauth2-proxy namespace: oauth2-proxy spec: interval: 30m chart: spec: chart: oauth2-proxy version: ">=7.0.0 <8.0.0" # TODO(WS-SEC): pin at bring-up; Renovate maintains sourceRef: kind: HelmRepository name: oauth2-proxy namespace: oauth2-proxy install: remediation: retries: 3 upgrade: remediation: retries: 3 values: replicaCount: ${OAUTH2_PROXY_REPLICAS} # overlay knob: dev 1 / prod 2 (HA) — R-ENV-02 config: # client-id / client-secret / cookie-secret from the SOPS secret (name only). client-id + # client-secret MUST match the realm's `oauth2-proxy` client (keycloak-realm-clients secret). existingSecret: oauth2-proxy-credentials extraArgs: provider: oidc oidc-issuer-url: https://keycloak.home.keithjackson.dev/realms/homelab # Forward-auth (ext-auth) mode: no upstream app; return 202 for an authenticated session so the # Gateway ext-authz can allow/deny. Auth headers are surfaced to the backend. reverse-proxy: "true" upstream: static://202 set-xauthrequest: "true" pass-access-token: "true" email-domain: "*" # Single sign-in/callback host for all forward-auth-protected services on the platform zone. redirect-url: https://auth.home.keithjackson.dev/oauth2/callback whitelist-domain: ".home.keithjackson.dev" cookie-domain: ".home.keithjackson.dev" cookie-secure: "true" # Expose group membership so per-service group authorization (R-IDP-06) can be enforced. The # Keycloak `oauth2-proxy` client emits a `groups` claim (full.path=false => bare names like # `platform-admins`, keycloak-realm-import.yaml). `--allowed-groups` below is the PLATFORM FLOOR: # a valid Keycloak session is NOT enough — the user must ALSO be in `platform-admins`, or # /oauth2/auth returns 403 and ext_authz denies (R-IDP-06). Every currently-onboarded # forward-auth app (pihole, *arr, qbittorrent, homepage, prometheus, alertmanager, hubble) # declares `groups: [platform-admins]` in its ServiceDefinition, so this floor matches them all. # Per-ROUTE group differentiation (a future app allowing a different group) does NOT need a # second proxy: the ext_authz filter appends `?allowed_groups=` to /oauth2/auth from the # HTTPRoute's `homelab.keithjackson.dev/auth-groups` annotation — oauth2-proxy honours the # per-request query on top of this floor. See forward-auth-cec.yaml + README "opt-in". oidc-groups-claim: groups allowed-group: platform-admins # R-IDP-06 floor: authenticated AND in platform-admins (oauth2-proxy flag is singular --allowed-group, repeatable) # Single Keycloak provider => skip the oauth2-proxy interstitial "Sign In" button and 302 # straight to Keycloak. Verified in-cluster: WITHOUT this, an ext_authz-denied browser request # gets oauth2-proxy's HTML sign-in page (HTTP 403) instead of an immediate redirect (docs/15 UX). skip-provider-button: "true" scope: "openid email profile" # Metrics for the ServiceMonitor (../oauth2-proxy servicemonitor in platform-config). metrics: enabled: true # ENFORCEMENT (Phase 6): oauth2-proxy is the AUTHENTICATOR; the per-route ext_authz ENFORCEMENT is # Gateway-side. On Cilium 1.16.5 the shared Gateway's Envoy config is a machine-owned, constantly # regenerated CiliumEnvoyConfig (`gateway/cilium-gateway-shared`) that CANNOT be injected into, # and native Gateway-API ExternalAuth (GEP-1494) ships in NO released Cilium version yet. The # enforcement mechanism + the three wiring options are documented in README.md; the interim # self-authored ext_authz listener is forward-auth-cec.yaml (a template, not yet Flux-wired).