UAE PASS
To add UAE PASS as a social sign-in provider, you need a UAE PASS integration account. Visit UAE PASS
to register your application. For testing, use the staging credentials sandbox_stage / sandbox_stage.
- Ory CLI / Self-Hosted
Follow these steps to add UAE PASS as a social sign-in provider to your project using the Ory CLI or self-hosted Kratos:
-
Create a Jsonnet code snippet to map the desired claims to the Ory Identity schema.
UAE PASS doesn't return an
id_token. Ory sends requests to UAE PASS's userinfo API and adds the user info tostd.extVar('claims'). All UAE PASS-specific attributes are available viaclaims.rawClaims.Basic mapping (email and name):
local claims = std.extVar('claims');
{
identity: {
traits: {
[if 'email' in claims then 'email' else null]: claims.email,
name: {
first: claims.given_name,
last: claims.family_name,
},
},
},
}Full mapping (with UAE PASS metadata and verified email):
local claims = std.extVar('claims');
local hasRaw = 'rawClaims' in claims;
local raw = if hasRaw then claims.rawClaims else {};
local titleCase(s) =
local words = std.split(s, ' ');
std.join(' ', [
if std.length(w) == 0 then ''
else std.asciiUpper(w[0]) + std.asciiLower(w[1:])
for w in words
]);
{
identity: {
traits: {
[if 'email' in claims then 'email' else null]: claims.email,
[if 'mobile' in raw then 'phone'
else if 'phone_number' in claims then 'phone'
else null]:
if 'mobile' in raw then raw.mobile
else if 'phone_number' in claims then claims.phone_number,
name: {
first: titleCase(claims.given_name),
last: titleCase(claims.family_name),
},
},
verified_addresses: [
if 'email' in claims then {
via: 'email',
value: claims.email,
verified: true,
},
],
[if hasRaw then 'metadata_public' else null]: {
uaepass: {
[if 'uuid' in raw then 'uuid' else null]: raw.uuid,
[if 'userType' in raw then 'user_type' else null]: raw.userType,
[if 'mobile' in raw then 'mobile' else null]: raw.mobile,
[if 'email' in raw then 'email' else null]: raw.email,
[if 'firstnameEN' in raw then 'firstname_en' else null]: raw.firstnameEN,
[if 'lastnameEN' in raw then 'lastname_en' else null]: raw.lastnameEN,
[if 'firstnameAR' in raw then 'firstname_ar' else null]: raw.firstnameAR,
[if 'lastnameAR' in raw then 'lastname_ar' else null]: raw.lastnameAR,
[if 'fullnameEN' in raw then 'fullname_en' else null]: raw.fullnameEN,
[if 'fullnameAR' in raw then 'fullname_ar' else null]: raw.fullnameAR,
[if 'nationalityEN' in raw then 'nationality_en' else null]: raw.nationalityEN,
[if 'nationalityAR' in raw then 'nationality_ar' else null]: raw.nationalityAR,
[if 'gender' in raw then 'gender' else null]: raw.gender,
[if 'idn' in raw then 'emirates_id' else null]: raw.idn,
[if 'idType' in raw then 'id_type' else null]: raw.idType,
[if 'spuuid' in raw then 'smartpass_uuid' else null]: raw.spuuid,
[if 'titleEN' in raw then 'title_en' else null]: raw.titleEN,
[if 'titleAR' in raw then 'title_ar' else null]: raw.titleAR,
[if 'profileType' in raw then 'profile_type' else null]: raw.profileType,
[if 'unifiedId' in raw then 'unified_id' else null]: raw.unifiedId,
},
},
},
}infoUAE PASS returns different attributes depending on the user's account level (SOP):
Level Name Available Attributes SOP1 Basic uuid, email, mobile, firstnameEN, lastnameEN, userType SOP2 Advanced All SOP1 + full names (EN/AR), nationality, gender, idn, idType SOP3 Qualified All SOP2 + titleEN/AR, profileType, unifiedId All raw attributes are accessible via
claims.rawClaims.*in the Jsonnet mapper. Always guard access torawClaimswith'rawClaims' in claimsto avoid runtime errors if the field is not populated.UAE PASS returns names in uppercase (e.g.,
"MOHAMMED ALI"). Use atitleCasehelper in your mapper to normalize names before storing them in traits.
Don't save secrets such as API keys, credentials, or personal data directly in Jsonnet code snippets. Jsonnet code snippets used for data mapping aren't stored in an encrypted format in Ory Network.
-
Encode the Jsonnet snippet with Base64 or host it under an URL accessible to Ory Network.
cat your-data-mapping.jsonnet | base64 -
Download the Ory Identities config from your project and save it to a file:
## List all available workspaces
ory list workspaces
## List all available projects
ory list projects --workspace <workspace-id>
## Get config
ory get identity-config --project <project-id> --workspace <workspace-id> --format yaml > identity-config.yaml -
Add the social sign-in provider configuration to the downloaded config. Add the Jsonnet snippet with mappings as a Base64 string or provide an URL to the file.
Staging configuration:
selfservice:
methods:
oidc:
config:
providers:
- id: uaepass # this is `<provider-id>` in the Authorization callback URL. DO NOT CHANGE IT ONCE SET!
provider: uaepass
client_id: sandbox_stage
client_secret: sandbox_stage
auth_url: https://stg-id.uaepass.ae/idshub/authorize
token_url: https://stg-id.uaepass.ae/idshub/token
issuer_url: https://stg-id.uaepass.ae/idshub
mapper_url: "base64://{YOUR_BASE64_ENCODED_JSONNET_HERE}"
# Alternatively, use an URL:
# mapper_url: https://storage.googleapis.com/example-example-prd/example-file
scope:
- urn:uae:digitalid:profile:general
enabled: trueProduction configuration:
selfservice:
methods:
oidc:
config:
providers:
- id: uaepass
provider: uaepass
client_id: .... # Replace with your UAE PASS client ID
client_secret: .... # Replace with your UAE PASS client secret
auth_url: https://id.uaepass.ae/idshub/authorize
token_url: https://id.uaepass.ae/idshub/token
issuer_url: https://id.uaepass.ae/idshub
mapper_url: "base64://{YOUR_BASE64_ENCODED_JSONNET_HERE}"
scope:
- urn:uae:digitalid:profile:general
enabled: truetipFor visitor integration, add extra scopes to retrieve
profileTypeandunifiedId:scope:
- urn:uae:digitalid:profile:general
- urn:uae:digitalid:profile:general:profileType
- urn:uae:digitalid:profile:general:unifiedId -
Update the Ory Identities configuration using the file you worked with:
ory update identity-config --project <project-id> --workspace <workspace-id> --file identity-config.yaml
Configuration reference
The uaepass provider handles the following UAE PASS requirements automatically:
- No OIDC discovery — UAE PASS doesn't expose
.well-known/openid-configuration. Endpoints are configured directly. - No
openidscope — UAE PASS doesn't support the standardopenidscope. Useurn:uae:digitalid:profile:general. acr_valuesinjection — The requiredurn:safelayer:tws:policies:authentication:level:lowparameter is added automatically.client_secret_basicauth — The token endpoint uses HTTP Basic authentication as required by UAE PASS.- Userinfo-based claims — UAE PASS doesn't return ID tokens. Claims are fetched from the userinfo endpoint.
Endpoints
| Environment | Authorize | Token | Userinfo | Logout |
|---|---|---|---|---|
| Staging | https://stg-id.uaepass.ae/idshub/authorize | https://stg-id.uaepass.ae/idshub/token | https://stg-id.uaepass.ae/idshub/userinfo | https://stg-id.uaepass.ae/idshub/logout |
| Production | https://id.uaepass.ae/idshub/authorize | https://id.uaepass.ae/idshub/token | https://id.uaepass.ae/idshub/userinfo | https://id.uaepass.ae/idshub/logout |
Configuration fields
| Field | Required | Description |
|---|---|---|
provider | Yes | Must be uaepass |
client_id | Yes | Your UAE PASS client ID (use sandbox_stage for staging) |
client_secret | Yes | Your UAE PASS client secret (use sandbox_stage for staging) |
auth_url | No | Authorization endpoint. Defaults to staging if omitted |
token_url | No | Token endpoint. Defaults to staging if omitted |
issuer_url | No | Base URL for deriving the userinfo endpoint ({issuer_url}/userinfo). Defaults to staging if omitted |
scope | Yes | Must include urn:uae:digitalid:profile:general |
mapper_url | Yes | Path or Base64-encoded Jsonnet mapper |
Available claims
UAE PASS doesn't return an id_token. Ory sends requests to UAE PASS's userinfo API and adds the user info to
std.extVar('claims').
Standard claims
These claims are mapped automatically by the provider and available directly on the claims object:
| Claim | Field | Description |
|---|---|---|
claims.sub | Subject | UUID (preferred) or sub identifier |
claims.given_name | Given Name | firstnameEN from UAE PASS |
claims.family_name | Family Name | lastnameEN from UAE PASS |
claims.name | Full Name | fullnameEN from UAE PASS |
claims.email | Verified email | |
claims.phone_number | Phone | Mobile number |
claims.gender | Gender | Gender |
UAE PASS-specific claims (rawClaims)
These are accessible via claims.rawClaims in the Jsonnet mapper. Availability depends on the user's account level (SOP):
| Claim | SOP Level | Description |
|---|---|---|
claims.rawClaims.uuid | All | UAE PASS unique user identifier |
claims.rawClaims.userType | All | Account type: SOP1, SOP2, or SOP3 |
claims.rawClaims.mobile | All | Verified phone number |
claims.rawClaims.email | All | Verified email |
claims.rawClaims.firstnameEN | All | Given name (English) |
claims.rawClaims.lastnameEN | All | Family name (English) |
claims.rawClaims.firstnameAR | SOP2+ | Given name (Arabic) |
claims.rawClaims.lastnameAR | SOP2+ | Family name (Arabic) |
claims.rawClaims.fullnameEN | SOP2+ | Full name (English) |
claims.rawClaims.fullnameAR | SOP2+ | Full name (Arabic) |
claims.rawClaims.nationalityEN | SOP2+ | Nationality (English) |
claims.rawClaims.nationalityAR | SOP2+ | Nationality (Arabic) |
claims.rawClaims.gender | SOP2+ | Gender |
claims.rawClaims.idn | SOP2+ | Emirates ID number (citizens/residents only) |
claims.rawClaims.idType | SOP2+ | ID type |
claims.rawClaims.spuuid | SOP2+ | SmartPass UUID (SmartPass-verified accounts only) |
claims.rawClaims.titleEN | SOP2+ | Title (English) |
claims.rawClaims.titleAR | SOP2+ | Title (Arabic) |
claims.rawClaims.profileType | SOP3 (Visitors) | 1 (Citizen/Resident) or 2 (Visitor) |
claims.rawClaims.unifiedId | SOP3 (Visitors) | Unified user ID |
The idn (Emirates ID) attribute is not returned for Visitor profiles. It is only available for Citizens and Residents with
SOP2 or SOP3 accounts.
User account types (SOP levels)
UAE PASS supports three account levels, known as Standard Operating Procedures (SOPs). The account level determines which attributes are returned in the userinfo response.
| Level | Name | Verification Method | Available Attributes |
|---|---|---|---|
| SOP1 | Basic | Email + Mobile OTP only. Account is unverified. | uuid, email, mobile, firstnameEN, lastnameEN, userType |
| SOP2 | Advanced | Emirates ID + PIN, or migrated from SmartPass/Dubai ID. Account is verified. | All SOP1 + fullnameEN/AR, firstnameAR, lastnameAR, nationalityEN/AR, gender, idn, idType, spuuid, titleEN/AR |
| SOP3 | Qualified | Emirates ID + Biometrics (face or fingerprint). Account is verified. | All SOP2 + profileType, unifiedId |
SOP2 and SOP3 accounts have access to digital signature capabilities. SOP1 accounts only support authentication — they cannot use digital signature or data/document sharing features.
Visitor accounts
Visitors (non-Citizens/non-Residents) have a different attribute set. Visitors only support SOP1 and SOP3 levels. To retrieve visitor-specific attributes, add extra scopes to your configuration:
scope:
- urn:uae:digitalid:profile:general
- urn:uae:digitalid:profile:general:profileType
- urn:uae:digitalid:profile:general:unifiedId
You can distinguish visitor profiles from citizen/resident profiles using the profileType claim:
profileType = 1→ Citizen or ResidentprofileType = 2→ Visitor
Build and deploy
The uaepass provider requires a custom build of Ory Kratos from the
fork with UAE PASS support. This is necessary because the provider is not yet part of the
upstream Ory Kratos distribution.
# Clone the fork
git clone https://github.com/baytii/kratos.git
cd kratos
# Build the custom Docker image
docker build -t your-registry/kratos:latest-uaepass .
# Push to your registry
docker push your-registry/kratos:latest-uaepass
Then reference this image in your docker-compose.yml or Kubernetes deployment:
# docker-compose.yml
services:
kratos:
image: your-registry/kratos:latest-uaepass
# ... rest of your config
Staging testing
Follow these steps to test your UAE PASS integration in the staging environment:
- Create a staging account: Set up a UAE PASS staging account at docs.uaepass.ae. Staging accounts can be created from any location — there are no geographic restrictions.
- Use staging credentials:
client_id: sandbox_stage,client_secret: sandbox_stage. - Upgrade your account (optional): The staging account starts as SOP1 (basic). To test SOP2/SOP3 attributes, upgrade via the self-care portal.
- Run a POC: Follow the POC guide to verify the authentication flow end-to-end.
UAE PASS APIs are publicly accessible — both staging and production endpoints work from overseas. There are currently no charges for integrating with UAE PASS.
Troubleshooting
When you add a social sign-in provider, you can encounter common problems such as:
- Redirect URI mismatch
- Redirect loops during registration
- Domain verification issues
To troubleshoot those issues, read Social sign-in troubleshooting.
UAE PASS-specific issues
- No attributes returned: Check the user's SOP level. SOP1 accounts return only basic attributes (uuid, email, mobile, firstnameEN, lastnameEN). Upgrade the staging account to SOP3 for full attribute testing.
- Missing
idnfor visitors: The Emirates ID (idn) attribute is not returned for Visitor profiles. This is expected behavior. - Logout redirect issues: UAE PASS only accepts a
stateparameter in the logout URL. To pass additional parameters, Base64-encode them into thestateparameter:https://stg-id.uaepass.ae/idshub/logout?redirect_uri=https://your-app.com/logout&state={base64_encoded_query_string}
Credits
This provider was developed by GBYTE TECH and is available under the Apache 2.0 license.