Mermaid exampleSequence Diagram

JWT Authentication Sequence Diagram with Token Refresh

Most JWT bugs live in the refresh path: the client retries forever, the server accepts a revoked refresh token, or the two tokens have the wrong lifetimes. This diagram puts the happy path and both failure paths on one page, which is the version you want in the auth section of your API docs.

  • jwt sequence diagram
  • refresh token flow
  • access token expiry diagram
  • mermaid authentication diagram
JWT Authentication Sequence Diagram with Token RefreshResource APIAuth APIClientResource APIAuth APIClientalt[Refresh token valid][Refresh revoked or expired]alt[Token valid][Token expired]POST /login with email and passwordVerify password hashaccess_token (15 min) and refresh_token (30 days)GET /orders with Bearer access_tokenVerify signature and exp claim200 orders401 token_expiredPOST /refresh with refresh_tokenNew access_tokenRetry GET /orders200 orders401 reauthenticateRedirect to login
Open in editor → 23 linesrenders in GitHub, Notion, Obsidian

Mermaid code

sequenceDiagram
    participant C as Client
    participant A as Auth API
    participant R as Resource API
    C->>A: POST /login with email and password
    A->>A: Verify password hash
    A-->>C: access_token (15 min) and refresh_token (30 days)
    C->>R: GET /orders with Bearer access_token
    R->>R: Verify signature and exp claim
    alt Token valid
        R-->>C: 200 orders
    else Token expired
        R-->>C: 401 token_expired
        C->>A: POST /refresh with refresh_token
        alt Refresh token valid
            A-->>C: New access_token
            C->>R: Retry GET /orders
            R-->>C: 200 orders
        else Refresh revoked or expired
            A-->>C: 401 reauthenticate
            C->>C: Redirect to login
        end
    end

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

Three lanes: Client, Auth API, and Resource API. Login returns two tokens with their lifetimes written into the message. The resource API verifies the signature and the exp claim locally, with no call to the auth API, which is the main reason to use JWTs at all. The outer alt splits on token validity. Inside the expired branch, the nested alt splits again on whether the refresh token is still good: a new access token and a transparent retry, or a hard 401 that sends the user back to login.

How to adapt it

  • Change the lifetimes in the first response to your real values; the diagram is a good place to make the 15-minute and 30-day choice explicit.
  • Add A->>A: Rotate refresh token before issuing the new access token if you use refresh token rotation, and extend the else branch with the reuse-detection case.
  • Replace GET /orders with any protected call; keep the retry line so readers see that the client, not the user, handles expiry.
  • Add a Note over R: Public key cached from /jwks to show where the verification key comes from.

FAQ

Why does the resource API not call the auth API?

Because the JWT is self-contained: the signature and the exp claim are enough to accept or reject it. That is the trade-off against sessions, where every request would hit a store. Revocation before expiry needs a separate mechanism such as a short access token lifetime or a denylist.

How do I show the retry only happening once?

Sequence diagrams do not express counters, so write it in the message or a note: C->>R: Retry GET /orders (once). If retries loop, use a loop block with the limit in its label.