Normalized user profile
Learn how Scalekit's normalized user profiles standardize identity data across providers, streamlining single sign-on (SSO) integration and user management.
When a user logs in with SSO, each identity provider shares the user profile information in their own format. This adds complexity for the application developers to parse the user profile info and code related identity workflows. To make this seamless for developers, Scalekit normalizes the user profile info into a standard set of fields across all identity providers.
This means that you’d always receive the user profile payload in a fixed set of fields, irrespective of the identity provider and protocol you interact with. This is one of our foundational aspects of the unified SSO solution.
{ "email": "john.doe@acmecorp.com", "email_verified": true, "family_name": "Doe", "given_name": "John", "locale": "en", "name": "John Doe", "picture": "https://lh3.googleusercontent.com/a/ACg8ocKNE4TZ...iEma17URCEf=s96-c", "sub": "conn_17576372041941092;google-oauth2|104630259163176101050", "identities": [ { "connection_id": "conn_17576372041941092", "organization_id": "org_17002852291444836", "connection_type": "OIDC", "provider_name": "AUTH0", "social": false, "provider_raw_attributes": { "aud": "ztTgHijLLguDXJQab0oiPyIcDLXXrJX6", "email": "john.doe@acmecorp.com", "email_verified": true, "exp": 1714580633, "family_name": "Doe", "given_name": "John", "iat": 1714544633, "iss": "https://dev-rmmfmus2g7vverbf.us.auth0.com/", "locale": "en", "name": "John Doe", "nickname": "john.doe", "nonce": "Lof9SpxEzs9dhUlJzgrrbQ==", "picture": "https://lh3.googleusercontent.com/a/ACg8ocKNE4T...17URCEf=s96-c", "sid": "5yqRJIfjPh8c7lr1s2N-IbY6WR8VyaIZ", "sub": "google-oauth2|104630259163176101050", "updated_at": "2024-04-30T10:02:30.988Z" } } ]}Full list of user profile attributes
Section titled “Full list of user profile attributes”| Profile attribute | Data type | Description |
|---|---|---|
sub | string | The connection ID and the user’s ID at the identity provider, joined by ;. See How sub is built. |
email | string | The user’s email address. |
email_verified | boolean | True if the user’s e-mail address has been verified as claimed by the identity provider; otherwise false. |
name | string | Fully formatted user’s name |
family_name | string | The user’s surname or last name. |
given_name | string | The user’s given name or first name. |
locale | string | The user’s locale, represented by a BCP 47 language tag. Example: ‘en’ |
picture | string | The user’s profile picture in URL format |
identities | Array of Identity objects | Array of all identity information received from the identity providers in the raw format |
Identity object attributes
Section titled “Identity object attributes”| Identity attribute | Data type | Description |
|---|---|---|
organization_id | string | Unique ID of the organization to which this user belongs to |
connection_id | string | Unique ID of the connection for which this identity data is fetched from |
connection_type | string | type of the connection: SAML or OIDC |
provider_name | string | name of the connection provider. Example: Okta, Google, Auth0 |
social | boolean | Is the connection a social provider (like Google, Microsoft, GitHub etc) or an enterprise connection. |
provider_raw_attributes | object | key-value map of all the raw attributes received from the connection provider as-is |
How sub is built
Section titled “How sub is built”sub has the form <connection_id>;<IdP user ID>, for example conn_17576372041941092;00u1a2b3c4d5e6f7g8h9. The IdP user ID depends on the connection type:
| Connection type | IdP user ID in sub |
|---|---|
| SAML | The NameID value in the assertion’s Subject. Scalekit rejects a SAML response without a NameID with mandatory_attribute_missing, so sub is always present. |
| OIDC | The sub claim from the identity provider. |
What provider_raw_attributes contains
Section titled “What provider_raw_attributes contains”provider_raw_attributes holds the identity provider’s data before Scalekit maps it to the fields above:
- SAML: every attribute in the assertion’s attribute statements, keyed by the attribute
Nameexactly as the IdP sent it, plus theNameIDunder the keynameid. An attribute with one value is a string; an attribute with several values, andgroups, is an array. - OIDC: every claim in the identity provider’s ID token. For some providers, such as Okta, Scalekit reads the claims from the provider’s userinfo endpoint instead, because their ID tokens leave out attributes like groups.
Choose a stable user identifier
Section titled “Choose a stable user identifier”Store the identifier that stays the same for a user across sign-ins:
- Key users on the organization and the IdP user ID, not on the full
sub.substarts with the connection ID, so it changes if your customer deletes their SSO connection and creates a new one. - Check which value the IdP sends as the user ID. A SAML
NameIDin persistent format, or an OIDCsub, stays the same for a user. ANameIDthat holds an email address or user principal name changes when the user is renamed.
Microsoft Entra ID
Section titled “Microsoft Entra ID”- SAML: Entra ID sends the user principal name as the
NameIDby default. Use the object ID instead: read it from thehttp://schemas.microsoft.com/identity/claims/objectidentifierattribute inprovider_raw_attributes, or ask your customer to set the Unique User Identifier (Name ID) claim touser.objectidin their Entra ID app. - OIDC: Entra ID’s
subclaim is unique to each app registration. To match the same user across apps, or with directory data, read theoidclaim fromprovider_raw_attributes. It’s the user’s object ID in Entra ID.