Refresh token¶
A refresh token renews an access token while the person is elsewhere (RFC 6749 §6). The client spends it at
the token endpoint with grant_type=refresh_token, and it is the only client that can: a refresh token is
issued to one client and refused to every other. What a refresh token is, how long it lives and everything
that ends one are on refresh tokens; this page is the request.
When a client gets one¶
Three grants issue refresh tokens: authorization code, device
code and backchannel authentication. Their answer carries
one when the client is registered for refresh_token, and either:
offline_accessis among the scopes of the authorization (OIDC Core §11), or- the client is confidential, whether it asked for
offline_accessor not.
So a public client gets one only by asking for offline_access, and a client registered for no
refresh_token gets none, whatever it asks for. The provider offers offline_access only while it is wired
with a grant that issues refresh tokens and a grant that spends them, and a client asks for it as for any
other scope, among the ones it registered.
The request¶
| Parameter | |
|---|---|
grant_type |
refresh_token |
refresh_token |
Required |
scope |
Optional: a subset of the scopes of the refresh token, for this answer only (RFC 6749 §6) |
resource |
Optional and repeatable: a subset of the resources of the authorization, for this access token only (RFC 8707 §2.2) |
authorization_details |
Optional: a subset of the details of the authorization, for this access token only (RFC 9396 §7) |
The client authenticates beside them with the method it registered.
What is checked¶
In this order. The first five refusals are invalid_grant, all with the one description The refresh token
is invalid.:
- The token is one this provider issued, to the client that authenticated, and it has not been revoked.
- It has not been replaced. A token that was rotated and is presented again is a reuse
(RFC 9700 §4.13.2): its whole family is revoked, the successor the client holds included, and the act
refresh_token.reuse_detectedis written in the journal of the person. - The session it descends from has not ended. A session that merely expired does not stop a refresh,
renewing while the person is away being what the token is for; a session that ended does, however it
ended, and the act
refresh_token.outlived_its_sessionis written. - It has not expired. Its own lifetime never reaches past the absolute lifetime of its family.
- A token bound to a key or to a certificate is refreshed by a request that proves that key or presents that certificate again (RFC 9449 §5, RFC 8705 §4).
scopenames nothing the token does not carry:invalid_scopeotherwise. Ascopethat is not a list of scope tokens isinvalid_scopetoo, before the token is even looked up.resourceandauthorization_detailsnarrow and never widen:invalid_targetandinvalid_authorization_detailsotherwise.
Rotation¶
A refresh token is replaced where nothing else tells it from a copy of itself (RFC 9700 §4.13.2). Three things can: the authentication of a confidential client, the key or the certificate the token is bound to, and rotation. One is enough, so the provider rotates exactly where the other two are missing:
| The client | Its refresh token |
|---|---|
| Confidential | Stands. The answer carries no refresh_token, and the client keeps the one it holds until it expires |
| Public, the token bound to a DPoP key or to a certificate | Stands, for the same reason |
| Public, the token bound to nothing | Rotates. The token presented is marked replaced, and the answer carries its successor |
A successor belongs to the same family. It carries the whole authorization, whatever this request narrowed
for its access token, and what the session had proven when the authorization was granted. Its own lifetime,
tokens.refresh_token_ttl, starts at the rotation and never reaches past the end of the family. The act
refresh_token.rotated is written in the journal of the person.
What the answer carries¶
- An access token, bound to what this request binds it to and not to what bound the request that obtained the refresh token (grants): a confidential client whose tokens are bound to its certificate, and whose certificate was renewed, gets tokens bound to the new one.
- An ID token when
openidis among the scopes of the answer. It describes the same authentication as the first one, the sameauth_time,acrandamr, and it carries nononce, the refresh having none to carry (OIDC Core §12.2). - A refresh token when the token rotated, and only then.
A client takes a refresh token back itself at the revocation endpoint (RFC 7009 §2.1), which revokes that token and removes the opaque access tokens of its grant. Introspection and revocation describes the endpoint.