Migrating from Auth0
UniAuth is a drop-in OIDC provider. If your code uses Auth0's discovery URL and standard OIDC claims, migration is mostly config changes. Here's the mapping.
Endpoint Mapping
| Auth0 | UniAuth |
|---|---|
| .well-known/openid-configuration | .well-known/openid-configuration |
| .well-known/jwks.json | .well-known/jwks.json |
| /authorize | /api/oauth/authorize |
| /oauth/token | /api/oauth/token |
| /userinfo | /api/oauth/userinfo |
| /v2/logout | /api/oauth/end-session |
| /oauth/revoke | /api/oauth/revoke |
| /oauth/device/code | /api/oauth/device |
| /oauth/token (client_credentials) | /api/oauth/token |
| /oauth/introspect | /api/oauth/introspect |
| /oauth/par | /api/oauth/par |
| /oidc/register | /api/oauth/register |
Best practice: don't hardcode any of these. Your OIDC library should fetch them from the discovery URL. Just replace your Auth0 domain with https://uniauth.id.
Claim Mapping
| Auth0 Claim | UniAuth Claim | Notes |
|---|---|---|
| sub | sub | Pairwise (app-specific) in UniAuth by default — privacy-preserving |
| Same | ||
| email_verified | email_verified | Same |
| name | name | Same |
| nickname | nickname | Same |
| picture | picture | Same |
| https://yourapp.com/roles | groups | UniAuth uses standard groups scope — no custom namespace |
| app_metadata.role | groups | Use groups claim with group membership |
| https://yourapp.com/tenant | org_id or groups | Use native organizations or groups |
| amr | amr | Array; UniAuth emits pwd + mfa + the specific factor (totp/sms/email). Subset of Auth0's values, same semantics. |
| acr | acr | urn:uniauth:acr:{pwd,mfa,passkey} |
Key Differences
1. Pairwise Subject Identifiers
Auth0 gives every app the same sub for a user. UniAuth gives each app a different one (HMAC-SHA256 of user ID + client ID). This is a privacy feature — apps can't correlate users across services. If you need to migrate existing users by sub, keep a mapping table or use email as the join key.
2. Custom Claim Namespace
Auth0 requires namespaced claims for custom data (e.g. https://yourapp.com/roles). UniAuth uses standard OIDC claim names — groups, trust_tier, etc. Your code can stop stripping namespaces.
3. Universal Login vs. Your UI
Auth0's Universal Login is customizable but lives on their domain. UniAuth's login page is customizable at Developer Console → Branding (per-client logo, colors, support URLs). Same concept, different UX.
4. Rules / Actions → Custom Claims
Auth0 Rules/Actions map user data into ID tokens. UniAuth uses per-client custom claim mappings configured in the Developer Console — static values, user field references, or role-based.
5. Back-Channel Logout
Auth0 supports back-channel logout (paid plans). UniAuth supports it on every tier. See Logout Guide.
6. Token Lifetimes
Auth0 defaults: access tokens 24h, refresh tokens 30d (configurable per API). UniAuth defaults: access tokens 1h, refresh tokens 30d (rotating, family-tracked for replay detection), ID tokens 1h. If your client was hardcoded to assume 24h access tokens, either refresh more aggressively or adjust the tenant-wide lifetime in the admin console.
Minimal Code Diff
If your app uses OIDC discovery, this is typically all that changes:
- issuer: https://{yourTenant}.auth0.com/
+ issuer: https://uniauth.id
- client_id: {your auth0 client id}
+ client_id: uni_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- client_secret: {your auth0 client secret}
+ client_secret: unis_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxMigration Checklist
- Create a UniAuth OAuth client at Developer Console.
- Replace Auth0 domain with
https://uniauth.idin config. - Update redirect_uri and post_logout_redirect_uri on your OAuth client.
- Replace namespaced claim accessors with standard names (
groupsinstead ofhttps://yourapp/roles). - Build a sub-mapping table during cutover if you're preserving user IDs.
- Register backchannel_logout_uri for global logout propagation.
- Test the full flow against our Integration Checklist.
- Export users from Auth0 (Management API
GET /api/v2/users), transform to the UniAuth import schema, thenPOST /api/admin/users/import(JSON, max 10,000 per request, dry-run supported).
Need Help?
Migration support is available — contact us.