OAuth Flow Lab
The wrong OAuth grant is how tokens get stolen. Work a queue of real app profiles — a SPA, a mobile or native desktop app, a CLI, a smart TV, a backend service — and pick the correct grant for each: Authorization Code + PKCE for an interactive user on a public client, Client Credentials when no user is involved, the Device Authorization Grant when the user is on a browserless device. Retire the implicit and resource-owner password grants on sight — OAuth 2.1 removed both — and add PKCE where an authorization-code client is missing it.
The real job. More noise, a tighter clock.
Flow selection
For each app, pick the correct OAuth 2.0 grant. Retire the deprecated ones; add PKCE where it is missing.
#1
React single-page app (SPA)
A browser-only React app with no backend of its own. Users log in to reach their dashboard. The client ships as JavaScript, so any "secret" is readable in dev tools.
#2
iOS consumer mobile app
A native iOS app where users sign in to their account. The binary is distributed through the App Store, so any embedded secret can be extracted.
#3
Orders → Inventory microservice call
The Orders backend calls the internal Inventory API every time an order is placed. There is no end user in this path — it is one service acting as itself.
#4
Smart-TV streaming app
A living-room TV app. The user needs to sign in to their account, but the only input is a D-pad remote — no usable browser, no real keyboard.
#5
Nightly data-sync cron job
A scheduled job runs at 02:00 with no one logged in, pulling records from a partner API into the warehouse. It runs on a locked-down server that can hold a secret in a vault.
#6
Android consumer app
A native Android app. Users authenticate to access their profile. Distributed via Play Store; the APK is decompilable, so no secret is safe in it.
#7
Server-rendered web app (confidential)
A traditional server-side web app (Node/Rails) with its own backend. Users log in; the app already runs the authorization-code flow with a client secret — but WITHOUT a PKCE code challenge.
#8
Developer CLI on a laptop
A command-line tool run on a developer workstation that HAS a desktop browser. On `login` it can spin up a temporary listener on 127.0.0.1 and open the browser to the authorization endpoint.
#9
Legacy first-party web login
An older in-house web app shows its own username/password form and posts the credentials to the IdP token endpoint with the resource-owner password grant, because "it is our own app and our own users."
#10
CLI on a headless remote server
The same CLI, but run over SSH on a headless box with no desktop and no browser. The engineer is present at their own laptop, but the machine running the tool cannot open a browser or receive a loopback redirect the user can see.
#11
Partner API scheduled integration
Our backend calls a partner’s REST API on a fixed schedule to push catalog updates. The partner issued us a client ID + secret for our organization. No individual user is represented.
#12
Game-console companion app
A console app where the player signs into their account to sync saves. Input is a game controller; there is no comfortable browser or keyboard on the device.
Right flow, no retired grants
Decide each app, then grade. So far 0/12 decided, 0/12 on the right grant, 0 deprecated pick(s).
The three questions
Is a human authenticating? No → Client Credentials.
Can the device open a browser? No (but a user is present) → Device Code.
Otherwise → Authorization Code + PKCE (PKCE on every auth-code client, confidential ones too).
Implicit and resource-owner password are deprecated by OAuth 2.1 — never correct.
Live arena
4 activeadversary staging…
What this lab is
- A free, browser-based OAuth 2.0 lab: read a queue of real app profiles — SPA, mobile, native desktop, CLI, smart-TV/IoT, backend service — and pick the correct grant for each.
- The only ever-correct answers are Authorization Code + PKCE (interactive user, public client), Client Credentials (no user, service-to-service), and the Device Authorization Grant (user present but the device has no browser).
- You retire the deprecated grants on sight: the implicit grant and the resource-owner password credentials grant, both removed by OAuth 2.1 — and you add PKCE where an authorization-code client is missing it.
- Scoring rewards the right grant everywhere and takes an extra penalty for reaching for a deprecated flow, because a retired grant is the one that actually gets tokens stolen.
- Harder tiers add the subtle calls: device code vs client credentials when a user is on a browserless device, loopback PKCE vs device code for a CLI, and PKCE on confidential clients too.
Frequently asked questions
What is the OAuth Flow Lab?
A free, in-browser exercise where you work a queue of app and integration profiles — a single-page app, a mobile app, a desktop app, a command-line tool, a smart TV, a backend service — and choose the correct OAuth 2.0 grant for each one. The choices are Authorization Code with PKCE, Client Credentials, the Device Authorization Grant, and the two deprecated grants (implicit and resource-owner password) that you must learn to never pick. You are scored on choosing the right modern grant for every case.
How do I know which grant is right?
Three questions decide almost every case. Is a human interactively authenticating? If no, it is Client Credentials (a service authenticating as itself). If yes, can the device drive a browser? If no, it is the Device Authorization Grant (the user finishes on a phone against a code). Otherwise it is Authorization Code with PKCE — which, under OAuth 2.1, applies to every authorization-code client, including confidential server-side apps that also hold a client secret.
Why are the implicit and password grants always wrong?
Both were deprecated by OAuth 2.1. The implicit grant returns access tokens in the redirect URL fragment with no proof-of-possession, so they leak through browser history, logs and referrers and cannot be refreshed safely — Authorization Code with PKCE replaces it. The resource-owner password grant has the client collect the user password directly, which bypasses the identity provider login and therefore cannot do MFA, SSO, passkeys or risk-based step-up, and it trains users to type passwords into app forms. There is a modern replacement for every legitimate use of each.
Does it talk to a real authorization server?
No. Nothing is sent anywhere, no tokens are issued and no cryptography runs. The scenarios are authored, realistic app profiles bundled with the page, each with one correct grant and a written explanation revealed after grading. It runs entirely in your browser — no account, no install.
Who is it for?
Developers wiring up OAuth/OIDC, platform and identity engineers reviewing how apps authenticate, and anyone prepping for a security or IAM interview who wants the grant-selection decision to become automatic: public client versus confidential, user present versus machine-only, browser-capable versus input-constrained, and modern versus retired.