Aller au contenu principal
Version 0.3Brouillon

Multi-factor authentication

What is multi-factor authentication on LuxID?

Multi-Factor Authentication (MFA) on LuxID requires users to provide a second proof of identity in addition to their password.

LuxID supports four MFA methods, each targeting a different user population and security profile. All MFA prompting and orchestration happens within Universal Login at https://login.luxid.lu (opens in a new tab) - your application does not implement any MFA logic.

The result of MFA is expressed in two token claims:

  • amr (Authentication Methods References) - an array listing which authentication methods the user completed during the session
  • acr (Authentication Context Class Reference) - LuxID's auth_level-based classification of the authentication event (not a formal eIDAS LoA assertion)

MFA methods

One-time codes - SMS and voice (amr: "otp")

LuxID delivers a randomly generated numeric code to the user's registered phone number by SMS. If the SMS is not received within the expected time, the user can request delivery by voice call instead.

This method is defined in LuxID's tag vocabulary as otp - it is a randomly generated code delivered out-of-band. It is distinct from totp (authenticator app codes derived from a shared secret).

Assurance level: Substantial (when combined with password).

User prerequisite: A phone number registered on the user's LuxID Account (opens in a new tab).

Considerations for Partners: SMS delivery depends on the user's mobile network and may be delayed in some regions or for roaming users. Voice call fallback mitigates most delivery failures. LuxID manages SMS and voice delivery; Partners are not involved in this process.

For user-facing guidance on setting up One-Time Codes, see https://www.luxid.lu/en/getting-started/setup-2fa (opens in a new tab).

Authenticator app TOTP (amr: "totp")

Users configure a Time-based One-Time Password (TOTP) authenticator app - such as Aegis (Android), FreeOTP, Authy, or Microsoft Authenticator - by scanning a QR code in their LuxID Account (opens in a new tab). The app generates a new six-digit code every 30 seconds, derived from a shared secret using the TOTP algorithm (RFC 6238).

TOTP codes are generated offline on the user's device and do not require a network connection or SMS delivery at authentication time. This makes TOTP more resilient than OTP in poor-connectivity environments.

Assurance level: Substantial (when combined with password).

User prerequisite: An authenticator app installed and configured on the user's device.

Note on terminology: In LuxID, totp refers specifically to authenticator-app-based codes derived from a shared secret. Do not conflate with otp (SMS/voice random codes). The two are distinct methods with different security properties and different amr values.

Passkeys - WebAuthn/FIDO2 (amr: "fido")

Passkeys use public-key cryptography anchored to a hardware authenticator - either a platform authenticator built into the user's device (Apple Touch ID / Face ID via iCloud Keychain, Google Password Manager, Windows Hello) or a roaming hardware key (YubiKey, etc.).

Because the private key never leaves the device, passkeys are inherently phishing-resistant: a fake login page cannot trigger a valid passkey assertion because the cryptographic challenge is bound to the origin (login.luxid.lu).

Assurance level: Substantial. A passkey alone, or a passkey combined with LuxID Verified, reaches Substantial assurance. High assurance requires LuxTrust as the authentication method.

amr value: "fido" - LuxID's amr value for a WebAuthn / passkey (FIDO2) authentication.

User prerequisite: A passkey registered on the user's LuxID Account. Users can manage passkeys at https://account.luxid.lu/ (opens in a new tab). Public help: https://www.luxid.lu/en/resources/passkeys (opens in a new tab).

For the full passkey integration story, see Passwordless and passkeys.

LuxTrust (amr: "luxtrust")

LuxTrust is Luxembourg's national PKI-based authentication infrastructure. LuxID supports LuxTrust as an MFA method in two form factors:

  • LuxTrust Mobile app - a mobile authenticator
  • LuxTrust Smartcard - a PKI smartcard (requires a card reader)

The amr value "luxtrust" is a LuxID extension not present in the standard IANA registry, reflecting the fact that LuxTrust is a country-specific mechanism. Partners should treat it as equivalent to a hardware-backed MFA method for assurance purposes.

Assurance level: High (when combined with password and LuxTrust proofing), or Substantial (LuxTrust used as second factor without full identity proofing).

User prerequisite: An active LuxTrust subscription. LuxTrust is operated independently of LuxID; users obtain LuxTrust credentials from LuxTrust S.A. LuxID and LuxTrust are complementary - neither service is subordinate to the other.

Use cases: LuxTrust as MFA is particularly relevant for access to regulated services (e-government, banking, notarial services) where High assurance is required.

Authentication level per method

LuxID classifies each authentication path on an internal numeric scale, auth_level. Partners can require a minimum auth_level per Application (or per action). The numeric scale is finer-grained than a three-tier model, which lets a Partner say "I want LuxTrust specifically" rather than just "I want the highest-strength tier".

Methodamr valueauth_levelComparable to (informal)
Password only["pwd"]2Low
Password + OTP via SMS / voice["pwd","otp"]3Substantial
Password + TOTP (authenticator)["pwd","totp"]4Substantial
Passkey (WebAuthn / FIDO2)["fido"]8Substantial
LuxTrust (mobile / smartcard)["luxtrust"]9High

These comparisons are informal and design-aligned. LuxID is not a notified eID scheme and does not emit formal eIDAS LoA assertions; the auth_level scale is LuxID's own classification. Formal LoA assertions can appear in LuxID payloads only when relayed from a qualified upstream - see Authentication levels.

When you care about the factor specifically (for example, "I require LuxTrust"), use the numeric auth_level knob. When you care about overall trust (the highest-strength tier), use acr_values. The two are related but not identical: auth_level >= 9 is the sole path to urn:luxid:acr:level:high.

The Application registration exposes both a default minimum auth_level for all sign-ins and per-action escalation rules for individual operations. See Authentication levels for the full scale, the informal comparison table, and the runtime request patterns; see Register an Application for the configuration fields.

Token claims

amr - authentication methods references

The amr claim is an array of strings. Each element identifies one authentication method the user completed during the session.

Methodamr value
Password"pwd"
SMS / voice one-time code"otp"
Authenticator app TOTP"totp"
Passkey (WebAuthn/FIDO2)"fido"
LuxTrust"luxtrust"

These five values are the complete amr catalogue - it matches the reference in Tokens and Claims.

A typical MFA session with password plus SMS OTP produces:

{
"amr": ["pwd", "otp"]
}

A passkey-only (passwordless) session produces:

{
"amr": ["fido"]
}

A password plus LuxTrust session:

{
"amr": ["pwd", "luxtrust"]
}

acr - authentication context class reference

The acr claim conveys LuxID's auth_level-based classification of the authentication event. LuxID uses three acr tiers, expressed as URNs:

acr valueauth_level rangeTypical method combination
urn:luxid:acr:level:low2Password only (no MFA)
urn:luxid:acr:level:substantial3, 4, or 8Password plus any MFA method; or passkey
urn:luxid:acr:level:high9LuxTrust (hardware-backed qualified credential)

These tiers are LuxID's own classification; they are not formal eIDAS LoA assertions. See Authentication levels for the full auth_level model and the relationship with eIDAS principles.

auth_time

The auth_time claim is the Unix timestamp of when the authentication event completed on Universal Login. It reflects the actual moment the user satisfied the required factors, not the time the token was issued.

Full example ID Token (password + SMS OTP)

{
"iss": "https://login.luxid.lu",
"sub": "a3f2c1d8-9b4e-4a2f-8c1d-3e7b9a2f1c4d",
"aud": "app_mypost_prod",
"iat": 1748476800,
"exp": 1748480400,
"auth_time": 1748476800,
"nonce": "n-0S6_WzA2Mj",
"acr": "urn:luxid:acr:level:substantial",
"amr": ["pwd", "otp"],
"email": "utilisateur@example.lu",
"email_verified": true,
"name": "Marie Dupont",
"given_name": "Marie",
"family_name": "Dupont"
}

Full example ID Token (passkey passwordless)

{
"iss": "https://login.luxid.lu",
"sub": "a3f2c1d8-9b4e-4a2f-8c1d-3e7b9a2f1c4d",
"aud": "app_mypost_prod",
"iat": 1748476900,
"exp": 1748480500,
"auth_time": 1748476900,
"nonce": "x-7Kp2mBnQ4",
"acr": "urn:luxid:acr:level:substantial",
"amr": ["fido"],
"email": "utilisateur@example.lu",
"email_verified": true,
"name": "Marie Dupont",
"given_name": "Marie",
"family_name": "Dupont"
}

Configuration

Minimum authentication level per Application

Each Application can specify a default minimum auth_level. If a user attempts to sign in with a session that does not meet the minimum, Universal Login will prompt them to complete an additional factor before the authorisation flow can complete.

auth_level floorEffect
2 (default)Password only is accepted. No MFA is required.
3 or 4At least one MFA method (OTP or TOTP) must be completed in addition to the password.
8A passkey is required as the authentication method.
9LuxTrust is required. auth_level 9 is the sole path to urn:luxid:acr:level:high.

Setting a minimum authentication level is the recommended approach for applications handling sensitive operations or personal data.

Step-up authentication

For applications that handle a mix of low-risk and high-risk operations, you can request a higher assurance level for specific flows using the acr_values parameter on the authorisation request. LuxID will prompt the user to complete additional factors if the current session does not already satisfy the requested level.

GET https://login.luxid.lu/mga/sps/oauth/oauth20/authorize
?client_id=<your_client_id>
&response_type=code
&redirect_uri=<your_callback>
&scope=openid profile email
&acr_values=urn:luxid:acr:level:substantial
&prompt=login
&state=<state>
&nonce=<nonce>

The canonical acr_values request form is urn:luxid:acr:level:low, urn:luxid:acr:level:substantial, or urn:luxid:acr:level:high - symmetric with the response acr claim. The accepted request values are agreed per Partner during onboarding.

Use prompt=login alongside acr_values when you want to guarantee a fresh authentication rather than accepting a cached session that already meets the assurance level.

After completing step-up, verify the acr claim in the returned ID Token before proceeding with the sensitive operation. Do not rely solely on the fact that the authorisation flow completed.

Requesting a specific MFA method

There is no standard request parameter to require a specific MFA method. LuxID's assurance model is level-based, not method-based: you request a level via acr_values (canonical form urn:luxid:acr:level:low|substantial|high, with the accepted values agreed per Partner during onboarding) and LuxID enforces it using whichever eligible method the user has enrolled.

Two practical consequences:

  • To require any MFA, request acr_values=urn:luxid:acr:level:substantial.
  • To require LuxTrust specifically, request acr_values=urn:luxid:acr:level:high - LuxTrust (auth_level 9) is the sole path to the High tier.

If your Application has a contractual or regulatory requirement for another specific method (for example, passkeys only), discuss it with LuxID during onboarding.

Recovery paths

If a user cannot complete MFA - for example, because they have lost their phone - LuxID provides recovery paths within Universal Login:

  • SMS OTP not received: Request delivery by voice call instead. If the phone is lost entirely, the user must contact LuxID.
  • TOTP codes not available (lost device): The user must contact LuxID to initiate account recovery. LuxID verifies identity through a separate process before removing the TOTP factor.
  • Passkey not available: If the passkey device is unavailable, LuxID falls back to password plus another available MFA method. If no other method is enrolled, the user must contact LuxID.
  • LuxTrust not available: The user contacts LuxTrust S.A. directly to recover their LuxTrust credential.

If you lose access to your MFA factor, contact LuxID. LuxID verifies your identity before making any change to your MFA settings.

Partners are not involved in MFA recovery flows. LuxID handles all recovery communication directly with the user.

Security and privacy notes

attention
Verify acr in your token

After an authorisation flow completes, always check the acr claim in the ID Token to confirm the assurance level actually reached. Do not assume that the authorisation flow completing means the minimum acr was satisfied - verify the value rather than inferring it from a successful flow.

amr is informational. The amr array tells you which methods were used but does not by itself constitute an authorisation decision. Use acr for access control decisions.

MFA is enforced by LuxID. Partners cannot bypass the minimum assurance level configured in the Console by manipulating the authorisation request parameters. LuxID enforces the requirement server-side.

Do not cache auth_time across sessions. A user who completed MFA in a previous session and is silently re-authenticated will present the original auth_time. If your application requires a recent MFA completion, use prompt=login and max_age=0 to force a fresh authentication, then check auth_time in the resulting token.

Privacy. The amr claim reveals which authentication methods a user has enrolled. Consider whether your application needs to log or store the amr claim, and apply appropriate data minimisation.

Mise à jour le 2026-07-02