Skip to main content

2026-04-20 PSSaaS → PSX Infra — Keycloak pssaas-app Client + Superset Embedding Pre-Flight Request (Phase 8.5 W1)

Date: 2026-04-20 Originating project: PSSaaS (request) Owning Collaborator: PSSaaS Collaborator (consumer of PSX Infra's response) Adoption status: OPEN — relay drafted by PSSaaS Architect at Phase 8.5 W1 ship; PO sends to PSX Infra; PSSaaS pauses Phase 8.5 W2-4 dispatch until response lands. Phase 8.5 W1 ships the manifests + config + GHA workflow that REFERENCE the artifacts requested below; the artifacts themselves (Keycloak client, Secret value, Superset config verification, PUBLIC_ROLE_LIKE pre-flip) are PSX-Infra-owned. Companion canonical sections:


Why this exchange is archived (in advance of close)

Three reasons this relay gets archived even before PSX Infra's response lands:

  1. The request shape itself is reusable. Phase 10+ will add new PSSaaS surfaces (Pipeline Management UI, Risk Manager UI) that each need their own oauth2-proxy + Keycloak client pair. This relay is the canonical template for "PSSaaS asks PSX Infra to provision a new Keycloak client + verify Superset embedding pre-flight."
  2. The five-item Superset-config-verification list is load-bearing. Per PSX Collab's gotcha #1 in the 2026-04-19 relay (PUBLIC_ROLE_LIKE silent no-op on existing Superset; half-day debug trap), these five checks done UPFRONT prevent the most-cost-likely failure mode for Phase 8.5 W2-4 smoke-test.
  3. The "what PSSaaS Architect committed without waiting for the response" honesty list mirrors the PSX Collab "what I am NOT providing" discipline shape banked from the 2026-04-19 exchange. Crisp inheritance-boundary signal.

Inbound (the request — to PSX Infra, brokered by PO)

PSSaaS Phase 8.5 Workstream 1 has shipped the PSSaaS-side manifests + config + GHA workflow for the new oauth2-proxy Deployment that fronts pssaas.staging.powerseller.com/app/ and /api/. The auth boundary is wired EXCEPT for two PSX-Infra-owned dependencies and three PSX-Infra-owned verifications.

Two artifact deliveries needed from PSX Infra

(1) New Keycloak confidential client pssaas-app in the pss-platform realm

FieldValue
Realmpss-platform (the existing realm at https://auth.powerseller.com)
Client IDpssaas-app (analog of PSX's existing docs-proxy static-site client; please confirm no name collision)
Client typeOpenID Connect, confidential (NOT public — oauth2-proxy needs client_secret for server-side OIDC code exchange)
Standard flow enabledYes
Direct access grants enabledNo
Service accounts enabledNo
Valid redirect URIshttps://pssaas.staging.powerseller.com/oauth2/callback
Web origins+ (single plus = same as redirect URIs)
Client authenticationclient-secret (delivered via your existing Vault → K8s Secret pattern)

Delivery shape: populate the client_secret into a K8s Secret named pssaas-oauth2-proxy-secrets in the pssaas-staging namespace (key client_secret, base64-encoded). The PSSaaS-side kubectl apply -f infra/azure/k8s/pssaas-staging/services.yaml references the Secret at deploy time; rolling restart picks it up automatically once the Secret exists.

PSSaaS-side template for the Secret manifest at infra/azure/k8s/pssaas-staging/oauth2-proxy-secrets.yaml.example — feel free to copy + fill + apply, OR use whatever your established pattern is for delivering secrets into the pssaas-staging namespace.

(2) Realm-side tenant_id claim mapper for the demo user

A68 (Phase 8.5 Workstream 4) inverts the PSSaaS TenantMiddleware so the OIDC tenant_id claim wins over the X-Tenant-Id header. Per PO disposition (defer canonical-identity convention to first-real-customer-onboarding; A68 long-term decoupling lands as code shape only at Phase 8.5; migration is no-op), we need:

  • One Keycloak realm-side mapper on pssaas-app that emits tenant_id: ps-demodata as a top-level claim on the access token
  • Applies to whichever Keycloak user(s) you provision for the Greg demo. If you already have a kevin@... or similar test user, that's the one
  • Mapper type: hardcoded claim (not user-attribute-sourced for v1; we're not yet a multi-tenant realm-config thing)

Three verifications on platform-Superset

Per ADR-027 D-8.5-5 + PSX Collab's 2026-04-19 reply (gotchas #1-#7), please verify the following on bi.staging.powerseller.com (now in pss-platform per Backlog #30 closure) and remediate if needed:

#CheckWhy it mattersIf not set
1FEATURE_FLAGS["EMBEDDED_SUPERSET"] = TrueEmbedded API endpoints don't exist without it. Likely already on (you use it for Principal).Phase 8.5 W2-4 dead-on-arrival — please flip on.
2TALISMAN_ENABLED = False (or equivalent CSP frame-ancestors allow)Default Superset CSP blocks all framing.iframe never renders.
3HTTP_HEADERS = {"X-Frame-Options": "ALLOWALL"} AND nginx-side X-Frame-Options does NOT override (PSX Collab gotcha #3 — your Superset nginx had to explicitly set X-Frame-Options to empty after a security-defaults update reintroduced DENY)Same as (2) but at the nginx layer.iframe blocked even with TALISMAN off.
4GUEST_TOKEN_JWT_SECRET set + stable (not rotated mid-session)PSSaaS guest-token mint relies on this signing key matching what Superset's /embedded/{uuid}/ endpoint validates with.Mid-session token invalidation; opaque "auth failed" errors.
5PUBLIC_ROLE_LIKE = "Gamma" actual-state-on-existing-DB (per PSX gotcha #1)This is a fresh-init-only config; on existing Superset (which platform-Superset is post-Backlog-#30), it silently no-ops. Embedded dashboards then fail with cryptic "embedded authentication" errors that don't point to the Public role being empty. The half-day debug trap.Pre-flip required: either run copy_gamma_to_public.py script (PSX has the canonical) OR manually grant Public role Gamma's permissions via Settings → Security → List Roles → Public → Edit.

If item #5 needs the copy_gamma_to_public.py script, please either run it or share the script (we can kubectl exec against the pss-platform-namespace Superset pod ourselves per the runbook).

What PSSaaS will do once this lands

  1. Apply the filled oauth2-proxy-secrets.yaml (locally, NOT committed)
  2. Re-trigger GHA deploy-staging (or rolling-restart oauth2-proxy manually) to load the Secret
  3. Run the cross-boundary cutover verification recipe (per AGENTS.md):
    • curl -I https://pssaas.staging.powerseller.com/app/ → expect HTTP 302 to Keycloak login
    • curl -I https://pssaas.staging.powerseller.com/api/health → expect HTTP 401
    • curl -I https://pssaas.staging.powerseller.com/docs/ → expect HTTP 200 (UNCHANGED)
    • Browser login flow end-to-end → expect post-login /app/ 200 with the React UI rendering
  4. Bilateral check from your side (per the recipe): Keycloak admin shows the pssaas-app client + the OIDC flow tracing for one full login cycle shows the expected redirect chain
  5. Dispatch Phase 8.5 W2 (embedded SDK) + W3 (.NET 8 guest-token-mint endpoint + per-dashboard registration script) + W4 (TenantMiddleware OIDC claim sourcing) per the Phase 8.5 plan

What PSSaaS Architect committed without waiting for the response (the honesty list)

Mirroring PSX Collab's 2026-04-19 "what I am NOT providing" discipline shape, here's what PSSaaS Architect committed in W1 BEFORE this relay's response lands — so the inheritance boundary stays crisp:

  • infra/oauth2-proxy/oauth2-proxy.cfg — the canonical PSSaaS oauth2-proxy config; client_secret deferred to env-from-Secret
  • infra/azure/k8s/pssaas-staging/services.yamloauth2-proxy Deployment + Service + ConfigMap; secretKeyRef pointing at the Secret you (PSX Infra) will indirectly populate
  • infra/azure/k8s/pssaas-staging/oauth2-proxy-secrets.yaml.example — TEMPLATE; the filled version is uncommitted + locally applied
  • infra/azure/k8s/ingress/pssaas-ingress.yaml — reconfigured to delegate /oauth2/, /app/, /api/ to oauth2-proxy:4180; /docs/ UNCHANGED (UNAUTH per kickoff non-negotiable)
  • .github/workflows/deploy-staging.yaml — added oauth2-proxy rolling-restart step with first-deploy-Deployment + Secret-existence guards (no-op until both exist)
  • docs-site/docs/handoffs/powerfill-phase-8-5-w1-checkpoint.md — plan-stage Architect Report at the W1 checkpoint per Reviewable Chunks

Note we are NOT committing:

  • The filled Secret manifest (gitignore-protected pattern)
  • The pssaas-app client_secret in any form (delivered via Vault → K8s Secret out-of-band)
  • The Keycloak realm-side mapper config (PSX-Infra-owned admin operation)
  • Any copy_gamma_to_public.py derivative (PSX-Infra-owned)

PSX Collab pairing offer (standing per the 2026-04-19 relay close-out)

If translation friction surfaces post-deploy on:

  • The 3-step Superset handshake (login → CSRF → guest_token POST) — FastAPI to .NET 8 + HttpClient
  • The iframe-sizing containerRef polling — PSX SupersetEmbed.tsx (Next.js) to PSSaaS EmbeddedDashboard.tsx (Vite)

PO can broker pairing. Phase 8.5 W2-4 dispatch will surface any of these as a separate exchange.


Open questions (for PSX Infra)

  1. Superset admin credentials for the .NET guest-token-mint endpoint — Phase 8.5 W3's SupersetGuestTokenClient calls Superset's /api/v1/security/login + /api/v1/security/csrf_token + /api/v1/security/guest_token. PSX uses what credentials for their FastAPI service? Same admin user as the dashboard registration script? Service account? We need a username/password (or service account) that PSSaaS API calls into Superset with for the server-to-server handshake. Please deliver as pssaas-secrets keys SUPERSET_ADMIN_USERNAME + SUPERSET_ADMIN_PASSWORD (we'll add the secretKeyRefs to services.yaml at W3 ship).
  2. Per-dashboard registration script invocation pattern — PSSaaS will write infra/superset/register-powerfill-embeds.py (PSX has no reference per the 2026-04-19 honesty list). Confirm the runbook is kubectl exec -n pss-platform deploy/superset -c superset -- python /tmp/register-powerfill-embeds.py after kubectl cp of the script — same pattern as PSSaaS's deploy-powerfill.py from Phase 8 W1.
  3. Anything else from the 2026-04-19 relay's 8 ranked gotchas that's worth pre-mitigation we're missing? Especially anything PSX hit on post-Backlog-#30 platform-Superset that's specific to the new pss-platform namespace deployment shape.

Cross-references

  • Triggers Phase 8.5 W1 → W2-4 sequencing per the Phase 8.5 plan
  • Inherits framing from ADR-027 D-8.5-1 through D-8.5-5
  • Inherits PSX Collab's authoritative file paths from 2026-04-19-psx-superset-embedding-relay
  • AGENTS.md cross-boundary cutover verification recipe (banked 2026-04-19) is the post-response verification template

PSSaaS Architect Phase 8.5 W1 dispatch, 2026-04-20. PO sends; PSX Infra responds; PSSaaS Architect resumes W2-4 once response received.