T4 supports single sign-on (SSO), letting your users log in with your own identity provider (IdP) over OpenID Connect (OIDC) instead of a T4 password. Your application obtains an OIDC token from your IdP and sends it in the T4 login request in place of the password.
Integrating SSO takes three steps:
Email the following to [email protected]. T4 will confirm once the provider is set up.
| Item | Description |
| Name | A short label for the provider, e.g. Acme Corp Okta. |
| Vendor | Okta, Entra ID, AD FS, Ping Identity, Google, Keycloak, or Generic OIDC. |
| Issuer URL | The iss value in your tokens, e.g. https://acme.okta.com/oauth2/default. |
| JWKS URI | The URL of your JSON Web Key Set. Listed under jwks_uri in {issuer}/.well-known/openid-configuration. |
| Subject claim | The claim that uniquely identifies a user. Use sub for most providers; oid for Entra ID. |
Note:
The Issuer URL must match the iss claim in your tokens exactly, including any trailing slash.
| Provider | Issuer | Subject claim | JWKS URI |
| Entra ID | https://login.microsoftonline.com/{tenantId}/v2.0 | oid | https://login.microsoftonline.com/{tenantId}/discovery/v2.0/keys |
| Okta | https://{domain}/oauth2/default | sub | https://{domain}/oauth2/default/v1/keys |
https://accounts.google.com | sub | https://www.googleapis.com/oauth2/v3/certs |
|
| AD FS | https://{adfs-host}/adfs | sub | https://{adfs-host}/adfs/discovery/keys |
| Ping Identity | https://{env}.pingone.com/{envId}/as | sub | https://{env}.pingone.com/{envId}/as/jwks |
Link a user by adding an identityProvider object with two values:
| Field | Description |
| issuer | The provider's issuer URL. |
| subject | The subject-claim value (sub/oid) for that user, as issued by your IdP. |
Set the link when onboarding, when creating a user, or on an existing user.
Add identityProvider to the User object in the onboard request:
POST https://api.t4login.com/admin/v1/users/onboard
{
"User": {
"templateUser": "DefaultTemplate",
"username": "[email protected]",
"password": "SecurePassword123!",
"firstname": "Alice",
"lastname": "Smith",
"email": "[email protected]",
"apptype": "NonProfessional",
"identityProvider": {
"issuer": "https://acme.okta.com/oauth2/default",
"subject": "00u1ab2cd3EF4GH5IJ6K"
}
},
"Account": { "...": "..." },
"MarketData": { "...": "..." },
"Eula": { "...": "..." }
}
POST https://api.t4login.com/admin/v1/users
{
"username": "[email protected]",
"firstname": "Alice",
"lastname": "Smith",
"email": "[email protected]",
"apptype": "NonProfessional",
"identityProvider": {
"issuer": "https://acme.okta.com/oauth2/default",
"subject": "00u1ab2cd3EF4GH5IJ6K"
}
}
PATCH https://api.t4login.com/admin/v1/users/{userID}
{
"identityProvider": {
"issuer": "https://acme.okta.com/oauth2/default",
"subject": "00u1ab2cd3EF4GH5IJ6K"
}
}
Note:
To remove a link, PATCH with an empty issuer. Omit identityProvider to leave it unchanged.
Log the user in with the standard LoginRequest, but instead of username/password set your IdP's OIDC ID token in the id_token field. app_name and app_license are still required.
// ClientMessage
login_request {
id_token: "eyJhbGciOiJSUzI1NiIsImtpZCI6..." // OIDC ID token from your IdP
app_name: "YourApp"
app_license: "YOUR-APP-LICENSE-GUID"
price_format: PRICE_FORMAT_DECIMAL
}
T4 validates the token (signature, issuer, and expiry) and signs in the user whose (issuer, subject) link matches. The reply is the usual LoginResponse.
subject value.