Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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.

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:

  • kid

    A 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 jku URL. In this example it is a UUID, but it can be any string.

  • alg

    The 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 alg claim will never be “none”. This algorithm indicates that the token is not signed and MUST be rejected.

  • jku

    The 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_id

    The UUID identifier of the session.

  • iss

    The issuer of the access token; the authorization server. This value MUST be a URL and is typically https://oauth.iracing.com.

  • exp

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

  • aud

    The 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_id of the client to which this access token was issued.

  • sub (may be null)

    The subject of the access token.

    Note

    The sub claim may be null. Access tokens are not intended for use as identity tokens. For user identity information, use /iracing/profile instead.

  • client_id

    The identifier of the client application.

  • iat

    The time of issue of the access token in seconds since Thursday 1 January 1970 00:00:00 UTC. If the iat claim 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.

  • jti

    A UUID identifying this access token, which may be used to detect and prevent replays.

  • auth_time

    The 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_time claim 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 null and 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 null and 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 null and 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

  1. Ensure the token is a well-formed JWS in compact serialization format.

  2. Ensure the header contains a kid claim, which is a non-empty string.

  3. Ensure the header contains an alg claim, 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 alg claim 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 the alg claim.

  4. Ensure the header contains a jku claim, 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.

  5. Verify that the JWKS at the jku URL contains one and only one key with a kid claim matching the token’s kid claim.

  6. Verify that the key identified by the kid claim is valid for the algorithm specified in the alg claim. For example, if the alg claim is “EdDSA”, the key must have a kty claim of “OKP” and a crv claim of “Ed25519”. Ignore any header-provided key material parameters including but not limited to the jwk parameter.

  7. Verify the token’s signature using the key identified by the kid claim. 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:

  1. Ensure the token’s exp claim 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.
  2. Ensure the token’s iat claim 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.
  3. Ensure the token’s auth_time claim 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.
  4. Ensure the token’s iat claim is no earlier than the auth_time claim.
  5. Ensure the token’s iss claim matches the expected issuer for the operational context. This is typically https://oauth.iracing.com.
  6. Ensure the token’s aud claim includes both “oauth-api” and the client_id of the client to which this access token was issued.
  7. Ensure the token’s scope claim contains the required scopes.
  8. Ensure the token’s iracing_env claim, if present, matches the expected iRacing environment for the operational context. This is typically “members”.