skip to content

Access and Refresh

The difference between an access token and a refresh token: what each is for, how long it lives, and what rotation costs a thief. Lifetime choices decide how bad a leak gets, so interviewers ask.

part ofOAuth 2.0overview, primer and where to startread it →
on this pageshow

questions

4

In OAuth 2.0, what is an access token for, and why does the authorization server issue a refresh token alongside it?

level: juniorimportance: must knowfreq 78%

answer

  1. two credentials, not one
  2. different destinations, different lifetimes
  3. one faces the API, one the issuer
  4. short life absorbs the leak risk
  5. a resource server never sees the refresh token

basics

~20 s

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

solid answer

~50 s

The two tokens have different jobs and different destinations. An **access token** is what the client presents to a **resource server** to make calls inside the granted `scope`; it is deliberately short-lived, so a copy that leaks stops working on its own. A **refresh token** is presented only back to the **authorization server**, at the token endpoint, and its only purpose is to obtain a new access token without sending the resource owner through an authorization step again. A resource server should never see a refresh token, and an access token is not the resource owner's password in another form: it names no password, is limited to the scope that was granted, and expires. Without the second token you would have to choose between an access token long enough to be dangerous and a user who is asked to authorize again every hour.

code

json · 7 lines
json
{
  "access_token": "2YotnFZFEjr1zCsicMWpAA",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
  "scope": "berths.read tides.read"
}

go deeper

for a junior

Recall the pair and their destinations: the access token goes to the API, the refresh token goes back to the authorization server. Say that the access token is short-lived on purpose.

for a middle

Explain why the split exists at all - one credential cannot be both short enough to limit a leak and long enough to avoid asking the resource owner again - and name the members of the token response.

for a senior

Show that you know what the pair does not give you: no proof of presence, no identity, and no statement of how long the refresh token itself will be honoured.

for a principal

Frame it as where risk is parked. The access token is the piece you are willing to lose; every decision about lifetimes, rotation and which clients get a refresh token at all follows from that placement.

## What an access token is An **access token** is a credential the **client** (the application) presents to a **resource server** (the API holding the data) to act on one slice of a **resource owner's** account. RFC 6749 describes it as a string representing an authorization issued to the client. Three properties matter more than its shape: - it is **scoped** - it carries only the permissions that were granted, not the account; - it is **time-limited** - it stops being accepted after its expiry; - it is **disposable** - throwing one away costs nothing, because it is not the resource owner's password and cannot be turned back into one. That is the whole reason delegated authorization is safer than handing an application a password: the application holds something narrower than the account, and something that dies on a schedule. ## Why a second token exists If the access token were the only credential, its lifetime would be a single, impossible compromise. Make it long and a leaked copy is useful to a thief for as long as it lives. Make it short and the resource owner is pushed through an authorization step every time it lapses, which is unusable for anything that runs in the background. The **refresh token** breaks that compromise in two. The short-lived access token absorbs the risk; the long-lived refresh token carries the **grant** - the resource owner's standing permission - and is spent only at the **token endpoint** to mint a replacement. The resource owner authorizes once; the client keeps working; a leaked access token still expires quickly. ## Where each one goes | | access token | refresh token | |---|---|---| | presented to | the resource server | the authorization server's token endpoint | | typical lifetime | minutes to about an hour | days or longer, and it may still carry an absolute or inactivity expiry | | what it buys | calls inside the granted scope | one replacement access token | | what a thief gains | the granted scope until it expires | the ability to keep minting access tokens until it is invalidated | | who validates it | the resource server | the authorization server that issued it | The row that candidates get wrong is the first one. A refresh token sent to a resource server is a mistake in two directions: the resource server has no way to use it, and the client has just handed its longest-lived credential to a party that was never meant to hold it. ## What the token response carries RFC 6749 section 5.1 defines the members the token endpoint returns: 1. `access_token` - required, the credential itself; 2. `token_type` - required, how the client is expected to present it; 3. `expires_in` - recommended, the access token's lifetime in seconds; 4. `refresh_token` - optional, issued at the authorization server's discretion; 5. `scope` - required only when what was granted differs from what was asked for. Notice what is absent: there is no member describing the refresh token's lifetime. Nothing in the response tells the client how long its refresh token will be honoured. ## The offline case that makes the split concrete Take a small marina's berth-holder application. A boat owner opens it on the pontoon to check tide times, then motors out and is off signal for six hours. When the phone reconnects, the access token it was holding is long dead - which is exactly what you wanted, because that phone has spent the afternoon in a wet pocket on a boat. The refresh token it also holds is still good, so the application silently obtains a new access token and the owner never sees a sign-in screen. One credential was built to expire; the other was built to survive the gap. ## What neither token proves - An access token proves that a **grant existed when it was issued**. It does not prove the resource owner is present now, or even still consenting. - Neither token says anything about who the human is; identity is a separate layer with its own token. - A refresh token is not a stronger access token. It buys nothing at a resource server, and an access token buys nothing at the token endpoint. Hold those three and the rest of the lifecycle - how long to make each one, what to ask for when you refresh, what rotation buys - follows from a split you can actually explain.

  • Does every OAuth 2.0 token response contain a refresh token?
    No. RFC 6749 makes `refresh_token` optional, and the authorization server decides whether to issue one for a given client and grant. A client that runs only while a person is watching it, and can simply ask again, may be given none at all - and an authorization server that judges a client too exposed to hold a long-lived credential can withhold it.
  • What does an access token prove about the resource owner at the moment it is used?
    Only that a grant existed when the token was issued. It says nothing about whether the resource owner is present, awake or still willing - they may have walked away hours ago, or changed their mind. That gap between consent and use is exactly why access-token lifetimes are kept short.
  • Why is an access token not simply the resource owner's password under another name?
    A password opens the whole account, everywhere, until it is changed, and it can be replayed to change itself. An access token carries only the scope that was granted, is accepted only by the resource servers it was issued for, expires on its own, and can be thrown away without the resource owner doing anything.

A crew pass that opens the pontoon gate until dusk, versus the berth agreement kept at the harbour office. You show the pass at the gate all afternoon; the agreement you present only at the office counter, and only to be issued another pass.

saying these in an interview costs you the question

  • Says the refresh token is sent to the API on every request
  • Treats an access token as the resource owner's password in another form
  • Describes a refresh token as just a longer-lived access token
  • Claims an access token proves the resource owner is present right now
  • Says one token would do if you simply made it last longer
  • Assumes every token response must include a refresh token
open as a page

In an OAuth 2.0 token response, what does expires_in describe, and how is an access-token lifetime chosen?

level: middleimportance: must knowfreq 60%

basics

~20 s

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

open as a page

When a client redeems a refresh token at the token endpoint, what may its scope parameter ask for?

level: middleimportance: should knowfreq 45%

basics

~20 s

Only scopes inside the grant the resource owner originally gave. RFC 6749 says the requested scope on a refresh MUST NOT include any scope not originally granted, and that omitting it is treated as asking for the original grant. A client may narrow, never widen.

open as a page

Refresh-token rotation is on, and a boat's phone that lost signal mid-refresh comes back signed out - what happened?

level: seniorimportance: should knowfreq 52%

basics

~20 s

The rotated refresh token reached the client's response but never arrived, so the phone replayed the old one. Rotation invalidates a refresh token as soon as it is used, and a replay of an invalidated token is read as a breach, so the authorization server revoked the active token and the grant had to be re-authorized.

open as a page