Access Token: Concept, Purpose, Way It Works
Find out what the access token is and what purpose it has. Check how to acquire an access token and how to use it.
What Access Token Is
The access token is a piece of code used for authenticating the client application to access specific resources on the resource owner's behalf. The access token represents the client's authorization to access a specific resource. Access tokens can be provided as JSON Web Tokens (JWTs) or opaque tokens, which are passed over HTTPS so that they are secure in transit.
Access Token Usage
The access token is used by the client application for making API calls to access specific resources on behalf of their owner. Which particular resource the client can access is determined by scopes included in the token payload. A token with relevant scopes attached allows the client to access a specific resources and/or perform particular actions.
Access Token Structure
The authorization server can return the access token to the client either as a random string with authorization information attached or in the form of a self-encoded token, which is a string that contains all the required data encoded in itself (with no other properties attached). JWT is an example of the self-encoded token.
The access token, specifically JWT for the purpose of this article, consists the header, the payload, and the signature. Within its three components, the self-contained access token carries information using so called claims). Claims are asserted attributes describing the resource owner, privileges, groups, token type, token expiration, encoding algorithm, and more.
Read More
For details on the structure of the access token in the form of JWT, see JWT structure.
Signing Algorithms
The signing algorithm is used to sign tokens generated for an application or API. A signature is the final component of JWT, which enables validating that the information has not been modified along the way.
There are a few signing algorithms that are recommended for access-token purposes:
HS256 (HMAC with SHA-256): Hash-Based Message Authentication Codes (HMACs) enables signing messages with a shared key. They use a cryptographic hash function (for example, SHA256). Forgery resilience of HS256 depends on the hashing algorithm used. HS256 is a symmetric algorithm with only one private key that is kept secret, shared between the two parties, and used both to create and verify the signature. The key is issued while registering an application (client secret) or API (signing Secret) with the HS256 algorithm. A major drawback of this approach is that if the key gets compromised, you need to generate another one (redeploy your application/API).
RS256 (RSA (Rivest–Shamir–Adleman) Signature with SHA-256): RS256 is asymmetric, that is, uses two different keys: the public key and the private key (that needs to be kept secret). One party (SecureAuth) signs a JWT with its private key. The other party (client application) validate the JWT with the public key of the sending party. The receiver cannot create a new JWT with the sender's public key.
Benefits of Using RS256
Ability to verify or decrypt a token with no possibility to create a new one: Only the owner of the private key (SecureAuth) can sign a token, but all the parties with the public key can verify the validity of the token.
Validity for multiple parties (in possession of the public key)
Possibility to use the key rotation in case the private key gets compromised (no need to re-deploy the application/API with a new secret)
ECDSA (Elliptic Curve Digital Signature Algorithm): Like RSA, ECDSA is an asymmetric encryption and digital signature algorithm. It differs from RSA in speed and the size of the key. With a smaller key, ECDSA can achieve the same security level as RSA. At the same time, ECDSA tends to be slower than RSA.
Access Token Scope
In the context of requesting the access token, scope
is an optional request body parameter. Its value holds name(s) of specific scope(s) granted to the client by the resource owner.
"scope" : "scope_1 scope_2 scope_n"
For example:
"scope" : "openid profile email"
Conceptually, the scope is to restrict the range of the requested access to particular areas only. The scope can be used as an access-control attribute that indicates what resources the client application is allowed to access.
Read more: Access token scope
Note
It's considered a good practice to limit the scopes the client application can request. It is done by providing the scopes to be requested as the value of the scope
parameter. Then, the client application requests only the scopes that it needs. When no scopes are provided with the scope
parameter, the client application receives access to all scopes.
How it works
Access Token Request
There are a few methods to acquire an access token. Each of them has its corresponding authorization grant flow: Authorization code grant (the client application calls the token endpoint including an authorization code in the request), Client credentials, and more.
Access Token Response
Authorization server returns the access token to the client application by means of the access token response.
Example of the Access Token Response
This particular response includes the bearer
type of the access token, which is typically a string of characters. The bearer format allows alphanumeric characters and punctuation marks -._~+/
.
HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"dB_8.C4f-3.1KwL", "token_type":"Bearer", "expires_in":5700, "refresh_token":"rHsv3JOkF0XG5Qx2TlTROL" "scope":"update" }
Authorization Properties
On top of the access token, the response from the server to the client needs to include properties regarding the authorization, such as token_type
, expires_in
, scope
. To prevent the request from being cached, the following headers are also required: Cache-Control: no-store
and Pragma: no-cache
.
Access Token Applied
The client application calls an API with the access token provided from the authorization server.
Depending on whether you want to call SecureAuth admin APIs or SecureAuth system APIs, you need the admin access token or the system access token, respectively.
Time to Live (TTL)
TTL specifies how long a particular token is valid, that is, can be used to access APIs.
In SecureAuth, there are TTLs for access tokens predefined per workspace (authorization server). Depending on the workspace type, different TTLs are used as defaults, for example, TTLs in the Open Banking workspace are typically shorter than in the other ones. You can modify TTLs by entering a particular workspace and navigating to Workspace settings > Tokens > Time to Live Settings > Access token TTL.
The recommended approach for configuring TTLs of tokens is the use of short-lived access tokens and long-lived refresh tokens.
In this scenario, an authorization server generates access tokens that are valid for a few hours or so. While issuing an access token, the server creates also a refresh token, which is sent in the same access token response to the client. When the access token gets invalid, the client uses the refresh token to acquire a new access token, which happens without the user's involvement.
In SecureAuth, there are TTLs for refresh tokens predefined per workspace (authorization server). You can modify them by entering a particular workspace and navigating to Workspace settings > Tokens > Time to Live Settings > Refresh token TTL.
Access Tokens vs Cookies
Typically, web applications consuming APIs support the token-based authentication, while web APIs (traditional server-side applications) support the cookie-based authentication.
The cookie-based authentication uses cookies to authenticate the client requests and keep session information on the server over HTTP. The cookie-based authentication is stateful: The user's state and the session record are maintained both on the server and on the client end. The server needs to keep a record of active sessions in a database and a cookie is produced to hold a session identifier.
The token-based authentication is stateless: The user’s state is stored on the client, not the server. The server does not keep track of logged-in users or issued JWTs. Requests to the server come along with tokens, which the server uses to verify the legitimacy of the requests.
SecureAuth uses the token-based authentication, which is a widespread standard nowadays due to its statelessness (backend offload) and scalability. This approach allows for a self-reliant comprehensive cross-domain processing of authorization requests.
Access Token Best Practices
Keep the signing key secret and reveal it only to services that require it.
Exclude sensitive data from the payload: Tokens are signed but can be decoded.
Use as few claims as possible: In the payload, add required claims only to optimize performance and security.
Set the expiration time for tokens and make sure their signing keys are revokable.
For more information, see Manage signing keys
Send tokens over HTTPS connections (encrypted channels).
Reduce and reuse: To minimize your application's attack surface, keeps the communication and information exchange that it's involved in at the absolute minimum. Save access tokens acquired from the authorization server for future use until they expire. Instead of requesting a new token, use a stored one.
Use refresh tokens, which allow the client to acquire new access tokens from SecureAuth with no need to request the user to sign in again.
Validate your JWTs with middleware or an open source third-party library.
Make an assumption that there can be multiple signing keys in your JWKS (for example, due to rotating signing certificates). Cache your signing keys to optimize the application performance and keep your rates low.