December 04th, 2019
Firefox Accounts uses a number of different types of "token" to keep track of whether a user has been authenticated, and of what actions a client is authorized to perform. This document provides an overview of the different types of token, their properties and intended uses.
The most important types of token for FxA Replying Parties to know about are:
- Session Tokens, long-lived tokens that represent an authenticated user session with the FxA servers.
- OAuth Refresh Tokens, long-lived tokens indicating that the user has authorized a particular client to perform particular actions on their behalf.
- OAuth Access Tokens, short-lived tokens used by authorized clients when performing particular actions on behalf of the user.
- OIDC Identity Tokens, short-lived JWTs used to communicate an authentication event from FxA to a relying party.
FxA has additional types of token that it uses for its own account-management purposes, but which should never be visible to Relying Parties:
Relying Parties that wish to integrate with Firefox Sync may also need to know about these additional types of token:
Token Usage Mechanisms
A Bearer Token is an opaque string that can be used by any client in posession of the token, simply by presenting
it verbatim in the request to the server (e.g. in the
Authorization header). These are the simplest types of token
for clients to use, but allow for interception and replay attacks. In particular, the server that receives a Bearer Token
is capable of extracting it and using it to perform other API calls.
A Hawk Token consists of an opaque string id and corresponding secret key. To use the token, clients must use the secret key to sign outgoing requests using the scheme described here. This is more complicated for clients but it binds the use of the token to the particular request being made, and it offers the potential for replay prevention.
An FxA Hawk Token is a 32-byte string from which the id and key of a Hawk Token can be generated using HKDF. This simplifies client handling of the token since it only has to persist a single value.
sessionToken is the Firefox Accounts equivalent of traditional website login session cookie - it represents
the user who is currently signed in to accounts.firefox.com, and it used to authenticate many calls from the
FxA front-end website to the FxA back-end API.
Session tokens are an FxA Hawk Token where the 32-byte string is generated by the server. They can be obtained by:
- The successful creation of a new account, via the
- A successful login to a new account, via the
- Duplicating an existing
sessionToken, via the
- Providing the id of a previous
sessionTokenwhen changing the account password, via the
- Requesting the
https://identity.mozilla.com/tokens/sessionscope during an OAuth flow.
Session tokens are intended only for authenticated communication with the FxA servers themselves, so RP servers should never encounter a session token in the wild.
On the client side, session tokens are typically handled by web content on accounts.firefox.com while the user is interacting with their account. However, web browsers that support signing in with FxA in order to access account-enabled browser features, may obtain a session token during the sigin flow and use it to communicate directly with the FxA server APIs.
Since session tokens represent a signed-in user, the server maintains a lot of additional metadata about the user's signed-in state. Properties of the session token include:
- The types of authentication performed by the user, and level of confidence in their identity.
- Timestamp at which authentication last occurred (which can be increased by prompting the user to re-enter their password).
- Timestamp at which the token was last used (truncated to a few hours granularity to reduce db write load).
- Details of the user-agent string from the last use of the token.
- The geolocation of the IP address that requested the session token
This information may be used by the FxA server to make authorization decisions, and RPs may request that a user be authenticated to a certain level of assurance (such as requiring that the sessionToken be last-authenticated within a certain amount of time, or authenticated via 2FA).
As an additional security measure against credential-stuffing attacks, FxA has the notion of a "verified session", which is intended to indicate a higher level of confidence in the authenticity of the user.
A session is considered verified if the user did some additional authentication step in addition to proving knowledge of the account password, such as completing an email confirmation loop or answering a 2FA challenge. Sessions may also be considered verified based on server-side heuristics, such as whether the account is newly-created or whether we've seen previous verified logins form the same IP address.
Certain actions on the account can only be performed with a verified session, including:
- Modifying email or 2FA settings
- Authorizing OAuth grants that involve key-bearing scopes
If the user enables two-step authentication on their account, then each sessionToken will keep track of whether it has been involved in a successful 2FA authentication. This information is reported in the session metadata in two ways:
- The "authenticator assurance level" or "AAL" is a numeric indicator of the number of distinct types of
authentication factor that have been provided for a session; it will be
2for sessions in which the user has successfully successfully performed 2FA.
- The "authentication methods" is a list of all the different types of authentication action that have been performed on this session (such as "entered password" or "completed email loop" or "provided totp code"). It's a more detailed view than the summary provided by the AAL.
OAuth Refresh Tokens
RPs that wish to obtain long-lived permission to access the user's account data should request an OAuth Refresh Token as part of their authorization flow. This is a long-lived Bearer Token that represents the permissions granted by the user to that RP. For example the refresh token might indicate that the RP has permission to read the user's profile data.
Refresh tokens can only be created by authorizing them via a valid
Refresh tokens should only ever be presented to the FxA auth/oauth server, and should not be used when talking to other resource servers. Instead, the RP should use the refresh token to generate a short-lived [access token][#oauth-access-tokens] and use that to communicate with resource servers.
OAuth Access Tokens
RPs that wish to access resource servers on behalf of the user (say, to read or store user data) need to obtain an OAuth Access Token. This is a short-lived Bearer Token that represents the permissions granted by the user to that RP, in a format that can be consumed by resource servers. For example the RP might use an access token with scope "profile" in order to read the user's profile data from the FxA profile server.
FxA also supports JWT Access tokens. See JWT Access Tokens for an in-depth look at that less-commonly-used type.
OIDC Identity Tokens
They're for signin.
This token, a JWT, proves that a user's been authenticated (in this case,
with FxA). It can also be used as the
id_token_hint query param value in a
prompt=none flow (additional information]).
This token is issued along with the access token and refresh token when the scope "openid" is present.
They're for fetching keys. RPs shouldn't need to now this, because they use the scoped-keys flow.
Password Change Tokens
Special-use token for changing password. Hawk token.
Password Forgot Tokens
Special-use token for resetting password. Needs to be verified via a code received over email. Limited number of verification attempts. Generates a reset token.
Account Reset Tokens
Special-use token for resetting the password.
Legacy identity assertion format. Used by sync, and accepted when granting OAuth tokens, but should not be used for anything new.
BrowserID stopped being used in Firefox 80 and we're eagerly awaiting the long tail of users to upgrade so we can remove this code. See details in Issue #9007 / FXA-2715.