Cargo A/C

JWKS Trust Model

Spokes validate cargo.ac-issued tokens against the auth.cargo.ac JWKS endpoint using asymmetric keys — no shared JWT secret is distributed.

Onboarding sequence

2/10 done
  • Record issuer reality (RULE A)

    Public auth domain (auth.cargo.ac) ≠ OIDC issuer. The issuer is whatever live discovery returns (backend host) and never changes — by design. JWT validation always uses the live-discovery issuer.

    Done
  • Affirm Cargo A/C as identity authority (RULE B)

    Cargo A/C owns the identity model; Supabase OAuth Server is only the current implementation. Nothing depends on Supabase-specific assumptions (OIDC Independence Trigger documented).

    Done
  • Provision confidential clients

    Register each client spoke as a confidential OAuth client (client_id + secret) with redirect_uri = {dataBackend}/auth/v1/callback. Deliver the secret out of band.

    In progress
  • Apply redirect allowlist

    Allowlist each spoke's branded {dataBackend}/auth/v1/callback. Legacy per-origin /auth/callback + /auth/silent are retired for client spokes.

    In progress
  • Apply Target Spoke Configuration

    Each spoke adds a Custom OIDC Provider 'custom:cargo-ac' with Auto-discovery OFF, Issuer = exact live-discovery value (backend host, copied), and manual endpoints on auth.cargo.ac. Subject to Gate 2.

    In progress
  • Gate 1 — Endpoint validation (pilot)

    CargoWorks AI confirms authorize, token, userinfo, jwks.json and openid-configuration all work through auth.cargo.ac. If any fails, temporarily use the issuer-host endpoint until Supabase clarifies.

    Planned
  • Gate 2 — Provider compatibility (pilot)

    CargoWorks AI verifies the spoke honors Auto-discovery OFF + manual Issuer/Authorization/Token/Userinfo/JWKS. If any setting is ignored or discovery is forced, rollout PAUSES for architecture review.

    Planned
  • Gate 3 — Token claims validation (pilot)

    Confirm username, cargo_account_number, identity_type, user_type, permissions[], orgs[], active_org, app_roles, amr, scope are present after login, refresh, refresh-rotation and org switch — and reachable by spoke RLS. Missing claims = failed migration.

    Planned
  • Gate 4 — First spoke cutover

    Only after Gates 1–3 pass: promote Target → Permanent Spoke Configuration and cut the pilot to production. Then roll out the rest of the ecosystem on the identical model.

    Planned
  • Hub spoke registration

    admin.cargo.ac sends 1-min heartbeats to the CW Network hub; connectivity shown live in the footer.

    In progress

Key handling

  • • auth.cargo.ac signs tokens with private keys; spokes only ever fetch public keys from JWKS.
  • • No shared secret is distributed — there is nothing to leak from a spoke.
  • • Spokes cache JWKS and verify tokens locally; rotation is picked up via the kid header.

Rotation is non-disruptive

Publishing a new signing key alongside the old one lets spokes validate both during the overlap window — no coordinated sign-out across surfaces.