Sandbox environment
Overview
The LuxID UAT (User Acceptance Testing) environment mirrors the production protocol surface for development and QA against isolated test users.
LuxID provides a dedicated UAT (User Acceptance Testing) environment that mirrors the production protocol surface. Every feature of the integration layer - OIDC, OAuth 2.0, token endpoints, consent flows, MFA - is available in UAT. The environment is intended for:
- Initial integration development before your production credentials are provisioned.
- Regression testing before releases.
- QA validation of consent screen content and claim configuration.
- Load and smoke testing (within rate limits - see below).
The UAT base URL is https://login-uat.luxid.lu.
What is the same as production
The UAT environment runs the same software version as production and exposes identical endpoint paths.
| Aspect | UAT | Production |
|---|---|---|
| OIDC discovery | https://login-uat.luxid.lu/.well-known/openid-configuration | https://login.luxid.lu/.well-known/openid-configuration |
| Authorization endpoint | https://login-uat.luxid.lu/mga/sps/oauth/oauth20/authorize | https://login.luxid.lu/mga/sps/oauth/oauth20/authorize |
| Token endpoint | https://login-uat.luxid.lu/mga/sps/oauth/oauth20/token | https://login.luxid.lu/mga/sps/oauth/oauth20/token |
| UserInfo endpoint | https://login-uat.luxid.lu/mga/sps/oauth/oauth20/userinfo | https://login.luxid.lu/mga/sps/oauth/oauth20/userinfo |
| JWKS endpoint | https://login-uat.luxid.lu/mga/sps/oauth/oauth20/jwks/OIDC-LUXID | https://login.luxid.lu/mga/sps/oauth/oauth20/jwks/OIDC-LUXID |
| Introspection | https://login-uat.luxid.lu/mga/sps/oauth/oauth20/introspect | https://login.luxid.lu/mga/sps/oauth/oauth20/introspect |
| Revocation | https://login-uat.luxid.lu/mga/sps/oauth/oauth20/revoke | https://login.luxid.lu/mga/sps/oauth/oauth20/revoke |
| Supported grant types | Authorization Code + PKCE, Refresh Token (no Client Credentials grant - for server-to-server, use the Partner API) | Same |
| Supported response types | code | Same |
| PKCE support | Required | Required |
| MFA methods | OTP, TOTP, passkeys, LuxTrust | Same |
Authentication levels (auth_level / acr) | auth_level 2/3/4/8/9; acr URNs level:low/level:substantial/level:high | Same |
| Consent flows | Full consent dialogue, incremental consent | Same |
| JWKS key rotation | Yes | Yes |
| SAML 2.0 | Yes (separate metadata URL) | Same |
The endpoint paths are identical - only the host differs. This means your configuration can be driven by a single environment variable (LUXID_BASE_URL) with no other code changes between environments.
What is different from production
Separate Partner registration and credentials
Your UAT Client ID and Client Secret are not the same as your production credentials. They are issued when your UAT application is registered with LuxID. Store them separately in your secret management system and never use UAT credentials in production or vice versa.
See Environments for how to request UAT access.
Isolated user base
UAT has its own user directory. Production user accounts do not exist in UAT, and UAT test accounts do not exist in production. Test users are provisioned specifically for UAT - see Test users and simulation.
There is no way to import or copy real users from production into UAT. This is intentional: it prevents accidental exposure of real user data during development.
Email and phone-number whitelisting in UAT
UAT does not deliver emails or OTP messages (SMS or voice call) to recipients outside a per-Partner whitelist. This is intentional: it prevents test messages from reaching real users who happen to share an address or phone number with your test data.
Production has no such whitelist - messages reach all real recipients. The sections below explain how the UAT whitelist works and how to manage it.
How the whitelist works
Silent dropping - no error is returned to the user or to your Application. From the user's perspective, the message simply never arrives.
Email whitelisting
Whitelisting is by domain, not by individual address. All addresses under a whitelisted domain receive delivery in UAT.
- Correct format:
@example.lu,@qa.mycompany.lu - Incorrect:
testuser@example.lu(individual addresses are not accepted) - Addresses on whitelisted domains land in real inboxes, so use a domain you control and monitor.
- The
(ext.)post.ludomain is whitelisted by default, so addresses on it receive delivery without a request. Any other domain (including(ext.)deep.eu) must be requested.
If your test addresses are on a pre-whitelisted domain, you can self-register test accounts at https://login-uat.luxid.lu (opens in a new tab) and receive the activation email immediately - see Test users and simulation.
Phone-number whitelisting
Whitelisting is by full E.164 number. Wildcards and prefix ranges are not supported.
- Correct format:
+352621123456 - Incorrect:
+3526210*(wildcards not accepted) - Each number must be added individually.
Silent-failure symptoms
If a test is blocked by a missing whitelist entry, the failure is silent. Use this table to diagnose the cause:
| Symptom | Likely cause | Fix |
|---|---|---|
| Activation email never arrives | Recipient domain not whitelisted | Request domain whitelist entry |
| OTP SMS never arrives | Recipient phone number not whitelisted | Request number whitelist entry |
| OTP voice call never rings | Recipient phone number not whitelisted | Request number whitelist entry |
| Password-reset email missing | Recipient domain not whitelisted | Request domain whitelist entry |
How to request a whitelist entry
Contact us with the Partner name and the domain(s) and/or E.164 number(s) to add. Once the planned LuxID Console ships, this will be a self-service action under Partner > UAT > Whitelists.
Routine additions are processed on request; bulk additions (more than ten entries) may take longer.
Production behaviour
Production has no whitelist - emails and OTP messages are dispatched to all real recipients without restriction. When you promote from UAT to production:
- Remove test phone numbers and addresses from any data your Application sends to LuxID.
- Do not assume that a flow "worked in UAT" means it will work in production for an arbitrary user: the whitelisted test set is narrow by design.
Recommended setup
Register a dedicated test domain (for example, qa.example.lu) and a small fixed set of test phone numbers at the start of your UAT engagement. Use these consistently across all test scenarios rather than adding ad hoc entries throughout the project. This keeps the whitelist short and makes it easy to re-provision after a UAT reset.
Rate limits
UAT enforces rate limits to prevent accidental runaway test loops from affecting shared infrastructure. The limits are lower than production.
| Category | UAT limit | Notes |
|---|---|---|
| Per-IP (authorization requests) | TBC | Applies to the public-facing authorize endpoint |
| Per-client (token requests) | TBC | Applies to your Client ID across all redirect URIs |
| Per-user (login attempts) | TBC | Triggers temporary lockout on repeated failures |
| Token endpoint (client credentials) | TBC | Separate bucket from authorization code flows |
When a limit is exceeded, the endpoint returns HTTP 429 Too Many Requests with a Retry-After header. Your test harness should respect this header rather than tight-looping.
For load testing that requires higher limits, contact LuxID in advance so capacity can be allocated.
JWKS signing keys
UAT uses a separate signing key pair from production. When validating token signatures in UAT, always fetch the JWKS from the UAT endpoint:
https://login-uat.luxid.lu/mga/sps/oauth/oauth20/jwks/OIDC-LUXID
Never hardcode a public key. Always resolve the jwks_uri from the discovery document at runtime. This ensures your code handles key rotation correctly in both environments.
Test data lifecycle
UAT data is not guaranteed to persist indefinitely. The LuxID platform team may reset or refresh UAT at any time as part of maintenance, schema migrations, or software upgrades.
Implications for your project:
- Do not rely on long-term test user persistence. Automate test user creation via LuxID or API rather than maintaining a manually curated list of accounts.
- Do not store UAT credentials in long-lived CI secrets without a rotation plan. UAT Client IDs and Secrets may be rotated after an environment reset.
- Document your test scenarios in your own repository so they can be re-created quickly after a reset.
- Do not use UAT as a staging database for any real data. UAT should only ever contain synthetic test data.
After a UAT reset, you will receive a notification from LuxID. Rebuild your test user set and re-validate your integration before the next planned release.
Configuring your Application for UAT
Replace only the host in your configuration. Everything else - grant type, scopes, redirect URIs - remains the same.
Example: environment variable approach (recommended)
# .env.uat
LUXID_BASE_URL=https://login-uat.luxid.lu
LUXID_CLIENT_ID=<your-uat-client-id>
LUXID_CLIENT_SECRET=<your-uat-client-secret>
LUXID_REDIRECT_URI=https://yourapp-uat.example.com/callback
LUXID_SCOPES=openid profile email
# .env.production
LUXID_BASE_URL=https://login.luxid.lu
LUXID_CLIENT_ID=<your-production-client-id>
LUXID_CLIENT_SECRET=<your-production-client-secret>
LUXID_REDIRECT_URI=https://yourapp.example.com/callback
LUXID_SCOPES=openid profile email
Your code then constructs all endpoints from LUXID_BASE_URL - or better, reads them dynamically from the discovery document:
# Resolve the discovery document once at startup
curl -s "${LUXID_BASE_URL}/.well-known/openid-configuration" | jq .
Redirect URIs: your UAT redirect URIs must be registered with LuxID under your UAT application. They are separate from your production redirect URIs.
Promoting to production
When your integration passes QA in UAT, you promote it to production by submitting a promotion request to LuxID. The promotion process:
- Contact us with a promotion request for the UAT application configuration (Application name, Client ID, target production redirect URIs).
- LuxID reviews the configuration (redirect URIs, requested scopes, Claim Templates, branding assets).
- A production Client ID and Client Secret are issued.
- You update your production environment variables and deploy.
See Environments for the full promotion workflow and checklist.
Do not attempt to reuse UAT credentials in production. Production credentials are always issued separately.
Quick reference
| Item | UAT value |
|---|---|
| Discovery document | https://login-uat.luxid.lu/.well-known/openid-configuration |
Issuer (iss) | https://login-uat.luxid.lu |
| JWKS | https://login-uat.luxid.lu/mga/sps/oauth/oauth20/jwks/OIDC-LUXID |
| Token endpoint | https://login-uat.luxid.lu/mga/sps/oauth/oauth20/token |
| UserInfo endpoint | https://login-uat.luxid.lu/mga/sps/oauth/oauth20/userinfo |
| Test user panel | LuxID Console > UAT > Test Users |
| Support | LuxID |