Mermaid code
sequenceDiagram
actor U as User
participant C as Client app
participant AS as Authorization server
participant RS as Resource server
U->>C: Click "Sign in"
C->>C: Generate code_verifier and code_challenge
C->>AS: GET /authorize with code_challenge
AS-->>U: Login and consent screen
U->>AS: Approve
AS-->>C: Redirect to callback with code
C->>AS: POST /token with code and code_verifier
AS->>AS: Verify challenge matches verifier
AS-->>C: access_token and refresh_token
C->>RS: GET /me with Bearer access_token
RS->>RS: Validate signature and scope
RS-->>C: 200 profile JSON
C-->>U: Signed in Paste this into any tool that renders Mermaid, or into the editor to change the theme and export PNG or SVG. Syntax reference: Sequence Diagram guide.
What this diagram shows
Four lanes: the User (drawn as a stick figure with actor), the Client app, the Authorization server, and the Resource server. The client generates a code_verifier and sends its hashed code_challenge with the authorize request. After login and consent, the server redirects back with a one-time code. The client exchanges that code together with the original verifier for tokens, and the server checks that the verifier hashes to the challenge it saw earlier. Only then does the client call the resource server with a bearer token.
Self-messages (C->>C, AS->>AS) mark the two PKCE steps, which is a useful convention: anything that happens inside one party without a network call gets a loop-back arrow.
How to adapt it
- Replace
/mewith the first protected endpoint your app calls after sign-in so the diagram ends on something concrete. - Add a
Note over C,AS: state parameter prevents CSRFto document thestatecheck if your reviewers ask about it. - Insert an
altafter the token request for theinvalid_granterror path when the code has already been used or has expired. - Remove the two self-messages if you are documenting a confidential client that uses a client secret instead of PKCE, and add
client_secretto the token request.
FAQ
Why does the user lane use actor instead of participant?
actor draws a stick figure, which makes the human visually distinct from the three systems. It is purely cosmetic; messages work the same way.
Where does the refresh token flow go?
In a separate diagram. Refresh happens later and repeatedly, so mixing it into the initial sign-in sequence makes both harder to read. The JWT example on this site covers refresh in detail.
How do I show the redirect through the browser explicitly?
Add a participant B as Browser lane between the user and the client, and route the /authorize request and the callback through it. For a single-page app the browser and the client are the same lane.