Module 09 Lesson 3 of 6 🕑 ~60 min

> cat module-09-3-oauth-oidc.md

OAuth & OpenID Connect

OAuth is one of the most widely misunderstood technologies in IT. It is primarily an authorisation framework, not an authentication protocol — OpenID Connect is what adds identity on top of it. This lesson untangles both, plus the tokens (access, refresh, ID, JWT) that flow between them.

1 OAuth & Its Roles

Authentication becomes more complex once multiple systems are involved — an employee, an application, an identity provider, an MFA provider, and a directory might all sit in the same login chain. Protocols like OAuth, OpenID Connect, SAML, Kerberos, LDAP and RADIUS let those components talk to each other. Understanding which problem each one solves is critical.

OAuth lets an application obtain limited access to another service without ever seeing the user's password. Without delegated authorisation, an app wanting access to your cloud drive would have to ask "Give me your username and password" — clearly dangerous. With OAuth:

Application
    ↓
Redirect user to identity/authorisation service
    ↓
User authorises requested permissions
    ↓
Application receives token
    ↓
Application uses token

The application never touches the password.

OAuth roles

Resource Owner
The entity that owns or controls the data — usually the user.
Client
The application requesting access.
Authorisation Server
Authenticates the user and issues tokens.
Resource Server
The API or service holding the protected resource.

Example mapping: User (Resource Owner) · Mobile App (Client) · Identity Platform (Authorisation Server) · Email API (Resource Server).

2 Authorization Code Flow & PKCE

The Authorization Code flow is one of the most important OAuth flows in practice.

OAuth Authorization Code flow with an animated token travelling between client, authorization server and resource server Client App Authorization Server Token Endpoint Resource Server / API 1. Redirect + login 2. Auth code 3. Exchange code 4. Access token 5. Bearer token → API

1–2: user authenticates, client gets a short-lived authorization code. 3–4: client exchanges the code for tokens at the token endpoint. 5: client calls the API with the access token.

The application then calls the protected API using the access token as a bearer credential:

Authorization: Bearer <access_token>

PKCE

PKCE (Proof Key for Code Exchange) protects the Authorization Code flow against interception. The client generates a temporary code_verifier, derives a code_challenge from it, and sends the challenge with the initial request. When exchanging the authorization code, the client provides the original verifier, and the authorisation server checks the two correspond. PKCE matters most for mobile apps and browser-based clients, where safely storing a traditional client secret is difficult.

3 Machine-to-Machine & Legacy Flows

OAuth Client Credentials flow

OAuth can also authenticate applications rather than users — no human involved:

Payroll Service
       ↓
Client ID + credential
       ↓
Authorization Server
       ↓
Access Token
       ↓
HR API

Commonly called machine-to-machine (M2M) authentication — common in microservices, backend APIs, automation, cloud services, and DevOps integrations.

Legacy OAuth flows

You should recognise older approaches because they still turn up in enterprise environments: the Implicit flow and the Resource Owner Password Credentials flow, where an application directly collects the user's username and password:

User
 ↓
Username/password
 ↓
Application
 ↓
Authorization server

This conflicts with the modern principle of keeping applications out of the business of handling user credentials. Modern architectures prefer browser-based redirection and stronger authentication — but legacy systems may still use these flows, and being a security engineer often means understanding both what should be deployed today and what already exists in production.

4 Tokens: Access, Scope & Refresh

An access token represents permission to access a resource — for example, allowing read user profile and read email but not change password or delete account. Because access tokens are frequently sent as bearer tokens, anyone possessing an unrestricted one can use it while it remains valid — they need strong protection.

Token scope

Scopes describe the permissions an application is requesting, e.g. profile.read, email.read, payments.read, payments.write. An application should receive only what it needs — least privilege applied to tokens. A reporting application might need payments.read but should never automatically receive payments.write.

Refresh tokens

Access tokens normally have short lifetimes. When one expires, a refresh token lets the client request a new one without forcing the user through a full login again:

Login
  ↓
Access token + Refresh token
  ↓
API calls
  ↓
Access token expires
  ↓
Refresh token → Token endpoint
  ↓
New access token

Refresh tokens are extremely sensitive — if an attacker steals one, they may retain access far longer than a single access token would allow.

Access TokenRefresh Token
Used against APIsUsed against the token endpoint
Usually shorter lifetimeOften longer-lived
Represents accessUsed to obtain new access
Frequently sentUsed less frequently
Exposure permits immediate API accessExposure can enable longer-term persistence

5 JWT

OAuth and OpenID Connect frequently use JSON Web Tokens, though OAuth doesn't strictly require every token to be a JWT. A JWT commonly looks like xxxxx.yyyyy.zzzzz — three parts, Header.Payload.Signature. Example decoded payload:

{
  "iss": "https://identity.example.com",
  "sub": "123456",
  "aud": "payments-api",
  "exp": 1780000000,
  "scope": "payments.read"
}

Common claims: iss = issuer, sub = subject, aud = audience, exp = expiration, iat = issued at.

Applications must not simply decode a JWT and trust its contents — they must validate it: signature, issuer, audience, expiration, algorithm, and required claims. A token can claim "role": "administrator", but that means nothing until its cryptographic authenticity is verified.

6 OpenID Connect & Single Sign-On

OpenID Connect (OIDC) adds an identity layer on top of OAuth:

OAuth = Delegated authorisation
OpenID Connect = Authentication / identity, built using OAuth mechanisms

OIDC is one of the most common technologies behind modern web Single Sign-On.

ID tokens

The ID token describes the authenticated user and the authentication event:

{
  "iss": "https://login.example.com",
  "sub": "248289761001",
  "aud": "application123",
  "name": "Alice Smith",
  "email": "alice@example.com"
}
ID Token
Answers "Who authenticated?" — used by the client application.
Access Token
Answers "What API access has been authorised?" — used against resource servers.

Do not treat these as interchangeable — a common mistake even among working developers.

OpenID Connect login flow

User → Application → Redirect to Identity Provider
  → Password / FIDO / MFA → Authentication successful
  → Authorization code → Application
  → Token exchange → Token Endpoint
  → ID Token + Access Token + Refresh Token → Application

The application establishes a local session after validating the required tokens.

Single Sign-On

SSO lets a user authenticate once and access multiple connected services — sign into the corporate Identity Provider, and Microsoft 365, Salesforce, ServiceNow, Workday and internal apps all become reachable without re-authenticating. SSO improves user experience, but it also concentrates risk: if an attacker compromises the central identity session, multiple applications may become accessible at once. This is exactly why identity providers are among the most security-critical services in an enterprise.

Lab Lab 1 – Watch an OIDC Flow in DevTools

🦡 Hands-on lab

Open your browser's developer tools (Network tab) and authenticate to any test application that uses OIDC login. Watch the sequence of requests.

🔮 Predict first, then verify

Before you look: what do you expect to see between the "Log in" click and landing back on the app — a redirect to an identity provider domain, a GET /authorize request, or something else? Then check the actual request URLs, status codes, redirects, cookies, and any code= parameter in the callback URL.

Reveal what to look for

You should see a redirect away to the identity provider's domain, a GET /authorize request carrying client ID and redirect URI, a login/consent step, then a redirect back to your application's callback URL carrying an authorization code (e.g. ?code=abc123). Do not expose real production tokens while doing this — the goal is to see that authentication is a sequence of ordinary HTTP transactions, not a magic login box.

Lab Lab 2 – Decode a JWT

🦡 Hands-on lab

Take a JWT created specifically for this lab (never a real production token) and split it on the two . characters into header, payload and signature.

🔮 Predict first

Base64-decode the payload. Who issued this token? Who is the subject? Which API should accept it? What permissions does it contain? When does it expire?

Reveal the key point

Decoding a JWT is not the same as validating a JWT. Anyone can Base64-decode the visible header and payload of most JWTs — that's not a security feature, it's just an encoding. Real security comes entirely from verifying the cryptographic signature and required claims (issuer, audience, expiration) against a trusted key, which is exactly what a naive "just decode it" approach skips.

Lab Lab 3 – Access Token vs Refresh Token in Practice

🦡 Hands-on lab

Using a sample OAuth/OIDC client (many identity platforms provide a free sandbox or "try it" tool), authenticate and capture both tokens. Let the access token expire, then use the refresh token to request a new one.

🔮 Predict first

Which token would cause more damage if stolen: the access token or the refresh token? Why?

Reveal the reasoning

Generally the refresh token, because of its longer lifetime and its ability to mint new access tokens repeatedly. A stolen access token is dangerous but self-limiting once it expires; a stolen refresh token can let an attacker keep generating fresh access tokens well beyond that window, which is exactly why refresh tokens require stronger protection (Lesson 6 covers session and token revocation in more depth).

Lesson Outcome

You should now be able to explain that OAuth is an authorisation framework, OpenID Connect adds authentication on top of it, and walk through the Authorization Code + PKCE flow, the Client Credentials (M2M) flow, and the difference between access, refresh and ID tokens. Lesson 4 covers SAML — the older, XML-based federation standard that still runs a huge share of enterprise SSO — and how it compares to OIDC.