Plan and design
Why design first
LuxID integrations involve decisions that are expensive to change after go-live. The sub assigned to a user is Sphere-scoped and stable only as long as the Subscription exists; changing Spheres mid-flight breaks user identity linkage. Protocol choice affects which libraries and infrastructure you need. The minimum auth_level you require shapes the user journey. Make these calls deliberately before writing production code.
Work through the checklist at the end of this page before starting implementation.
Decision 1 - protocol: OIDC or SAML
| Criterion | Recommendation |
|---|---|
| New web or mobile application | OIDC |
| SaaS platform with a built-in SAML SP connector | SAML (no custom code needed) |
| SaaS platform with a built-in OIDC connector | OIDC |
| Need API access tokens | OIDC (OAuth 2.0 layer) |
| Legacy enterprise application with SAML-only support | SAML |
| Mobile / native app | OIDC |
| Server-to-server (no user present) | Partner API (X-Client-Id / X-Client-Secret headers) - LuxID's OIDC tenant does not support the Client Credentials grant |
Default: choose OIDC. It has richer library support across all languages, simpler debugging (JWTs are human-readable), and is the direction the industry is standardising on. SAML is the right choice when your platform's connector makes it the path of least resistance - see Quick Integrations for platform-specific guides.
Full protocol documentation: OpenID Connect | SAML 2.0.
Decision 2 - required auth_level
Declare the minimum auth_level your application requires. LuxID enforces step-up authentication when the user's current session does not meet the requirement.
auth_level | Second factor required | Typical use case |
|---|---|---|
| 2 | None (password only) | Low-risk personalisation, reading public content |
| 3 or 4 | OTP (SMS/voice) or TOTP | Consumer e-commerce, account management, most B2C apps |
| 8 | Passkey | Phishing-resistant passwordless sign-in |
| 9 | LuxTrust (qualified authentication) | Identity-verified onboarding, regulated actions. Note: enforcing LuxTrust as the required second factor is a paid add-on. OTP, TOTP and passkeys are included in the base service. If a user voluntarily configures LuxTrust on their account, that is the user's choice and is not invoiced to the Partner. |
Questions to answer:
- Does your application perform actions with legal or financial consequences? If yes, consider requiring
auth_level9. - Does your application store or process sensitive personal data? If yes, consider requiring at least
auth_level3 or 4. - Is your application subject to a regulatory framework (PSD2, AML, GDPR data subject actions)? Check what authentication strength that framework requires and pick the corresponding
auth_level- and note that LuxID does not issue formal eIDAS LoA assertions, so frameworks demanding qualified means may require LuxTrust, a notified eID, or the EUDI Wallet directly. - Can some features require a higher
auth_levelthan others (step-up)? If yes, plan for step-up flows.
For the full auth_level scale and how it relates to eIDAS LoA, see Authentication levels.
Decision 3 - MFA policy and step-up
Even if your baseline auth_level is 2 or 3/4, you may want to trigger step-up authentication for specific high-risk actions (changing email address, authorising a payment, exporting personal data).
Design questions:
- Which actions in your application warrant step-up?
- What is the target
auth_levelfor each action? - How will your application signal to LuxID that step-up is required? (via the
acr_valuesparameter on the authorisation request) - How will you handle the case where the user cannot complete step-up (e.g. lost second factor)?
Plan step-up flows before building your UI. Retrofitting step-up into an existing session model is complex.
Decision 4 - claim minimisation
Request only the claims your application genuinely needs. Rationale:
- Consent friction - every claim you request appears on the user's consent screen. Unnecessary claims increase abandonment.
- Data liability - every claim you receive is personal data you are responsible for under GDPR (EU) 2016/679 (opens in a new tab). Minimise what you store.
- LuxID Agreement scope - your LuxID Agreement may restrict which claims you may request. Requesting out-of-scope claims will fail.
For each claim, ask: "Does my application break if this claim is absent?" If no, do not request it.
Claims available from LuxID: sub, name, given_name, family_name, birthdate, updated_at, email, email_verified, phone_number, phone_number_verified. (The age_over_16 claim is defined in the schema but is not currently offered.)
Decision 5 - Sphere strategy
The Sphere determines which sub value a user receives in your application. This is the most consequential identity architecture decision, because sub is how you link LuxID users to records in your own database.
| Sphere scenario | Effect | When to use |
|---|---|---|
| Dedicated Sphere per Application | Each app sees a unique sub for the same user | Default for isolated apps; maximum privacy isolation |
| Shared Sphere across your Partner's Applications | All apps under your Partner see the same sub | When you want to link user records across your own apps without asking users to re-link |
| Shared Sphere across your Organisation's Partners | All Partners in your Organisation see the same sub | When you operate multiple distinct services and want a unified user identity across all of them |
Key constraints:
- Sphere assignment is set at Application registration time. Changing it later means existing users get a new
sub- breaking any foreign-key relationships you have built. - Revoking the last Subscription in a Sphere and re-subscribing (e.g. if a user deletes and recreates their account) yields a new
sub. Treatsubas stable but not eternal. - Sharing a Sphere across Partners creates a cross-Partner user linkage. Ensure your LuxID Agreement and privacy policy cover this.
Recommendation for most new integrations: start with a dedicated Sphere. You can add Applications to it later. Do not share across Partners unless you have a clear architectural reason.
Decision 6 - session lifetime strategy
Your application manages its own session independently of LuxID's tokens. Define your session strategy explicitly.
| Parameter | Consideration |
|---|---|
| Application session lifetime | How long should a user stay logged in to your app without re-authenticating? Align with your security policy. |
| Access token refresh | Access tokens are short-lived. Use the refresh token to obtain new ones silently. |
| Refresh token lifetime | Refresh tokens are long-lived. After expiry the user must re-authenticate. |
| Idle timeout | Should inactivity trigger a logout? Implement this in your application layer, not in LuxID. |
| LuxID SSO session | Users may already have an active LuxID session from another Partner. If so, LuxID's Universal Login will complete silently (no password prompt). You cannot control this - design your UX to accommodate it. |
Decision 7 - logout strategy
Logout in a federated system has two distinct concepts:
Local logout - invalidate your application's session only. The user remains logged in to LuxID and may silently re-authenticate if they visit your login page again. Use this for low-sensitivity applications where convenience outweighs security.
User-driven LuxID sign-out - after invalidating your local session, redirect the user to https://login.luxid.lu/auth/logout?client_id=<your_client_id>. LuxID shows a confirmation screen naming your application and the user chooses whether to end the LuxID session. LuxID does not expose an OIDC end_session_endpoint and does not implement RP-Initiated Logout - a single application cannot unilaterally terminate the shared LuxID SSO session. Use this for sensitive applications, shared devices, or when your terms require it.
Design questions:
- What should the user see after logout? A confirmation page? The login page? Your home page?
- Should logout be triggered by inactivity?
- Is your application used on shared devices (kiosks, library computers)? If yes, federated logout is essential.
- Do you need to handle back-channel logout notifications from LuxID?
Decision 8 - error handling philosophy
Federated authentication introduces failure modes that do not exist in username/password systems. Plan for:
| Failure | Recommended handling |
|---|---|
| User cancels at LuxID login | Show a friendly "Sign-in cancelled" message; offer to retry |
access_denied from LuxID | Explain the user declined consent; do not retry automatically |
| Token validation failure | Log the error; do not expose token details to the user; ask them to retry |
| Network error on token exchange | Retry with exponential backoff (max 3 attempts); then show a support message |
| Refresh token expired | Redirect to login; do not silently fail with a blank page |
| LuxID service unavailable | Show a clear, friendly error and a retry option; do not expose internal error details to the user |
Never expose raw OAuth error codes or token contents to end users. Log them server-side with a correlation ID and show a user-friendly message.
See Common errors for the full error code reference.
Decision 9 - branding and UX strategy
LuxID provides the Universal Login page (hosted at https://login.luxid.lu (opens in a new tab)). You do not control the login UI. You do control:
- The login button in your application (must follow LuxID brand guidelines)
- The consent experience before and after the LuxID redirect
- The post-login landing page and onboarding flow
- Links to your Terms and Conditions and Privacy Information shown on the consent screen (optional)
- Additional explicit consents you ask LuxID to present on the consent screen, for example "Allow email usage for newsletters"
Your application should only present the "Sign in with LuxID" button. Do not show your own username/password fields or a "Create an account" prompt - both authentication and new-account creation are handled entirely on the LuxID Universal Login page after the redirect.
Design questions:
- Have you read the Login button guidelines?
- Is "Sign in with LuxID" your primary or secondary authentication method? Primary: make the button prominent. Secondary: place it after your primary method.
- What happens on first sign-in for a new user? Do you need a local provisioning / onboarding flow in your application after receiving the token? (This concerns your own user record - the LuxID Account itself is created on the Universal Login page, not by your application.) See Mapping identities to your application for how to link LuxID users to your own user records and keep the IdP pluggable.
Pre-implementation design checklist
Work through this checklist before writing production code. Each item maps to a decision above.
Protocol
- Chosen protocol: OIDC or SAML
- Chosen flow: Authorization Code + PKCE (OIDC) or SP-initiated (SAML)
- OIDC library selected and evaluated for security maintenance
Authentication strength and MFA
- Baseline minimum
auth_leveldefined (2 = password only, 3/4 = password + MFA, 8 = passkey, 9 = LuxTrust) - Step-up actions identified (if any)
- MFA methods your application will promote to users documented
Claims
- Claim list reviewed and minimised to genuine need
- All requested claims are within LuxID Agreement scope
- Consent screen copy reviewed for clarity
Identity architecture
- Sphere strategy decided (dedicated / shared Partner / shared Organisation)
-
sub→ internal user ID mapping strategy documented - Account linking strategy defined (what happens when a user who already has an account in your system signs in with LuxID for the first time?)
Session and tokens
- Application session lifetime defined
- Refresh token storage strategy documented (server-side only, encrypted)
- Idle timeout policy defined
- Logout strategy chosen (local or federated)
- Post-logout redirect URI registered
Error handling
- Error scenarios enumerated and UX copy written for each
- Server-side error logging with correlation IDs planned
- Support escalation path documented (user sees a message, what next?)
Security
- HTTPS enforced on all redirect URIs (production)
- JWKS key rotation handling planned (library-managed or explicit cache refresh)
- Client Secret storage reviewed (environment variable / secret manager, not source code)
- PKCE implemented (even for confidential clients)
-
stateandnoncevalidation implemented
Branding
- Login button reviewed against Login button guidelines
- First-login / onboarding flow designed
- Post-logout page designed
Security review
- Read Protect your Application before submitting for production approval
Next steps
- Add Login to your app - framework-specific quickstarts
- OpenID Connect - full OIDC reference
- SAML 2.0 - full SAML reference
- Protect your Application - security hardening guide
- Login button guidelines - branding requirements