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:
- ADR-027: Superset Embedding Strategy (Phase 8.5)
- Phase 8.5 W1 checkpoint report at
powerfill-phase-8-5-w1-checkpoint - 2026-04-19 PSX → PSSaaS Superset embedding pattern relay (this request inherits its Q3 architectural-mismatch correction):
2026-04-19-psx-superset-embedding-relay
Why this exchange is archived (in advance of close)
Three reasons this relay gets archived even before PSX Infra's response lands:
- 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."
- 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.
- 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
| Field | Value |
|---|---|
| Realm | pss-platform (the existing realm at https://auth.powerseller.com) |
| Client ID | pssaas-app (analog of PSX's existing docs-proxy static-site client; please confirm no name collision) |
| Client type | OpenID Connect, confidential (NOT public — oauth2-proxy needs client_secret for server-side OIDC code exchange) |
| Standard flow enabled | Yes |
| Direct access grants enabled | No |
| Service accounts enabled | No |
| Valid redirect URIs | https://pssaas.staging.powerseller.com/oauth2/callback |
| Web origins | + (single plus = same as redirect URIs) |
| Client authentication | client-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-appthat emitstenant_id: ps-demodataas 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:
| # | Check | Why it matters | If not set |
|---|---|---|---|
| 1 | FEATURE_FLAGS["EMBEDDED_SUPERSET"] = True | Embedded 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. |
| 2 | TALISMAN_ENABLED = False (or equivalent CSP frame-ancestors allow) | Default Superset CSP blocks all framing. | iframe never renders. |
| 3 | HTTP_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. |
| 4 | GUEST_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. |
| 5 | PUBLIC_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
- Apply the filled
oauth2-proxy-secrets.yaml(locally, NOT committed) - Re-trigger GHA
deploy-staging(or rolling-restart oauth2-proxy manually) to load the Secret - Run the cross-boundary cutover verification recipe (per AGENTS.md):
curl -I https://pssaas.staging.powerseller.com/app/→ expect HTTP 302 to Keycloak logincurl -I https://pssaas.staging.powerseller.com/api/health→ expect HTTP 401curl -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
- Bilateral check from your side (per the recipe): Keycloak admin shows the
pssaas-appclient + the OIDC flow tracing for one full login cycle shows the expected redirect chain - 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_secretdeferred to env-from-Secretinfra/azure/k8s/pssaas-staging/services.yaml—oauth2-proxyDeployment + Service + ConfigMap;secretKeyRefpointing at the Secret you (PSX Infra) will indirectly populateinfra/azure/k8s/pssaas-staging/oauth2-proxy-secrets.yaml.example— TEMPLATE; the filled version is uncommitted + locally appliedinfra/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-appclient_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.pyderivative (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
containerRefpolling — 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)
- Superset admin credentials for the .NET guest-token-mint endpoint — Phase 8.5 W3's
SupersetGuestTokenClientcalls 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 aspssaas-secretskeysSUPERSET_ADMIN_USERNAME+SUPERSET_ADMIN_PASSWORD(we'll add thesecretKeyRefs toservices.yamlat W3 ship). - 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 iskubectl exec -n pss-platform deploy/superset -c superset -- python /tmp/register-powerfill-embeds.pyafterkubectl cpof the script — same pattern as PSSaaS'sdeploy-powerfill.pyfrom Phase 8 W1. - 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-platformnamespace 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.