You can issue and validate JSON Web Tokens (JWTs) for MDriven Turnkey login and REST calls by merging the SysCert model pattern; use this page if you need to trust tokens from your own system or an external identity provider.
Choose the authentication pattern
The SysCert model pattern is the current, 2023 solution. It replaces the older SysExternalJWTDefinition-based setup described later on this page and supports both JWT and SAML2 tokens.
| Situation | Use | Result |
|---|---|---|
| You need to create tokens that another system can trust. | SysCert with a certificate/key set that includes a private key. | You can issue JWT or SAML2 tokens. |
| You need to accept tokens issued by an external provider. | SysCert with that provider's public certificate/key. | You can validate tokens, but cannot issue tokens as that provider. |
| You maintain an existing 2022 REST bearer-token integration. | The legacy SysExternalJWTDefinition pattern.
|
Existing integrations can continue to work; plan to move to SysCert. |
Set up the SysCert pattern
Merge the model pattern
- Obtain the
SysCert.ecomdlmerge file. - Merge it into your MDriven model in MDriven Designer.
- Save and deploy the updated application.
The merge adds the model support and user interface used in the certificate and token example. See the certificate and JWT walkthrough for a demonstration.
Create a key set for tokens you issue
A JWT is signed with cryptographic keys. The SysCert pattern uses RSA parameters for these keys.
- Open the SysCert view added by the merge.
- Create a new RSA key set.
- Assign a key identity (also called
kid). For example, useK1. - Keep the same key identity in every JWT issued by this key set.
- Set the token expiry and the token values your application requires, then generate the JWT.
The kid allows a receiver to select the correct key when validating a token. It also supports key rotation: create another key set with a different identity, such as K2, while systems still recognize K1 where required.
A generated JWT can assert a user name or email, an audience, an issuer, and validity times. For example, a token may assert the user alex@example.com, use OrdersSPA as its audience, and expire the next day.
Create a certificate when you need one
You can create an X.509 certificate from a key set. Set its subject name using a value that begins with CN=, and provide its validity dates.
Creating a full certificate is not required in order to generate a JWT from your own key set. The key identity is required because it is used to locate the matching key when the JWT is later presented for validation.
Trust an external issuer
To validate a token issued by another party, import that party's public certificate or public key material into SysCert.
A public-key-only entry can validate a received token's signature. It cannot generate tokens, because issuing a signed token requires the private key. This lets one MDriven application issue tokens while another MDriven application, or another system, imports the public key and validates them.
For an OpenID Connect provider, its discovery document commonly ends in .well-known/openid-configuration. The discovery information identifies provider endpoints and can lead you to its published signing keys. For OpenID Connect sign-in configuration rather than bearer-token validation, see Documentation:OpenID config.
Use a JWT for a Turnkey REST request
After you obtain a valid JWT, send it as a bearer token with the REST request. The legacy REST documentation describes the request header as:
Authentication: Bearer yourjwttoken
For example, a client calls a Turnkey REST command and supplies the token in the request header. The token identifies the signing key through its kid, so Turnkey can select the trusted public key and validate the token.
For a browser-based client, also configure cross-origin resource sharing (CORS). Documentation:Connecting javascript SinglePageApplications to Turnkey (SPA) shows a JavaScript single-page application obtaining an identity token and sending it to a Turnkey REST endpoint.
Legacy: SysExternalJWTDefinition pattern
This section documents the 2022 implementation for existing applications. For new work, use SysCert.
The legacy pattern allows a JavaScript or other REST client to present an arbitrary JWT to a Turnkey application. A valid token can establish the Turnkey login session, so later GET and POST calls are treated as logged-in calls.
How legacy validation works
When Turnkey receives a bearer token, it:
- Unpacks the JWT.
- Finds a
SysExternalJWTDefinitionthat matches both the token'skid(key identity) andaud(audience). - Uses the definition's
ModulusandExponentvalues to validate the signing key. - Checks that the token has not expired.
- Takes the token's email claim, or its name claim if email is absent.
- Calls
SysExternalJWTDefinition.AcceptAndTransformUserName(user:string;audience:String):string. - Looks up, but does not create, a
SysUsermatching the returned non-empty user name. - Marks that user as logged in and returns a login cookie for subsequent calls.
The audience is an identifier specific to the login or calling application. Configure the expected audience so that a token intended for one application is not accepted by another.
Configure external signing keys
Create one SysExternalJWTDefinition for each distinct external kid. Copy the external key's public modulus into Modulus and its public exponent into Exponent.
The key material comes from the identity provider that issued the token. For example, Azure AD publishes keys at its discovery keys endpoint. The related SPA example notes that the Modulus attribute must be long enough for the supplied value; a length of 500 characters is used in that example.
Control which users may enter
Implement AcceptAndTransformUserName to normalize a token identity to the value stored in SysUser.Email, or return an empty string to reject the login.
For example, the following logic accepts a user only when the token audience belongs to an approved external application. It then returns the supplied user value, which must already identify a SysUser in Turnkey.
if KnownExternalApp.allinstances->exists(x|(x.Audience=audience) and (x.IsOk)) then
user
else
''
endifThis method is the authorization point for the legacy pattern. Use it to reject an unexpected audience or transform an external identity into the email format used by your application.
CORS for browser clients
A browser client hosted on another origin needs CORS permission before it can call Turnkey. The SPA pattern uses a method such as GetAllowOriging to allow known origins.
For example:
if KnownExternalApp.allinstances->exists(x|(x.Origin=org) and (x.IsOk)) then
true
else
false
endifDo not treat CORS as token validation. CORS determines whether the browser may make the cross-origin call; JWT validation determines whether Turnkey accepts the caller's identity. Follow Documentation:Connecting javascript SinglePageApplications to Turnkey (SPA) for the complete SPA and CORS setup.
