Custom JWT Authentication
On this page
The Custom JWT authentication provider allows users to log in with an authentication credential from a third-party system (external to Atlas App Services) and use that token to access data and services with App Services. The external system must return a signed JSON Web Token (JWT) that contains a unique ID value for the authenticated user.
Authentication and Authorization
The third-party JWT provider authenticates users and returns a JWT. App Services uses the JWT to identify your application's users and authorize their requests.
App Services is agnostic to the authentication methods used by the third-party provider. It does not impose any restrictions on the external authentication system's requirements or authentication methods. For example, the system could require the user to perform multi-factor authentication (MFA), provide specific credentials, or otherwise identify themselves.
How JWT Authentication Works
There are many resources online that dive into the intricacies of JWT authentication and the token structure. In the context of App Services, the following diagram provides the process flow of a user logging on to a Device Sync app. The steps below the diagram provide details.
JWT authentication with App Services follows these general steps:
The user logs on to the third-party authentication provider by whatever means the provider requires.
If authentication succeeds, the provider returns a JWT to the client app.
The client app logs on to the App Services app, providing the JWT credential.
App Services parses and decodes the JWT.
If you manually provided signing keys in App Services, App Services checks if the signing key in the JWT matches one of the signing keys you specified. If so, the user is authenticated.
If you configured App Services to use a JSON Web Key (JWK) URI, App Services passes the JWT and public key to the third-party provider's JWK API.
The provider decodes and verifies the signature and returns a JWK.
App Services checks if the signature in the JWK matches the JWT's signature. If so, the user is authenticated.
Important
Access Token Always Expires after 30 Minutes
App Services always specifies a 30-minute access token expiry even if the
custom JWT token specifies a different expiry through the exp
key.
App Services will check the custom JWT token exp
to ensure that the token
is still valid before issuing the 30-minute expiry. For more information on
App Services access tokens, refer to Manage User Sessions.
Configuration
You configure Custom JWT Authentication from the UI or with the CLI. Choose your preferred method below.
You enable the JWT authentication provider from the App Services UI by selecting Custom JWT Authentication from the Authentication page.
To enable and configure the Custom JWT authentication provider with
App Services CLI, define a configuration
object for it in /auth/providers.json
.
A Custom JWT provider configuration has the following form:
{ "custom-token": { "name": "custom-token", "type": "custom-token", "config": { "audience": "<JWT Audience>", "requireAnyAudience": <boolean>, "signingAlgorithm": "<JWT Signing Algorithm>", "useJWKURI": <boolean>, "jwkURI": "<JWK or JWKS URL>", }, "secret_config": { "signingKeys": [ "<Signing Key Secret Name>", ... ] }, "metadata_fields": [ { "required": <boolean>, "name": "<JWT Field Path>", "field_name": "<Metadata Field Name>", }, ... ], "disabled": <boolean> } }
Verification Method
The Verification Method field determines how App Services will validate the JWT returned from the JWT provider. You can configure App Services to validate the JWT by using the signing key(s) you provide, or to validate by using a JSON Web Key (JWK) URI issued by the third-party provider.
Manually Specify Signing Keys
You can configure your app to use one or more signing keys to validate the JWT. There are two settings you need to provide:
Field | Description | |
---|---|---|
Signing Algorithm config.signingAlgorithm | The cryptographic method that the external system uses to sign the JWT. Custom authentication supports JWTs signed using either of the following algorithms:
| |
Signing Key secret_config.signingKeys | A list of up to three Secrets that each contain a signing key used by the third-party authentication system to sign JWTs. The key can only contain ASCII letters, numbers, underscores, and hyphens, and must be between 32 and 512 characters long. The following is a valid 256-bit signing key:
NoteIf you are uncertain of what value to use, consider visiting a random key generator website, like keygen.io, and using one of the generated 256-bit values. |
Set the Signing Algorithm:
Create one or more signing keys to sign the JWT. To do this, provide a name for the key (which is solely for your reference later), and then specify a 256-bit signing key.
"config": { "signingAlgorithm": "<JWT Signing Algorithm>", }, "secret_config": { "signingKeys": [ "<Signing Key Secret Name>", ... ] }
Warning
A Signing Key is a secret key and anyone with the key can issue valid user credentials for your app. Ensure that it's never stored in a publicly accessible location, such as a git repository, message board, or in your code.
Use a JWK URI
Some external authentication systems provide a JSON Web Key Set (JWKS) that describes the signing
algorithm and signing keys the system uses to sign JWTs. You can use the
JWKS to configure the provider instead of manually specifying the
signing algorithm and keys. The returned JWKS must include a
kid
header that specifies the Key ID of a key from the JWKS. The JWKS
may specify up to three signing keys and must use the RS256
algorithm.
Note
JWK and JWKS are used synonymously in Atlas App Services.
There is only one value you need to provide:
JWK URI
, which is the third-party URL that hosts a JWK or JWKS service. When you choose this option, App Service automatically sets encryption to the requiredRS256
method.
Specify the URL to the third-party JWKS endpoint:
"config": { "useJWKURI": <boolean>, "jwkURI": "<JWK or JWKS URL>" }
Metadata Fields
Metadata Fields are additional data that describe each internal
App Services user. App Services determines the value of each metadata field from
the value of a field included in the third-party JWT.
For example, if you set the name
field of a user, then App Services will use
that field in the JWT as the user's display name.
Note
App Services refreshes a user's metadata whenever they log in and exposes the
fields in the data
object of the user metadata.
Important
JWT and Metadata Field Character Limits
The length of a JWT token increases with the number of metadata fields in the token and the size of each field. App Services limits the length of a JWT token to 1 million characters, and the length of each metadata field to 4096 characters. If you exceed these limits, App Services logs an error and the ticket is not processed.
There are three values that you need to specify for each metadata field:
Field | Description |
---|---|
Required required | If true , the metadata field is required for all
users associated with the provider. The JWT
returned by the external system must have a
value assigned to the field designated by Path. |
Path name | The name of, or the path to, a field in the JWT that contains the value
for the metadata field. To specify the path to a field in
an embedded object, use dot notation.
If the name of the field itself in the JWT contains a period ( . )
character, use a backslash (\ ) to escape the period. For example, if
the name is http://example.com/id , use http://example\.com/id . |
Field Name field_name | Optional. A name for the metadata field in the user object's Default Value Rules
|
To define a metadata field, click Add Field and specify the mapping between the metadata field in the JWT and its corresponding field name in the user object.
To define a metadata field in a Custom JWT authentication
configuration file, add an entry for the field to the
metadata_fields
array. Each entry should be a document of the
following form:
{ required: <boolean>, name: "<field path>", field_name: "<metadata field name>" }
Use a backslash (\
) to escape period (.
) characters in JWT keys.
For example, in this JSON object, you represent the "nested_key"
in
the path name as valid\.json\.key\.nested_key
.
{ "valid.json.key": { "nested_key": "val" } }
Example
An external authentication system returns JWTs that include
additional information about each user in the user_data
field:
(JWT JSON) { "aud": "myapp-abcde", "exp": 1516239022, "sub": "24601", "user_data": { "name": "Jean Valjean", "aliases": [ "Monsieur Madeleine", "Ultime Fauchelevent", "Urbain Fabre" ] } }
To include the values from the user_data
field in each user's
user object, specify the following
metadata fields in your App Services configuration:
Path | Field Name |
---|---|
user_data.name | name |
user_data.aliases | aliases |
The user object, will now include those fields:
(USER METADATA OBJECT) { "id": "59fdd02846244cdse5369ebf", "type": "normal", "data": { "name": "Jean Valjean", "aliases": [ "Monsieur Madeleine", "Ultime Fauchelevent", "Urbain Fabre" ] }, identities: [ { "id": "24601", "provider_type": "custom-token", "data": { "name": "Jean Valjean", "aliases": [ "Monsieur Madeleine", "Ultime Fauchelevent", "Urbain Fabre" ] }, } ] }
Audience
The Audience of a JWT specifies the intended recipient of the token.
JWTs describe their audience in the aud
claim. App Services
expects aud
to contain the App ID of the App for which the provider
is configured. However, if the external authentication system JWT specifies a
different aud
value, then you can configure the provider to use that value
instead.
There are two fields you configure:
Field | Description |
---|---|
Audience | A single value or comma-separated list of values for the
audience or audiences expected to be found in a client JWT. |
Require | If you provide multiple audiences, you must specify how to handle them. Your options are:
|
To set an audience, configure config.audience
. There are two fields
you configure:
Field | Description |
---|---|
audience | An array of strings specifying the audience or audiences expected
to be found in a client JWT. |
requireAnyAudience | Boolean. If false , the JWT must include all of the listed
audiences. If true , the JWT must only include one or
more of the listed audiences. |
"config": { "audience": [ "<JWT Audience>", ], "requireAnyAudience": <boolean>, }
Using JWT Authentication
You can register new Custom JWT users and log them in using one of the Realm SDKs or an API service.
Realm SDKs
For code examples that demonstrate how to register and log in using Custom JWT authentication, see the Realm SDK documentation for your preferred language and platform:
API Services
You can authenticate Data API requests using the Custom JWT provider. You can either require users to create accounts before using a service, or configure your API endpoints to automatically create a new user account if the request contains a valid JWT that does not match an existing user. There are two approaches to using JWTs with your service APIs:
specify the JWT directly in the
jwtTokenString
request headerstart a user session with the JWT and include the session access token as an
Authorization
header bearer token.
For more information, see Authenticate Data API Requests.