Authentication Flow Diagram
The exact token exchange between browser, application, authorisation server and API — including what is short-lived, what is bound and what never touches the browser.
sequenceDiagram autonumber participant B as Browser participant A as App / BFF participant I as Identity Provider participant R as Resource API B->>A: GET /protected A-->>B: 302 to IdP (PKCE challenge, state, nonce) B->>I: authorise request I->>B: authenticate + MFA I-->>B: 302 back with authorisation code B->>A: code + state Note over A,I: back channel — browser never sees these A->>I: exchange code + PKCE verifier + client secret I-->>A: access token (10 min), refresh token, id token A->>A: store tokens server-side<br/>set HttpOnly SameSite cookie A-->>B: session cookie only B->>A: subsequent request + cookie A->>R: call with access token (Bearer) R->>I: fetch/refresh signing keys (JWKS, cached) R->>R: verify signature, issuer, audience,<br/>expiry, scope R-->>A: 200 A-->>B: rendered response Note over A,I: on expiry the BFF refreshes<br/>with rotating refresh token
What it is
The authorisation code flow with PKCE, drawn with the back channel marked. The design decision the picture is making is that tokens never reach the browser: the server-side component holds them and the browser gets an HttpOnly cookie, which removes the entire class of token-theft-via-script.
Every arrow is a place something can go wrong, which is why this is worth drawing rather than describing.
When you produce it
Whenever authentication is being designed or changed, and whenever integrating with a partner's identity provider — the mismatch is usually in expectations about token lifetime, audience and refresh behaviour.
Who reads it
Engineers on both sides of the exchange. Security reviewers, who check the flow choice against the client type. Partner integration teams.
What good looks like
- The flow matches the client type: authorisation code with PKCE for browsers and mobile, client credentials for machine-to-machine. Implicit flow is deprecated and should not appear.
- Token lifetimes are on the diagram.
- Validation steps at the API are enumerated — signature, issuer, audience, expiry, scope. Audience is the one most often skipped and it is what stops a token for one API being replayed at another.
- Refresh token rotation and reuse detection are shown.
- Logout and session revocation are addressed, not just login.
Common mistakes
- Access tokens in localStorage, readable by any injected script.
- Skipping audience validation, so any valid token from the issuer works everywhere.
- Long-lived access tokens to avoid implementing refresh.
- Only drawing login. Expiry, refresh, revocation and logout are where the bugs are.