Skip to content
Free lab

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.

0sPro

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)

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.

human signing inyes — a user authenticates
can hold a secretno — public client
browser on deviceyes
proposed / todayImplicit
Grant

#2

iOS consumer mobile app

Mobile

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.

human signing inyes — a user authenticates
can hold a secretno — public client
browser on deviceyes
proposed / today—
Grant

#3

Orders → Inventory microservice call

Service

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.

human signing inno — machine only
can hold a secretyes — confidential client
browser on deviceno — input-constrained
proposed / today—
Grant

#4

Smart-TV streaming app

TV / IoT

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.

human signing inyes — a user authenticates
can hold a secretno — public client
browser on deviceno — input-constrained
proposed / today—
Grant

#5

Nightly data-sync cron job

Service

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.

human signing inno — machine only
can hold a secretyes — confidential client
browser on deviceno — input-constrained
proposed / today—
Grant

#6

Android consumer app

Mobile

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.

human signing inyes — a user authenticates
can hold a secretno — public client
browser on deviceyes
proposed / today—
Grant

#7

Server-rendered web app (confidential)

Web server

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.

human signing inyes — a user authenticates
can hold a secretyes — confidential client
browser on deviceyes
today (no PKCE)auth code, missing PKCE
Grant

#8

Developer CLI on a laptop

CLI

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.

human signing inyes — a user authenticates
can hold a secretno — public client
browser on deviceyes
proposed / today—
Grant

#9

Legacy first-party web login

Web server

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."

human signing inyes — a user authenticates
can hold a secretyes — confidential client
browser on deviceyes
proposed / todayROPC
Grant

#10

CLI on a headless remote server

CLI

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.

human signing inyes — a user authenticates
can hold a secretno — public client
browser on deviceno — input-constrained
proposed / today—
Grant

#11

Partner API scheduled integration

Service

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.

human signing inno — machine only
can hold a secretyes — confidential client
browser on deviceno — input-constrained
proposed / today—
Grant

#12

Game-console companion app

TV / IoT

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.

human signing inyes — a user authenticates
can hold a secretno — public client
browser on deviceno — input-constrained
proposed / today—
Grant

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 active
adversary kill-chain1/4
idp-eng-rao18%
platform-kim16%
appsec-dana2%
idp-eng-you (you)0%

adversary staging…

TL;DR

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.

🎉 New here? Use code WELCOME10 for 10% off any plan at checkout
OAuth Flow Lab — Free Interactive OAuth 2.0 Grant Trainer · PlayCISO