Access Token
An access token is used by a client to access protected resources. It is issued by one of the various grants of /token, which is the last step of the Authentication and Authorization process.
An access token is short-lived, typically valid for 10 minutes. It may be used as required until it expires. After expiration, the client must obtain a new access token. If the client has a refresh token, it can use that to obtain a new access token without requiring the user to re-authenticate. This is done through the Refresh Token Grant of the /token endpoint. The typical lifetime of a refresh token is 7 days.
Clients must not rely on the lifetime values above. These lifetimes are the
defaults and may be changed on a per-client basis and at our discretion. The
/token response includes the expires_in and
refresh_token_expires_in fields, the lifetimes of the access and refresh
tokens in seconds. Clients should use these fields at runtime to determine when
to request new tokens.
Advanced Use
Caution
The information in this section is intended for advanced use-cases. Manual token parsing is complex, error-prone, rarely necessary, and can introduce security vulnerabilities in the relying code.
Most clients do not need to understand the contents of access tokens and should treat them as opaque values.
Server-controlled validation and inspection services are provided by the API, such as /iracing/profile. These significantly reduce the complexity of extracting information from an access token and often provide additional information not otherwise available.
Clients with use-cases which require manual access token parsing should carefully read the information in this section and ensure that they understand the security implications of their implementation choices. It is recommended that a well-maintained and widely used JOSE library is used to perform access token validation and verification. If a client chooses to implement access token validation and verification without a library, it should ensure that it performs all of the necessary steps described in this section and in any relevant RFCs to avoid security vulnerabilities in the relying code.
Clients relying on manual token parsing may introduce security vulnerabilities into their own client code. These vulnerabilities are the responsibility of the client, and do not constitute a vulnerability in the authorization server or iRacing.
When in doubt, do not proceed further.
An access token must be validated and verified before its decoded contents can be trusted. It is STRONGLY RECOMMENDED that a trustworthy JOSE library is used to perform these steps. The library should be well-maintained and widely used, and should be kept up to date to ensure that any security vulnerabilities are patched. The library should also be configured to perform most of the necessary validation and verification steps described below. Failure to properly validate and verify access tokens can lead to security vulnerabilities, such as accepting tokens that are expired, not properly signed, or issued for a different audience.
The validation and verification steps are often combined in a single process. Access token validation ensures that its format is correct. Access token verification ensures that the token was issued by the authorization server and has not been modified.
Once all of the validation and verification steps have been completed, the contents of the access token can be trusted and used to make authorization decisions.
Format
An access token is a JSON Web Token (JWT), which has been signed by the authorization server as a JSON Web Signature (JWS). It is encoded in compact serialization format and conforms to the specification in RFC 7515.
Warning
Access tokens MUST NOT be used until they have gone through the validation and verification process. The contents of an access token cannot be trusted until it has been validated and verified. This is a common attack vector against JWT implementations that fail to properly validate and verify tokens before trusting their contents.
Header
The header contains at least the following parameters:
{
"kid": "d760990f-62c9-4570-ac99-9e7477363e18",
"alg": "EdDSA",
"jku": "https://oauth.iracing.com/.well-known/jwks.json"
}
The fields are:
-
kidA string identifier of the key used to sign the token. This is used to identify the correct key in the JSON Web Key Set (JWKS) at the
jkuURL. In this example it is a UUID, but it can be any string. -
algThe algorithm used to sign the token. This is typically “EdDSA”, which indicates that the token is signed using Edwards-curve Digital Signature Algorithm (EdDSA) with the Ed25519 curve. This is a modern signature algorithm that provides strong security and performance. Other algorithms may be used in future implementations, but “none” will never be used.
Warning
The
algclaim will never be “none”. This algorithm indicates that the token is not signed and MUST be rejected. -
jkuThe URL of the JSON Web Key Set (JWKS) containing the public keys used to verify the token’s signature. This is typically https://oauth.iracing.com/.well-known/jwks.json. It MUST use HTTPS, the client MUST verify the TLS certificate, and the URL MUST NOT contain user information, a query component, or a fragment component. Further, the domain component of the URL MUST end with the exact text
.iracing.com.
Payload
The payload contains the claims of the token, which are the statements about an entity (typically, the user), the authorizations the entity has delegated to the client, and additional metadata.
Warning
The payload contains an agreement between the authorization server and the resource servers. This is not an Identity Token, and the claims in the payload are not guaranteed to be present or to keep any documented meaning. The claims in the payload are intended to be used by resource servers to make authorization decisions. Clients should not rely on the presence or meaning of any particular claim in the payload and should treat the access token as an opaque value. For user identity information, use dedicated endpoints such as /iracing/profile instead.
The claims in the payload may change without notice to clients, and new claims may be added at any time.
The payload contains at least the following claims:
{
"session_id": "51687ec8-34d5-4523-ae26-e9f0462b6e44",
"iss": "https://oauth.iracing.com",
"exp": 1680654339,
"aud": ["example_client", "oauth-api"],
"sub": "e8627b85-b178-499d-bb59-888bba14bebd",
"client_id": "example_client",
"iat": 1680653739,
"jti": "d760990f-62c9-4570-ac99-9e7477363e18",
"auth_time": 1680653739,
"scope": "iracing.auth",
"iracing_env": "members",
"iracing_cust_id": 15535,
"iracing_group_ids": [1, 2, 3, 5, 8, 10]
}
The fields are:
-
session_idThe UUID identifier of the session.
-
issThe issuer of the access token; the authorization server. This value MUST be a URL and is typically
https://oauth.iracing.com. -
expThe expiration time of the access token on or after which the access token MUST be rejected, in seconds since Thursday 1 January 1970 00:00:00 UTC.
-
audThe case-sensitive list of one or more audiences for which this access token is valid. The list MUST include both “oauth-api” and the
client_idof the client to which this access token was issued. -
sub(may be null)The subject of the access token.
Note
The
subclaim may benull. Access tokens are not intended for use as identity tokens. For user identity information, use /iracing/profile instead. -
client_idThe identifier of the client application.
-
iatThe time of issue of the access token in seconds since Thursday 1 January 1970 00:00:00 UTC. If the
iatclaim is in the future the token MUST be rejected. It is acceptable to allow a small tolerance for clock skew, typically no more than a few seconds, to account for minor time differences between servers. -
jtiA UUID identifying this access token, which may be used to detect and prevent replays.
-
auth_timeThe time at which the authentication and authorization process completed and the session was created, in seconds since Thursday 1 January 1970 00:00:00 UTC. If the
auth_timeclaim is in the future the token MUST be rejected. It is acceptable to allow a small tolerance for clock skew, typically no more than a few seconds, to account for minor time differences between servers. -
scope(may be null)One or more scopes granted to the session, if any, separated by white space. The session may not be granted any scopes, in which case this field is
null. -
iracing_env(may be null)The iRacing environment; typically “members”. This field is conditionally included. If the field is not
nulland the value is unexpected the access token MUST be rejected. -
iracing_cust_id(may be null)The numeric iRacing customer identifier of the subject. This field is conditionally included. If the field is not
nulland the value is unexpected the access token MUST be rejected. -
iracing_group_ids(may be null)Zero or more numeric iRacing group identifiers to which the subject belongs. This field is conditionally included. If the field is not
nulland the value is unexpected the access token MUST be rejected.
Validation and Verification
It is recommended that a library is used to help validate and verify access tokens. A well-behaved validation and verification process MUST complete both the signature verification and claims validation procedures.
Signature Verification
-
Ensure the token is a well-formed JWS in compact serialization format.
-
Ensure the header contains a
kidclaim, which is a non-empty string. -
Ensure the header contains an
algclaim, which is a non-empty string and not “none”. If the algorithm is not supported by the implementation, the token MUST be rejected.Warning
The
algclaim will never be “none”. This algorithm indicates that the token is not signed and MUST be rejected. This is a common attack vector against JWT implementations that fail to properly validate thealgclaim. -
Ensure the header contains a
jkuclaim, which is a non-empty string and a valid URL. Typically, this URL will be https://oauth.iracing.com/.well-known/jwks.json, which contains the public keys used to verify the token’s signature. This is a JSON Web Key Set (JWKS). The URL MUST use HTTPS, the client MUST verify the TLS certificate, and the URL MUST NOT contain user information, a query component, or a fragment component. Further, the domain component of the URL MUST end with the exact text.iracing.com. Do not follow redirects when fetching the JWKS. If the URL is not valid or does not meet these requirements, the token MUST be rejected. -
Verify that the JWKS at the
jkuURL contains one and only one key with akidclaim matching the token’skidclaim. -
Verify that the key identified by the
kidclaim is valid for the algorithm specified in thealgclaim. For example, if thealgclaim is “EdDSA”, the key must have aktyclaim of “OKP” and acrvclaim of “Ed25519”. Ignore any header-provided key material parameters including but not limited to thejwkparameter. -
Verify the token’s signature using the key identified by the
kidclaim. If the signature is invalid, the token MUST be rejected.
This is enough information to ensure that the token is valid, was issued by the authorization server, and has not been modified.
The claims MUST be validated before trusting their contents. The claims validation steps are described in the next section.
Claims Validation
Warning
The JOSE library should return the verified header and payload before proceeding. The client MUST use the verified header and payload returned by the library for the remaining validations.
Failure to use the verified header and payload can lead to security vulnerabilities, such as accepting tokens that are not properly signed, are expired, or are issued for a different audience.
The following additional checks should be performed to ensure the token is valid for the operational context:
- Ensure the token’s
expclaim is in the future. It is acceptable to allow a small tolerance for clock skew, typically no more than a few seconds, to account for minor time differences between servers. - Ensure the token’s
iatclaim is in the past. It is acceptable to allow a small tolerance for clock skew, typically no more than a few seconds, to account for minor time differences between servers. - Ensure the token’s
auth_timeclaim is in the past. It is acceptable to allow a small tolerance for clock skew, typically no more than a few seconds, to account for minor time differences between servers. - Ensure the token’s
iatclaim is no earlier than theauth_timeclaim. - Ensure the token’s
issclaim matches the expected issuer for the operational context. This is typicallyhttps://oauth.iracing.com. - Ensure the token’s
audclaim includes both “oauth-api” and theclient_idof the client to which this access token was issued. - Ensure the token’s
scopeclaim contains the required scopes. - Ensure the token’s
iracing_envclaim, if present, matches the expected iRacing environment for the operational context. This is typically “members”.