OAuth 2.0
Delegated authorization: the four parties, the grant flow a client picks, and the scoped token a resource server accepts. Asked because most teams wire it up without saying what it delegates.
on this pageshowhide
guide
overview
~1 minOAuth 2.0 is a delegation protocol. It lets a person give an application limited access to an account held somewhere else without handing that application their password: the application ends up holding a token that says what it may do, where, and for how long. Interviewers probe it because almost every team wires it up, and far fewer can say exactly what was delegated, to which party, and what an attacker gains when a code or a token escapes. A strong answer names the party, the credential it holds, and the attack each step of the flow is there to stop. The hub splits into four sections. [Core framework](/topics/proto-oauth2-framework) is the vocabulary everything else assumes: the four roles, client types and how a client proves itself, endpoints and discovery metadata, scopes and consent, and what OAuth 2.1 took out. [Delegation flows](/topics/proto-oauth2-grants) is how permission is actually obtained — the code exchange with its proof key, redirects for native apps, the device grant, token exchange and signed or pushed requests. [Token lifecycle](/topics/proto-oauth2-token-lifecycle) follows a token after it is issued: refreshing it, asking about it, revoking it and binding it to a key. [Attack surface](/topics/proto-oauth2-attack-surface) gathers the scenarios where real integrations break. Junior rounds stay on who does what and why the browser takes a detour through the authorization server. Senior and principal rounds turn into threat-model conversations: which parameter defends against which attacker, how a leak is contained, how an estate moves off retired grants without breaking partners. Learn the roles and client types first, then walk the authorization code flow end to end until it is second nature. Tokens and attacks read far better once that one flow is solid.
primer
### Delegation, not login OAuth answers one question: may this client call that API on this person's behalf, within these limits? It does not tell the client who the person is: an access token is addressed to a resource server and carries permission, not identity. Sign-in is a separate layer built on top, usually OpenID Connect, and confusing the two leads straight to designs that treat any valid token as a login. ### Every credential stays with the party that needs it The **resource owner**, the **client**, the **authorization server** and the **resource server** each hold different secrets. In the flows used today the person's password is typed only on the authorization server's pages, the client's credentials are shown to nobody but the authorization server, and the access token travels between client and API. Most questions in this hub reduce to "who holds what, and who else can see it on the way". ### Front channel and back channel Anything carried by a browser redirect is exposed to whatever touches the browser — history, logs, extensions, referrer headers, other apps on the phone. A direct HTTPS call from client to token endpoint is not. OAuth's answer is to put only a short-lived, single-use artefact on the front channel and redeem it on the back channel. **PKCE**, `state`, exact redirect matching and issuer checks are all ways of hardening that front-channel leg. ### The client type decides what can be trusted A **confidential client** runs on a server and can keep a secret or a private key. A **public client** — a single-page app, a mobile app, a CLI — cannot, so no protection may rest on its secret. That distinction decides how the client authenticates, how its refresh tokens are guarded, and why proof keys matter so much. ### The grant follows from who is present - A person at a browser: the **authorization code** grant with PKCE. - A person, but a device with no usable browser: the **device authorization** grant. - Nobody but the client itself: **client credentials**. - One service calling another on a user's behalf: **token exchange**. The implicit and password grants are retired because each put a credential somewhere it could leak. ### A token is scoped, short-lived and containable **Scope** limits what a token allows, **audience** limits where it is accepted, and expiry limits how long. By default a token is a **bearer** credential — whoever holds it can spend it — so a senior answer is about containment: short lifetimes, revocation, rotation, and binding tokens to a key only the client holds.
- Resource owner
- The person, or occasionally a system, that owns the protected data and can grant a client access to part of it.
- Client
- The application requesting access on the resource owner's behalf. It is a role, not a device: a web backend, a mobile app or a daemon can each be one.
- Authorization server
- The party that authenticates the resource owner, records consent, and issues codes and tokens through its authorization and token endpoints.
- Resource server
- The API holding the protected data. It accepts access tokens, checks them, and enforces the scope and audience they carry.
- Confidential client
- A client able to keep credentials secret, typically server-side code, so it can authenticate itself at the token endpoint.
- Public client
- A client whose code runs where users can inspect it, such as a browser app or installed app, so it cannot hold a secret.
- Authorization code
- A short-lived, single-use value returned through the browser after consent, which the client redeems at the token endpoint for tokens.
- Access token
- The credential a client presents to a resource server. It represents a granted scope, for a limited time, usually for a particular audience.
- Refresh token
- A longer-lived credential, presented only to the authorization server, that obtains new access tokens without sending the user through consent again.
- Scope
- A string naming a slice of access the client requests. The authorization server defines the vocabulary and may grant less than was asked.
- Redirect URI
- The client-hosted address the authorization server sends the browser back to with the response. It must be registered in advance.
- PKCE
- Proof Key for Code Exchange: the client commits to a secret when it starts the flow and reveals it when redeeming the code.
- state
- A per-request value the client generates and checks on the callback, tying the response to the browser session that started the flow.
- Sender-constrained token
- An access token bound to a key the client holds, via DPoP or mutual TLS, so a stolen copy is useless without that key.
- Authorization server metadata
- A JSON document published at a well-known URL listing an authorization server's issuer, endpoints and supported features.
- Introspection
- An endpoint where an authorized resource server asks the authorization server whether a token is currently active and what it grants.
- Token exchange
- A token-endpoint grant that trades one token for another, narrowed to a new audience, for delegation or impersonation between services.
Follow one authorization code flow and the rest of the hub attaches to it. The client reads the endpoint URLs from the server's metadata document, then sends the browser to the authorization endpoint with its client id, a registered redirect URI, the scopes it wants, a `state` value and a PKCE challenge. The authorization server authenticates the person and asks for consent; the browser comes back to the client's redirect URI carrying a code. The client then calls the token endpoint directly, authenticates itself if it is confidential, and redeems the code together with the PKCE verifier. It receives an access token, often a refresh token, and — when it differs from the request — the scope actually granted. ```http GET /authorize?response_type=code&client_id=shop-web&state=xyzABC &redirect_uri=https://shop.example/cb&scope=orders.read &code_challenge=E9Melhoa2Ow...&code_challenge_method=S256 HTTP/1.1 Host: as.example POST /token HTTP/1.1 Host: as.example Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&code=SplxlOBeZQ&client_id=shop-web &redirect_uri=https://shop.example/cb&code_verifier=dBjftJeZ4CVP... ``` The first request is front channel and public; the second is back channel. Every hardening measure in the hub lives on that seam: the challenge on the first request and the verifier on the second, `state` checked on the way back, the redirect URI matched exactly, the issuer confirmed before the code is spent. The other sections plug into the same frame: - **Other grants** replace the first leg: the device grant swaps the redirect for a code typed on a second screen, client credentials skips the person entirely, and token exchange starts from a token the caller already holds. - **Pushed and signed requests** move or protect the first leg's parameters so the browser cannot read or alter them. - **The token lifecycle** begins at the token response: resource servers validate tokens locally or through introspection, clients renew them with the refresh token, and revocation and key binding decide how far a leaked token reaches.
- Roles and Model →
The four parties and the credential each one holds; every flow and attack is described in these terms.
- Client Types →
Public versus confidential clients, and the ways a client authenticates, which decide what protections a flow can rely on.
- Grant Types →
Which grant fits which caller, and why two of the original grants were retired.
- Authorization Code + PKCE →
The authorization code flow as it is built today, with the proof key every client should send.
- Access and Refresh →
What access and refresh tokens are, how long they live, and how rotation limits a stolen refresh token.
- Redirect and Request Forgery →
The redirect and request-forgery scenarios interviewers use to test whether the flow is really understood.
Calling OAuth an authentication protocol: an access token says what a client may do at an API, not who signed in to the client.
Treating PKCE as a mobile-only extra: OAuth 2.1 expects it from every client using the code flow, confidential ones included.
Offering
stateas the defence against mix-up attacks: it ties a response to the browser session, not to the authorization server that sent it.Registering wildcard or prefix-matched redirect URIs for convenience, which lets a crafted request steer the code somewhere the client never intended.
Shipping a client secret inside a mobile app or single-page bundle and then counting it as client authentication.
Assuming revocation stops a self-contained access token everywhere at once; a resource server validating it locally keeps accepting it until it expires.
Designing one catch-all scope, so consent becomes all-or-nothing and no permission can be withdrawn on its own.
Recommending the implicit or password grant for a "simple" case; OAuth 2.1 drops both, and the code flow with PKCE covers those cases.
Turning on refresh-token rotation without planning for lost responses — see this rotation scenario.
OAuth 2.0 is not one document but a core plus extensions, and interviewers expect you to know which layer an answer comes from. This guide assumes a modern deployment: RFC 6749 as tightened by later security guidance, with OAuth 2.1 as the target shape. - **RFC 6749 and RFC 6750** (2012) define the core framework, the four original grants and bearer-token usage. - **RFC 7636** added PKCE, first aimed at native apps; **RFC 8252** set the rules for native-app redirects. - **RFC 8414** (metadata), **RFC 8628** (device grant), **RFC 8693** (token exchange) and **RFC 8705** (mutual-TLS client authentication and bound tokens) filled in discovery, constrained devices, service-to-service calls and key binding. - **RFC 9126** (pushed authorization requests), **RFC 9207** (the `iss` response parameter) and **RFC 9449** (DPoP) hardened the front channel and brought key binding to clients without mutual TLS. - **RFC 9700**, the OAuth security best current practice (2025), tells clients not to use the implicit grant, forbids the password grant, and tightens redirect and PKCE rules. **OAuth 2.1** folds the core and these hardening rules into one text rather than adding features. When an answer depends on which rules apply — whether PKCE is required, whether implicit is allowed — say whether you mean RFC 6749 as written or the current best practice.
OAuth sits in the middle of a family of standards, and interviewers expect you to place it among them. **OpenID Connect** is the identity layer built on OAuth: it adds an ID token that tells the client who signed in, which OAuth alone never does. **SAML** solves federated sign-in for enterprise applications with XML assertions and browser posts; it predates OAuth, was not designed for delegating API access, and remains common for enterprise single sign-on. **JWT** is a token format, not a protocol — OAuth access tokens are often JWTs but need not be, and opaque tokens checked by introspection are just as valid. Against simpler options, the trade is clear. **API keys** identify a calling application and suit server-to-server calls with no user involved, but they carry no user consent, no scope negotiation and no standard expiry. **Session cookies** remain the simplest way for a browser to stay signed in to its own backend; many teams keep the OAuth tokens on the server and give the browser only a session, rather than exposing tokens to page scripts. In practice teams run an existing identity provider rather than build an authorization server, so questions focus on integrating one safely.
explore
- Core Framework20 questions
- Roles and Model4 questions
- Endpoints and Metadata3 questions
- Client Types5 questions
- Scopes and Consent4 questions
- Version 2.1 Delta4 questions
- Delegation Flows28 questions
- Grant Types5 questions
- Authorization Code + PKCE5 questions
- Native and Browser Redirects5 questions
- Device Authorization4 questions
- Token Exchange4 questions
- Signed Request Objects5 questions
- Token Lifecycle12 questions
- Access and Refresh4 questions
- Introspection and Revocation5 questions
- Proof of Possession3 questions
- Attack Surface8 questions
- Redirect and Request Forgery5 questions
- Response Integrity3 questions
- GraphQLskillanchors this topic
- AI Red Teamingrole
- API Designskill
- Android Developerrole
- Backend Developerrole
- Cyber Security Expertrole
- DevSecOps Engineerrole
- Forward Deployed Engineerrole
- Frontend Developerrole
- Full Stack Developerrole
- Java Backend Developerrole
- Kotlin Backend Developerrole
- Software Architectrole
- iOS Developerrole
questions
68 · 4 sectionsIn OAuth 2.0, what makes a client confidential rather than public, and where does an installed mobile app fall?
basics
~20 sRFC 6749 section 2.1 types a client on one property: whether it can keep its credentials confidential. Server-side code can. An installed mobile app cannot, so it is public — a secret shipped inside it is readable by whoever installs it.
In OAuth 2.0, why is a client issued an access token instead of the resource owner's password?
basics
~20 sThe resource owner's password is a credential shared only with the authorization server, the party they already have an account with. That server authenticates the owner itself and issues the client a separate credential, an access token, which the resource server validates.
In OAuth 2.0, which four roles does RFC 6749 define, and what is each one responsible for?
basics
~20 sRFC 6749 defines four roles: the resource owner who grants access, the client that asks for it, the authorization server that authenticates the owner and issues an access token, and the resource server that holds the data and validates that token.
In OAuth 2.0, what does the `scope` parameter request, and how is its value formatted on the wire?
basics
~20 sThe scope parameter names the access a client is asking for, as a space-delimited list of case-sensitive strings the authorization server itself defines. Order carries no meaning; each string adds one more access range to the request.
In OAuth 2.0, how do client_secret_basic and client_secret_post differ, and which does RFC 6749 prefer?
basics
~20 sBoth carry the same client_secret to the token endpoint. client_secret_basic puts client_id and secret in an HTTP Basic Authorization header; client_secret_post puts them in the form body. RFC 6749 requires Basic support and marks the body form NOT RECOMMENDED.
Why does an OAuth 2.0 client send the user to the authorization server to log in and then back?
basics
~20 sThe authorization code grant keeps the resource owner's password at the authorization server. The user authenticates there, and the client receives only a short-lived authorization code, which it exchanges on a back channel for a scoped access token.
Why does RFC 8252 have a native mobile app open its OAuth 2.0 authorization request in the device's browser rather than an embedded web view?
basics
~20 sRFC 8252 keeps the authorization request in an external user-agent because an embedded web view runs inside the application: the application can observe what is typed into it, including the resource owner's credentials, and it shares no signed-in session with the browser.
In an OAuth 2.0 authorization-code flow, what attack does PKCE (RFC 7636) exist to stop?
basics
~20 sPKCE stops authorization-code interception. An attacker who captures the code as it travels back through the browser cannot redeem it, because the token request must also carry a code_verifier that only the application which started the flow holds.
What must a device-grant client do when the token endpoint answers slow_down, and what interval applies if none was sent?
basics
~20 sA slow_down answer means the client must add 5 seconds to its polling interval for this and every later request — a permanent increase, not a one-off pause. Where the response supplied no interval, the client must use 5 seconds.
How does a device with no browser redeem its device_code at the token endpoint, and with which grant_type?
basics
~10 sThe device POSTs to the token endpoint with grant_type set to urn:ietf:params:oauth:grant-type:device_code, plus its device_code and client_id. Until the user approves it gets an error response carrying authorization_pending, then a normal token response.
In OAuth 2.0, what is an access token for, and why does the authorization server issue a refresh token alongside it?
basics
~20 sAn access token is the short-lived credential a client presents to a resource server for one slice of an account. A refresh token goes only to the authorization server and buys a replacement access token when the access token expires.
In an RFC 7662 introspection response for an OAuth 2.0 access token, what does the `active` member assert?
basics
~20 sactive is the one REQUIRED member of an RFC 7662 introspection response, and a true value generally indicates that this authorization server issued the token, it has not been revoked, and the call falls inside its validity window.
In an OAuth 2.0 token response, what does expires_in describe, and how is an access-token lifetime chosen?
basics
~20 sexpires_in is the access token's lifetime in seconds, counted from when the response was generated - not an absolute time, and not a statement about the refresh token. The lifetime is chosen to balance how long a leaked token stays useful against how often clients must return to the token endpoint.
Under RFC 7009, what does revoking an OAuth 2.0 refresh token also invalidate, and how does revoking an access token differ?
basics
~20 sRevoking a refresh token SHOULD also invalidate every access token issued under the same authorization grant, where the server supports revoking access tokens at all. Revoking an access token only MAY take the matching refresh token with it.
What does an OAuth 2.0 client send to an RFC 7009 revocation endpoint, and what does a 200 answer mean?
basics
~20 sA revocation request is a form-encoded POST carrying the token parameter, an optional token_type_hint, and the client's own credentials. HTTP 200 means the token is no longer usable, and is also the answer when the submitted value was never valid.
Your app registers a callback URL with a partner authorization server; why must its redirect_uri match that registration exactly?
basics
~20 sExact string matching is what ties an issued authorization code to the application that asked for it. Any looser rule - prefix, substring or wildcard - lets an attacker steer the response to a destination the client never registered.
In an OAuth 2.0 authorization code flow, why is the callback URL the browser lands on treated as a secret?
basics
~20 sThe authorization response arrives as query parameters on that URL, and the code in it is a one-time credential redeemable at the token endpoint. Whatever copies the URL - an access log, browser history, a referring header - copies the credential.
What does the OAuth 2.0 `state` authorization-request parameter protect a client against, and what does it not prove?
basics
~20 sThe state parameter is an opaque value a client generates per authorization request, binds to that browser's session and checks on the callback. It rejects authorization responses the client never asked for. It proves nothing about which authorization server answered.
What makes a mix-up attack possible against a client that accepts logins from three partner authorization servers?
basics
~20 sA mix-up attack needs a client able to start flows at more than one authorization server. Nothing in a plain OAuth 2.0 authorization response names the server that produced it, so one server's response can be processed as another's.
Your client validates RFC 9207's iss authorization-response parameter whenever it is present - why is that not enough?
basics
~20 sAn attacker can simply omit the parameter. A client must record, per authorization server, whether that server returns iss, and reject a response from such a server when the parameter is missing as well as when it does not match.