Module 1 — OAuth & OIDC Foundations
Learning objectives
- Explain why OAuth 2.0 exists and name the actors in a flow.
- Distinguish an access token from an ID token and say what each is for.
- Explain what a scope is and how it limits a token.
The problem OAuth solves
Before OAuth, apps asked users for their password and stored it. That’s a disaster: every app becomes a place your password can leak, and you can’t revoke one app without changing your password everywhere.
OAuth 2.0 replaces “give the app your password” with “the app gets a token, issued by a trusted authorization server, that grants limited access for a limited time.” Faable Auth is that authorization server, for your tenant.
OpenID Connect (OIDC) is a thin layer on top of OAuth that adds authentication — a standard way to answer “who is this user?” — via the ID token.
The actors
| Actor | In Faable terms |
|---|---|
| Resource Owner | The end user signing in. |
| Client | Your application (a Client you register in the dashboard). |
| Authorization Server | Faable Auth — at https://<tenant>.auth.faable.link. |
| Resource Server | A backend API that accepts access tokens (an API / audience). |
The two tokens (do not confuse them)
This is the single most common source of integration bugs.
- ID token — “who the user is.” A JWT with identity claims (
sub,email,name,nonce,auth_time). It is for your app to read. Never send it to an API as authorization. Defined by OIDC. - Access token — “what the bearer may do.” Sent to a resource server in the
Authorization: Bearer …header. Itsaud(audience) says which API it’s for, and itsscope/permissionssay what it may do there. Your app should treat it as opaque and just forward it.
There’s also the refresh token — a long-lived credential used to get new access tokens without making the user log in again (covered in Module 3).
Rule of thumb: read the ID token to know your user; send the access token to call APIs. If you’re putting an ID token in an
Authorizationheader, stop — you want the access token.
Scopes
A scope is a string that narrows what a token can do, e.g. openid, profile,
email, or an API permission like read:users. The client requests scopes; the
server issues a token containing only the scopes it’s willing to grant.
openidis what turns an OAuth request into an OIDC request (you get an ID token).profile/emailadd standard claims, exposed via UserInfo and filtered per scope.- API scopes (Module 5) gate access to your own backends.
Why JWTs
Faable signs tokens as JWTs (RS256). A JWT has three parts —
header.payload.signature — base64url-encoded and dot-separated. Anyone can read
the payload (it’s not encrypted), but only Faable can sign it. Resource servers
verify the signature against Faable’s public keys, published at the
JWKS endpoint (/.well-known/jwks.json), and discovered via
/.well-known/openid-configuration.
⚠️ Because the payload is readable, never put secrets in token claims, and never paste a real token into an online decoder — decode locally.
Check yourself
- Your SPA calls your own
/api/ordersbackend. Which token goes in theAuthorizationheader? - What does adding
openidto the requested scopes change about the response? - True/false: a resource server needs to call Faable on every request to verify a token.
Answers
- The access token (with an
audfor your orders API). - You get back an ID token — the request becomes an OIDC authentication, not just an OAuth authorization.
- False. It verifies the JWT signature locally using Faable’s published JWKS public keys; no per-request call to Faable is needed.