Aller au contenu principal
Version 0.7Brouillon

Authentication levels

Every sign-in to LuxID reaches a strength level: a password alone is weaker than a password plus a second factor, which is weaker than a passkey or LuxTrust. Your Application requests a minimum level, and LuxID enforces it before the flow completes - you never receive a session weaker than you asked for. If you are new to LuxID, read Learn the basics first; this page is the reference for how levels are scored, reported in tokens, and requested.

The auth_level scale

LuxID's native authentication-strength scale is auth_level - a numeric score stored in LuxID's data model as AUTH_LEVEL. It represents the strength of the authentication factors the user presented during a given session. LuxID assigns it automatically based on which methods were completed. Partners cannot set it directly: they request a minimum via configuration or per-request parameters, and LuxID enforces it.

Levels marked not implemented are reserved in the scale but are not active in LuxID.

Authentication methodamr valuesauth_levelStatus
Password only["pwd"]2Implemented
Password + OTP via SMS / voice["pwd", "otp"]3Implemented
Password + TOTP (authenticator app)["pwd", "totp"]4Implemented
(Reserved - kerberos / loginless)-1Not implemented in LuxID
(Reserved - MFA fingerprint)-6Not implemented in LuxID
Passkey (WebAuthn / FIDO2)["fido"]8Implemented
LuxTrust (mobile / smartcard)["luxtrust"]9Implemented

Notes:

  • OTP (SMS or voice) maps to auth_level 3; TOTP (authenticator app) maps to auth_level 4. The two are distinct mechanisms with different delivery channels and different numeric values.
  • Passkey maps to 8 because a phishing-resistant hardware-bound credential is rated stronger than a shared-secret or out-of-band code.
  • LuxTrust reaches 9 because it involves a qualified hardware-backed credential with associated identity proofing.

Where auth_level is used

The auth_level value plays three distinct roles inside LuxID:

  • In each authentication event log - the level the user reached at sign-in is recorded against the authentication event, for audit, analytics and downstream evaluation.
  • As the Application's default minimum - configured per Application with LuxID, this is the floor every sign-in to the Application must meet.
  • In per-action escalation rules - an Application can attach rules that require a higher level for specific operations (for example, browsing = 2, checkout = 3, contract signing = 9). See Step-up authentication below.

auth_level in the ID Token

The auth_level numeric value surfaces in the ID Token as the luxid_auth_level claim (LuxID extension claim). The acr claim conveys LuxID's own classification of the authentication event - expressed in terms of auth_level - not an eIDAS LoA assertion. See the acr claim section below for the value format.

Example ID Token fragment:

{
"acr": "urn:luxid:acr:level:substantial",
"amr": ["pwd", "otp"],
"luxid_auth_level": 3
}

Relationship with eIDAS assurance levels (LoA)

LuxID's position

LuxID is not a notified eID scheme

LuxID is not a notified eID scheme under eIDAS Article 9 (opens in a new tab) and does not issue eIDAS LoA assertions of its own. The acr claim in the LuxID ID Token conveys auth_level (LuxID's own classification), not a formal eIDAS LoA.

LuxID aligns with eIDAS principles structurally. LuxID's three-tier strength model mirrors the Low / Substantial / High rationale from Commission Implementing Regulation (EU) 2015/1502 (CELEX:32015R1502 (opens in a new tab)), but alignment is a design statement, not legal equivalence. Relying Parties operating under eIDAS requirements should seek their own legal assessment of whether LuxID's levels satisfy their regulatory obligations.

Informal comparison table

The table below shows the informal design alignment between auth_level values and eIDAS LoA levels. The comparison is design-aligned, not legally binding.

auth_levelAuthentication methodComparable eIDAS LoA (informal)
2Password aloneLow
3Password + OTP via SMS or voiceSubstantial
4Password + TOTP (authenticator app)Substantial
8Passkey (phishing-resistant, hardware-bound)Substantial
9LuxTrust (hardware-backed qualified credential)High

Formal eIDAS LoA assertions appear in LuxID payloads only when relayed from a qualified upstream - see the next section.

When eIDAS LoA legitimately appears in LuxID payloads

eIDAS LoA values appear in LuxID payloads exclusively as a relay from a qualified upstream source. In each case the LoA was issued by the upstream, not by LuxID.

LuxID Verified (relay from LuxTrust) LuxTrust performs an identity verification at a declared LoA - currently Substantial. LuxID stores and relays that LoA to Partners alongside the verified attributes via the luxid_verification_level claim. The LoA value was issued by LuxTrust S.A. as a qualified trust service provider (LuxTrust S.A. (opens in a new tab)); LuxID acts as the relay.

LuxID Pro federation (relay from a corporate IdP or future notified eID) When an upstream federated IdP provides an LoA value, LuxID interprets it via a Partner-specific regex mapping rule defined between LuxID and the Partner during integration. The mapping links accepted upstream LoA labels to an auth_level in LuxID. The upstream IdP is the source of the LoA claim; LuxID maps it to auth_level for use within the LuxID ecosystem.

Future EUDIW integration When a European Digital Identity Wallet (EUDIW) provides a presentation, the LoA attached to the presentation originates from the EUDIW and the issuing Member State. LuxID will relay and map that LoA to auth_level using the same regex-mapping mechanism described above.


The acr claim in the ID Token

After a successful authentication, LuxID includes the acr (Authentication Context Class Reference) claim in the ID Token. This claim reports the auth_level-based classification reached during that authentication event - it may be equal to or higher than what you requested.

Example acr values (LuxID URN format):

auth_level reachedExample acr claim value
2 (password only)urn:luxid:acr:level:low
3 or 4 (password + second factor)urn:luxid:acr:level:substantial
8 (passkey)urn:luxid:acr:level:substantial
9 (LuxTrust)urn:luxid:acr:level:high

Example ID Token payload fragment:

{
"iss": "https://login.luxid.lu",
"sub": "a3f8b2c1-7e4d-4a1b-9c0f-5d2e8b3a6f1c",
"aud": "your-client-id",
"exp": 1748048400,
"iat": 1748044800,
"acr": "urn:luxid:acr:level:substantial",
"amr": ["pwd", "otp"],
"luxid_auth_level": 3
}
Validation rule

Always verify that the acr value in the received ID Token meets your application's minimum requirement. Do not assume that because you requested a level, the level was reached. An OIDC library will return the acr claim but will not automatically enforce your application's policy - that check is your responsibility.

# Example policy check
REQUIRED_ACR = "urn:luxid:acr:level:substantial"
ACR_ORDER = {
"urn:luxid:acr:level:low": 1,
"urn:luxid:acr:level:substantial": 2,
"urn:luxid:acr:level:high": 3,
}

received_acr = id_token_claims.get("acr", "")
if ACR_ORDER.get(received_acr, 0) < ACR_ORDER[REQUIRED_ACR]:
raise InsufficientAuthLevelError(received_acr)

The amr (Authentication Methods References) claim lists the specific methods used. See Tokens and claims for the full amr value catalogue.


Requesting a minimum level

LuxID provides two complementary mechanisms for requiring a minimum level: static pre-configuration on the Application and per-request escalation parameters.

Requesting a level

The canonical request form is the acr_values authorisation-request parameter carrying a LuxID level URN:

acr_values=urn:luxid:acr:level:low
acr_values=urn:luxid:acr:level:substantial
acr_values=urn:luxid:acr:level:high

Request exactly one value per authorisation request. The set of acr_values accepted for your integration is agreed per Partner during onboarding - confirm your accepted values with LuxID before relying on them.

Static pre-configuration

Set a floor that applies to every authorisation request for an Application, without any per-request parameter:

  • Application default minimum auth_level - the floor that applies to all sign-ins to this Application. If a user's session does not meet this level, Universal Login will prompt them to complete additional factors before the flow can complete.
  • Per-action escalation rules - attached to the Application, these let different operations require different levels (for example, browsing = 2, checkout = 3, contract signing = 9).

Both values are set on the Application registration. See Register an Application for the field reference.

Per-request escalation via acr_values

LuxID handles whatever acr_values the Partner has agreed with LuxID during integration. LuxID uses regex matching to interpret the incoming acr_values parameter against a Partner-specific mapping table defined at integration time. The mapping links accepted values to LuxID's internal auth_level.

The canonical form is the LuxID level URN shown in Requesting a level. Alternative forms may also be agreed for a given integration:

Form 1 - LuxID level URN (canonical):

acr_values=urn%3Aluxid%3Aacr%3Alevel%3Ahigh

Form 2 - Simple numeric:

acr_values=9

Form 3 - Upstream LoA label (from a federated source that emits eIDAS-style values):

acr_values=loa3

LuxID matches the incoming value via the configured regex and maps it to an auth_level. The exact values accepted for a given Partner's integration are defined during onboarding.

Example authorisation request using the canonical LuxID level URN:

GET https://login.luxid.lu/mga/sps/oauth/oauth20/authorize
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https%3A%2F%2Fyour-app.example.lu%2Fcallback
&scope=openid%20profile%20email
&acr_values=urn%3Aluxid%3Aacr%3Alevel%3Ahigh
&state=RANDOM_STATE
&code_challenge=CODE_CHALLENGE
&code_challenge_method=S256

Behaviour:

  • If the user's current LuxID session already meets or exceeds the requested level, LuxID will not re-prompt for credentials (SSO applies, subject to session validity).
  • If the user's session is at a lower level than requested, LuxID will step up authentication by prompting for an additional factor.
  • If the user cannot complete the requested level (for example, no second factor enrolled and a higher level is requested), LuxID will return an access_denied error.

Omitting acr_values: LuxID applies the Application's configured default policy. Because this default depends entirely on your Console configuration, you should set an explicit minimum assurance level appropriate to your Application rather than relying on the unconfigured default. Check your Application settings and configure a minimum that matches the sensitivity of what the Application protects.

Per-request escalation - numeric way (luxid_min_auth_level)

LuxID also supports a proprietary extension parameter, luxid_min_auth_level, that lets you specify a minimum auth_level value numerically on the authorisation request. This is useful when you need to require a specific factor type rather than an abstracted level - for example, when your regulated context mandates LuxTrust specifically (level 9). It complements the per-Application minimum LuxID stores in its backend (see Static pre-configuration): the request parameter raises the floor for a single authorisation request above the Application's configured default.

GET https://login.luxid.lu/mga/sps/oauth/oauth20/authorize
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https%3A%2F%2Fyour-app.example.lu%2Fcallback
&scope=openid%20profile%20email
&luxid_min_auth_level=9
&state=RANDOM_STATE
&code_challenge=CODE_CHALLENGE
&code_challenge_method=S256

When to use each approach:

SituationRecommended parameter
Standard access control (browsing, purchases, account changes)acr_values - portable, standards-aligned
LuxTrust specifically required (bypass acr abstraction)luxid_min_auth_level=9
Analytics or debugging to understand factor adoptionRead luxid_auth_level from issued tokens
Guidance

Default to acr_values for all production use cases. The numeric luxid_min_auth_level parameter is an escape hatch for factor-method specificity; overusing it creates coupling to LuxID's internal scoring and reduces portability if the scheme is ever recalibrated.


When to require each level

The table below provides guidance on matching auth_level to application action. These are recommendations; your application's risk assessment and any applicable regulatory requirements take precedence.

Use caseMinimum auth_levelRationale
Browsing public or personalised content2Low risk; no sensitive data exposed
Viewing account profile, email, phone number2Read-only access to user's own data
Saving preferences, favourites, notification settings2Limited harm if impersonated
Adding items to a cart; initiating a transaction3 or 4Impersonation could cause financial harm
Completing a purchase or payment3, 4, or higherDepends on transaction value and regulatory context
Changing account email address or phone number3 or 4Account takeover risk if impersonated
Changing password from inside an authenticated session3 or 4Credential change; high value target
Accessing sensitive personal data (medical, financial)3, 4, or higherDepends on data sensitivity
Signing a contract or legal document electronically9Legal identity assertion required
Accessing regulated financial services9Sector-specific regulation may apply
Submitting a government-facing service9Legal identity required; audit trail mandatory
Accessing age-gated content requiring identity proof9Age claim requires identity verification

Step-up authentication

Your application may start with a low-strength session and require a higher level only when a sensitive action is triggered - for example, initiating a payment after browsing a catalogue. This pattern is called step-up authentication.

How to implement step-up

When the user triggers a sensitive action:

  1. Check the acr and auth_time claims in the current ID Token.
  2. If the acr is below the required level - or if the authentication is older than your step-up freshness window - initiate a new authorisation request with the required acr_values.
  3. Pass prompt=login if you want to force re-authentication regardless of the existing LuxID session, or omit it if you are willing to allow LuxID to step up silently (for example, by prompting for an additional factor without re-entering the password).
  4. LuxID returns a new authorisation code. Exchange it for a new set of tokens. The new ID Token will carry the stepped-up acr value.
  5. Proceed with the sensitive action.

Example: step up to Substantial (auth_level 3 or higher):

GET https://login.luxid.lu/mga/sps/oauth/oauth20/authorize
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https%3A%2F%2Fyour-app.example.lu%2Fcallback
&scope=openid
&acr_values=urn%3Aluxid%3Aacr%3Alevel%3Asubstantial
&prompt=login
&state=RANDOM_STATE_2
&code_challenge=CODE_CHALLENGE_2
&code_challenge_method=S256

Step-up freshness

Even if the user's LuxID session is at the required level, you may want to ensure the step-up happened recently (for example, within the last 5 minutes) before allowing a high-value action. Use the max_age parameter to enforce this:

&max_age=300

With max_age=300, LuxID will re-prompt for authentication if more than 300 seconds have elapsed since auth_time. The auth_time claim in the returned ID Token confirms when the authentication occurred.

Storing the step-up result

Once you have the higher-level ID Token, you may store the elevated session level in your own application session - there is no need to re-initiate the LuxID flow on every subsequent page load within the same session. Design your session state to record both the acr value and the auth_time so you can enforce freshness windows per action type.


Handling authentication failures

When you request a level the user cannot satisfy, LuxID returns an error on the redirect URI:

ErrorLikely cause
access_deniedUser cancelled, or cannot satisfy the requested level (for example, no second factor enrolled)
unmet_authentication_requirementsThe requested acr_values could not be met by any available method for this user

Your application should:

  1. Detect the error parameter on the redirect.
  2. Display a helpful message - for example, directing the user to enrol a second factor at https://account.luxid.lu/ (opens in a new tab) before retrying.
  3. Not retry the authorisation request automatically in a loop.

Summary

auth_levelKey authentication methodsComparable to (informal)Typical use
2Password aloneLow (informal)Browsing, preferences, read-only profile
3Password + OTP (SMS or voice)Substantial (informal)Purchases, account changes
4Password + TOTP (authenticator app)Substantial (informal)Purchases, account changes
8Passkey (WebAuthn / FIDO2)Substantial (informal)Phishing-resistant passwordless sign-in
9LuxTrust (smartcard or mobile)High (informal)Contracts, regulated services, legal identity

The "Comparable to" column is design-aligned, not a legal eIDAS equivalence.


Mise à jour le 2026-07-02