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.
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.securityfor US,https://eu.userid.securityfor EU,https://ca.userid.securityfor CA, orhttps://au.userid.securityfor 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)
- Global signing key: The issuer is tenant-level (for example,
- A
kid(key ID) header referencing the correct key.
Token validation libraries resolve the appropriate key automatically based on these fields.
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 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
issclaim using${iss}/oidc/jwks(for example, ifissishttps://acme-corporation.app.transmitsecurity.io, the JWKS endpoint ishttps://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/jwksCheck 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.
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.
When validating tokens, follow these best practices:
- Determine the JWKS endpoint:
- For Global signing key, use
https://api.transmitsecurity.io/cis/oidc/jwks - For app-specific signing keys, derive it from the token's
issclaim using${iss}/oidc/jwks
- For Global signing key, use
- Select the correct public key using the
kidin the JWT header - Implement fallback behavior for key rotation if your system enforces strict verification
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.
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), orhttps://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)
- For Global signing key:
- 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 theaudclaim if the client it's issued for is connected to this resource. - Validate that
subcorresponds 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 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.securityfor US,https://eu.userid.securityfor EU,https://ca.userid.securityfor CA, orhttps://au.userid.securityfor 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)
- For Global signing key:
- 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.