feat(dev-sso): bunyip-api as the OIDC OP for hub and mokosh SPA #66

Merged
longjacksonle merged 1 commit from feat/dev-sso-bunyip-as-op into main 2026-06-05 19:41:42 +02:00

What

Converges the reversed OIDC wiring documented in runbook 3.8 / scaffold step 8. In dev-sso, bunyip-api becomes the single OpenID Provider; bunyip-web (the hub) and the mokosh SPA are both relying parties of it, and mokosh-server runs as a Resource Server. This mirrors the working staging topology, where the SPA at msp.<tld> derives issuer api.<tld> = bunyip-api.

Why

dev-sso was the only environment still wired the old way (mokosh-server as IdP, an incomplete cutover), which is why SSO login was broken there while staging works. The fix is to make dev-sso match staging, not to finish the abandoned mokosh-as-IdP path.

Changes (this repo)

  • compose.dev-sso.yml: expose the OP (port 4401) on ${USER}-bunyip-api.a8n.run; because the api container now publishes two Traefik services (OCI registry + OP) each router names its service explicitly (else Traefik refuses to auto-link and both hosts 404). Set OP runtime env: OIDC_ISSUER (public host), BUNYIP_WEB_ORIGIN, COOKIE_DOMAIN=.a8n.run, CORS_ORIGIN for hub + SPA.
  • justfile: add register-dev-clients (upserts the hub + SPA public PKCE clients with per-${USER} redirect URIs, which cannot live in a committed migration).
  • runbook 3.8 / 4 / 8: rewritten to the converged flow.

Companion PRs

  • mokosh-server feat/dev-sso-rs-trust-bunyip (Resource Server env).
  • mokosh-apps feat/dev-sso-bunyip-issuer (SPA issuer).

Verification (scripted, end to end)

login -> PKCE authorize -> token at bunyip-api yields an at+jwt (iss=…bunyip-api, kid=dev-2026, aud=…mokosh-api). mokosh-server then returns 200 on GET /api/v1/auth/me, GET /api/v1/contacts/companies, and POST create-company with that token. The original "401 on create company" symptom is resolved.

🤖 Generated with Claude Code

## What Converges the reversed OIDC wiring documented in runbook 3.8 / scaffold step 8. In dev-sso, `bunyip-api` becomes the single OpenID Provider; `bunyip-web` (the hub) and the mokosh SPA are both relying parties of it, and `mokosh-server` runs as a Resource Server. This mirrors the working staging topology, where the SPA at `msp.<tld>` derives issuer `api.<tld>` = bunyip-api. ## Why dev-sso was the only environment still wired the old way (mokosh-server as IdP, an incomplete cutover), which is why SSO login was broken there while staging works. The fix is to make dev-sso match staging, not to finish the abandoned mokosh-as-IdP path. ## Changes (this repo) - `compose.dev-sso.yml`: expose the OP (port 4401) on `${USER}-bunyip-api.a8n.run`; because the api container now publishes two Traefik services (OCI registry + OP) each router names its service explicitly (else Traefik refuses to auto-link and both hosts 404). Set OP runtime env: `OIDC_ISSUER` (public host), `BUNYIP_WEB_ORIGIN`, `COOKIE_DOMAIN=.a8n.run`, `CORS_ORIGIN` for hub + SPA. - `justfile`: add `register-dev-clients` (upserts the hub + SPA public PKCE clients with per-`${USER}` redirect URIs, which cannot live in a committed migration). - runbook 3.8 / 4 / 8: rewritten to the converged flow. ## Companion PRs - mokosh-server `feat/dev-sso-rs-trust-bunyip` (Resource Server env). - mokosh-apps `feat/dev-sso-bunyip-issuer` (SPA issuer). ## Verification (scripted, end to end) login -> PKCE authorize -> token at bunyip-api yields an at+jwt (`iss=…bunyip-api`, `kid=dev-2026`, `aud=…mokosh-api`). mokosh-server then returns 200 on `GET /api/v1/auth/me`, `GET /api/v1/contacts/companies`, and `POST` create-company with that token. The original "401 on create company" symptom is resolved. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(dev-sso): make bunyip-api the OIDC OP for the hub and mokosh SPA
All checks were successful
Check / fmt / clippy / build / test (pull_request) Successful in 1m7s
Create release / Create release from merged PR (pull_request) Has been skipped
ce45c853ac
Converges the reversed OIDC wiring flagged in runbook 3.8 / scaffold step 8. bunyip-api becomes the single OpenID Provider in dev-sso (matching staging, where the SPA at msp.<tld> derives issuer api.<tld> = bunyip-api); bunyip-web and the mokosh SPA are both relying parties of it, and mokosh-server runs as a Resource Server validating the at+jwt bunyip mints.

Expose the OP (app port 4401) on its own per-developer Traefik host `${USER}-bunyip-api.a8n.run`. Because the api container now publishes two Traefik services (OCI registry + OP), each router names its service explicitly; without it Traefik refuses to auto-link and both hosts 404.

Set the OP runtime env on the api service: OIDC_ISSUER (the public host so discovery/authorize/token/jwks are browser-reachable, not localhost), BUNYIP_WEB_ORIGIN (the login UI the OP bounces unauthenticated authorize requests to), COOKIE_DOMAIN=.a8n.run (so the OP session set by bunyip-web's /login is sent back to the OP on the subsequent authorize), and CORS_ORIGIN allowing the hub + SPA origins.

Add `just register-dev-clients`: the committed seed migration registers the static staging hosts, but dev redirect URIs carry ${USER} and cannot live in a migration, so this recipe upserts the hub + SPA public PKCE clients against the running dev DB. Point bunyip-web at the new issuer in .env and refresh the runbook to the converged flow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
longjacksonle deleted branch feat/dev-sso-bunyip-as-op 2026-06-05 19:41:43 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
psa-systems/bunyip!66
No description provided.