Skip to content

Validate tokens to protect your APIs

All user tokens returned by Mosaic should be validated, as described below. This helps guard your endpoints and ensure users have indeed authenticated with Mosaic before you can proceed with granting them access to resources. Note, that client app tokens and management app tokens are consumed and validated by Mosaic, you don't need to validate them.

The validation process depends on your token signing key configuration. Mosaic supports different signing strategies (Global signing key, app-specific keys, or BYOK), and the JWKS endpoint you use for validation varies accordingly.

Token structure

Tokens issued by the app include:

  • The issuer in the iss (issuer) claim. Its format depends on your signing key configuration:
    • Global signing key: The issuer is tenant-level (for example, https://userid.security for US, https://eu.userid.security for EU, https://ca.userid.security for CA, or https://au.userid.security for AU)
    • App-specific signing keys: The issuer is the app's unique domain (subdomain or custom domain) as configured in your application settings (for example, https://acme-corporation.app.transmitsecurity.io)
  • A kid (key ID) header referencing the correct key.

Token validation libraries resolve the appropriate key automatically based on these fields.

Example ID Token

The following decoded ID token illustrates how signing is reflected in the token structure:

Header:

{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "appkey-7f439c13"
}

Payload:

{
  "iss": "https://acme-corporation.app.transmitsecurity.io",
  "sub": "user-12345",
  "aud": "client-67890",
  "exp": 1723588800,
  "iat": 1723585200,
  "auth_time": 1723585190,
  "email": "user@example.com",
  "name": "User Example"
}

Verify token signatures

Verify that the token is signed by Mosaic. To do it, retrieve the public key from the JWKS endpoint. The endpoint you use depends on your signing key configuration:

  • Global signing key: Use the generic endpoint https://api.transmitsecurity.io/cis/oidc/jwks
  • App-specific signing keys: Derive the endpoint from the token's iss claim using ${iss}/oidc/jwks (for example, if iss is https://acme-corporation.app.transmitsecurity.io, the JWKS endpoint is https://acme-corporation.app.transmitsecurity.io/oidc/jwks)

The endpoint returns a set of keys, along with a name, algorithm used, etc. for each key.

# Example for Global signing key
curl -i -X GET \
  https://api.transmitsecurity.io/cis/oidc/jwks

Check the kid in the token header–it helps identify the key used to sign this particular token. Then locate the key with the same kid in the key array returned by JWKS response to find the right key to compare the signature against. Mismatching signatures might indicate that the token could have been stolen and replaced by bad actors.

Note

Instead of querying public keys every time you need to validate an ID or access token, consider caching a response returned by /oidc/jwks. It helps avoid reaching API rate limits and prevent latency issues. Signing keys don't change often. However, if token validation fails, try clearing the cache and fetching new keys before revalidating the token signature.

Token validation best practices

When validating tokens, follow these best practices:

  • Determine the JWKS endpoint:
  • Select the correct public key using the kid in the JWT header
  • Implement fallback behavior for key rotation if your system enforces strict verification
Note

You can also discover the correct JWKS URI dynamically from the jwks_uri field at: ${iss}/.well-known/openid-configuration

For information on managing token signing keys and key rotation, see Token signing keys.

Validate user access tokens

Important

User access tokens must be validated on your side if you plan on using them to authorize internal API calls. If you plan on passing these tokens to other services, they should validate tokens as well.

Validate access tokens returned upon successful authentication or fetched for API authorization, as follows:

  • Validate that the issuer of the access token (iss) matches the expected issuer:
    • For Global signing key: https://userid.security (for US tenants), https://eu.userid.security (for EU tenants), https://ca.userid.security (for CA tenants), or https://au.userid.security (for AU tenants)
    • For app-specific signing keys: The issuer is the app's unique domain as configured in your application settings (for example, https://acme-corporation.app.transmitsecurity.io)
  • Validate that the expiry time (exp) of the access token has not passed
  • Validate that the tenant ID (tid) corresponds to your tenant
  • Validate the audience (aud) if you want to limit access to a specific resource. The access token will only include the resource in the aud claim if the client it's issued for is connected to this resource.
  • Validate that sub corresponds to the user identity stored in Mosaic.
  • Validate that the client ID (client_id) corresponds to the application client ID stored in Transmit
  • Validate that roles (roles) correspond to the roles assigned to the user

See User access tokens for more details on token claims.

Validate ID tokens

Validate ID tokens returned upon successful authentication as follows:

  • Validate that the issuer of the ID token (iss) matches the expected issuer:
    • For Global signing key: https://userid.security for US, https://eu.userid.security for EU, https://ca.userid.security for CA, or https://au.userid.security for AU.
    • For app-specific signing keys: The issuer is the app's unique domain as configured in your application settings (for example, https://acme-corporation.app.transmitsecurity.io)
  • Validate that the audience of the ID token (aud) is equal to the client ID related to the authentication
  • Validate that the expiry time (exp) of the ID token has not passed
  • Validate that the tenant ID (tid) corresponds to your tenant

See ID tokens for more details on ID token claims.