====== SSO Integration ======
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:
- Send your identity provider details to T4.
- Link each T4 user to their identity in that provider.
- Send the OIDC token at login instead of a password.
===== What We Support =====
* **Protocol:** OpenID Connect (OIDC).
* **Providers:** Okta, Microsoft Entra ID (Azure AD), AD FS, Ping Identity, Google, Keycloak, or any standards-compliant Generic OIDC provider.
===== 1. Send Us Your Provider Details =====
Email the following to T4.APISupport@plus500.com. 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. |
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%%'' |
| Google | ''%%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%%'' |
===== 2. Link Each User to Their SSO Identity =====
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.
==== During Onboarding ====
Add ''identityProvider'' to the ''User'' object in the [[developers:admin:onboarding|onboard]] request:
POST https://api.t4login.com/admin/v1/users/onboard
{
"User": {
"templateUser": "DefaultTemplate",
"username": "alice@acme.com",
"password": "SecurePassword123!",
"firstname": "Alice",
"lastname": "Smith",
"email": "alice@acme.com",
"apptype": "NonProfessional",
"identityProvider": {
"issuer": "https://acme.okta.com/oauth2/default",
"subject": "00u1ab2cd3EF4GH5IJ6K"
}
},
"Account": { "...": "..." },
"MarketData": { "...": "..." },
"Eula": { "...": "..." }
}
==== When Creating a User ====
POST https://api.t4login.com/admin/v1/users
{
"username": "alice@acme.com",
"firstname": "Alice",
"lastname": "Smith",
"email": "alice@acme.com",
"apptype": "NonProfessional",
"identityProvider": {
"issuer": "https://acme.okta.com/oauth2/default",
"subject": "00u1ab2cd3EF4GH5IJ6K"
}
}
==== On an Existing User ====
PATCH https://api.t4login.com/admin/v1/users/{userID}
{
"identityProvider": {
"issuer": "https://acme.okta.com/oauth2/default",
"subject": "00u1ab2cd3EF4GH5IJ6K"
}
}
To remove a link, PATCH with an empty ''issuer''. Omit ''identityProvider'' to leave it unchanged.
===== 3. Logging In with SSO =====
Log the user in with the standard [[developers:apiv2:connecting|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''.
===== Checklist =====
* Provider details sent to T4.APISupport@plus500.com.
* Every SSO user linked with the correct ''subject'' value.
* At least one successful test login before go-live.