Skip to content

Instantly share code, notes, and snippets.

@cassc
Last active July 5, 2026 01:36
Show Gist options
  • Select an option

  • Save cassc/9fd002a9a4b4290449ca644d4db850eb to your computer and use it in GitHub Desktop.

Select an option

Save cassc/9fd002a9a4b4290449ca644d4db850eb to your computer and use it in GitHub Desktop.
oidc-mermaid.md

OIDC, OAuth, and OpenID — how they relate and how they work

The relationship

  • OAuth 2.0 — an authorization framework. It lets an app get a token to act on your behalf (e.g. "read my calendar"), without ever seeing your password. It says nothing about who you are.
  • OpenID / OpenID 2.0 — an older, separate authentication protocol (login only, no API access). Mostly dead now, replaced by OIDC.
  • OpenID Connect (OIDC) — an identity layer built on top of OAuth 2.0. It adds an ID token (a signed JWT saying who the user is) alongside OAuth's access token (which grants API access). This is why almost every "Login with Google/Microsoft/etc." today is OIDC, not old OpenID.

OIDC = OAuth 2.0 + a standard way to authenticate.

Key components

Role Description
Browser (resource owner) The user, acting through their browser
Client app The web/mobile app requesting login and access
Authorization server (IdP) Authenticates the user, issues tokens
Resource server The protected API the client calls with the access token

Token types

Token Who reads it Purpose
ID token Client app only Proves who the user is (JWT with sub, email, etc.)
Access token Resource server Grants API access — doesn't carry identity by itself

The ID token never leaves the client. Only the access token is forwarded to the resource server.

Architecture

                    ┌───────────┐
                    │  Browser  │
                    │ (resource │
                    │  owner)   │
                    └─────┬─────┘
                          │ login / redirect
                    ┌─────▼─────┐
                    │Client app │
                    │(web/mobile│
                    │   app)    │
                    └──┬─────┬──┘
       id token +      │     │     access token
       access token    │     │     only
              ┌────────▼┐   ┌▼────────────┐
              │Authoriz-│   │  Resource   │
              │ation svr│   │  server     │
              │ (issues │   │ (protected  │
              │ tokens) │   │ API)        │
              └─────────┘   └─────────────┘
  • Client ↔ Authorization server: gets ID token + access token
  • Client → Resource server: sends access token only
  • Authorization server and Resource server never talk directly (in the basic flow)

Full login sequence (Authorization Code flow)

Solid arrows = front-channel (through the browser, via redirects). Dashed arrows = back-channel (direct server-to-server, browser never sees these).

Browser        Client app        Auth server        Resource server
  │                │                   │                   │
  ├──clicks login─►│                   │                   │
  │                │                   │                   │
  │◄─auth redirect─┤                   │                   │
  │                │                   │                   │
  ├──────────────auth request─────────►│                   │
  │                │                   │                   │
  │◄─────────────login + consent───────┤                   │
  │                │                   │                   │
  │◄─────────────code returned─────────┤                   │
  │                │                   │                   │
  ├─callback(code)►│                   │                   │
  │                │                   │                   │
  │                ├╌╌tokens issued╌╌╌►│                   │
  │                │◄╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤                   │
  │                │  (id token +      │                   │
  │                │   access token)   │                   │
  │                │                   │                   │
  │                ├╌╌╌╌╌╌╌╌╌╌╌╌access token╌╌╌╌╌╌╌╌╌╌╌╌╌╌►│
  │                │◄╌╌╌╌╌╌╌╌╌╌╌╌╌protected data╌╌╌╌╌╌╌╌╌╌╌╌┤

Step-by-step

  1. Clicks login — Browser opens the client app.
  2. Auth redirect — Client redirects browser to the auth server's /authorize endpoint (includes scope=openid, state, and a PKCE code_challenge for public clients).
  3. Auth request — Browser lands on the auth server with the authorization request.
  4. Login + consent — User authenticates and approves access.
  5. Code returned — Auth server redirects browser back to the client's redirect_uri with an authorization code.
  6. Callback (code) — Browser delivers that code to the client app.
  7. Tokens issued (back-channel) — Client exchanges the code for tokens at the /token endpoint (using client_secret or PKCE code_verifier). Auth server returns both the ID token and access token.
  8. Access token (back-channel) — Client calls the resource server's API with Authorization: Bearer <access_token> — the ID token is not sent.
  9. Protected data — Resource server validates the access token and returns the data.

Security notes

  • state param — CSRF protection on the redirect.
  • PKCE (code_challenge / code_verifier) — required for public clients (SPAs, mobile apps) that can't hold a secret.
  • Client must validate the ID token's signature, iss, aud, exp, and nonce before trusting it.
  • Resource server should only ever need to validate the access token — it shouldn't need to parse it as identity info.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment