Skip to content

OAuth2 and BFF patterns

Token endpoint grants, authorization code flow hooks, and backend-for-frontend considerations.

Intended audience: Stakeholders, Business analysts, Solution architects, Developers, Testers

Learning outcomes by role

Stakeholders

  • Understand OAuth and BFF patterns as the supported browser login approach.

Business analysts

  • Describe consent, redirect, and token handoff flows for UX specs.

Solution architects

  • Design PKCE, cookie boundaries, and reverse-proxy rules for auth endpoints.

Developers

  • Implement Nuxt or other BFF clients following the documented sequence.

Testers

  • Automate authorization code, refresh, and negative OAuth cases.

OAuth2 is how browsers and mobile apps sign users in and obtain access and refresh tokens; a BFF (backend-for-frontend) keeps secrets off the device and forwards Bearer tokens to Cadence. Test plans should cover redirect URLs, consent, and token expiry; implementation detail lives in the OAuth2 token endpoint and authorization server grant logic.

  • UX versus security — Users expect SSO-style flows; the BFF pattern avoids putting client secrets in the browser bundle.
  • Compliance — Token lifetimes and consent screens are part of your audit story for interactive access.
  • Flows — Document redirect chains, consent screens, and error pages for each OAuth grant you enable.
  • Environments — Separate OAuth client registrations per environment so staging callbacks never hit production URLs.
  • Cadence exposes /oauth2/* and related routes (see cadence.api.oauth2); the BFF exchanges codes and stores refresh tokens server-side.
  • Redis still backs interactive Bearer sessions after token exchange (jti rows), consistent with JWT sessions.

Interactive clients need standard login and token exchange without embedding long-lived secrets in JavaScript. Cadence implements OAuth2-style endpoints so your SPA or mobile app can use authorization code + PKCE (or password/refresh grants where appropriate) while the API continues to authorize requests with Bearer JWTs backed by Redis sessions.

sequenceDiagram
  participant Browser
  participant BFF as BFF server
  participant Cadence as Cadence API
  participant Redis as Redis
  Browser->>Cadence: GET /oauth2/authorize
  Cadence->>Browser: Redirect with code
  Browser->>BFF: Callback with code
  BFF->>Cadence: POST /oauth2/token
  Cadence->>Redis: session / code storage
  Cadence->>BFF: access + refresh tokens

Cadence exposes OAuth2-style endpoints under /oauth2/* and OIDC discovery at /.well-known/openid-configuration. POST /oauth2/token switches on grant_type and calls the matching handle_*_grant helper.

grant_typePurpose
passwordResource-owner password (validated via AuthService / user repo); requires OAuth2 client credentials when clients are registered.
refresh_tokenRotates access + refresh via AuthService.refresh (see JWT sessions).
authorization_codeExchanges a one-time code from the consent redirect for tokens; uses session_store.consume_oauth2_code and optional PKCE code_verifier.

Unknown grants return 400 unsupported_grant_type.

Authorization code flow (browser-friendly)

Section titled “Authorization code flow (browser-friendly)”
  1. Client redirects user to GET /oauth2/authorize with client_id, redirect_uri, scope, state, optional PKCE code_challenge.
  2. After login/consent, user is redirected back with a code (stored briefly in Redis via store_oauth2_code).
  3. BFF or confidential client calls POST /oauth2/token with grant_type=authorization_code, code, redirect_uri, client_id/client_secret, and code_verifier if PKCE was used.

Related routes: /oauth2/consent/*, /oauth2/userinfo, POST /oauth2/revoke, POST /oauth2/introspect — see the Security and access API table.

TopicRule
SecretsNever ship client_secret in a browser bundle — exchange codes on a server-side BFF or use public clients with PKCE only when your model allows it.
TransportCadence expects Bearer access tokens on API calls; a BFF often stores refresh in http-only cookies and attaches access to upstream requests.
CORSSet CADENCE_CORS_ORIGINS for browser origins calling the API directly (see application entry and CORS configuration).
  • Grant support is fixed to the three types above; extension grants return 400.
  • Token and consent behavior depends on Redis for sessions and OAuth artifacts; broker/DB issues surface as 401/invalid_grant style errors from domain services.