Aller au contenu principal
Version 0.1Brouillon

Integration security checklist

Why this page

Most OAuth 2.0 and OpenID Connect security incidents come from the same short list of integration mistakes: a missing state check, an unvalidated ID Token, a token left in a URL or a log. This page is a checklist you can walk before go-live and during security reviews.

It is split into two parts on purpose:

  • Part 1 - what you must verify covers the things you are responsible for in your own application code. These are the checks that actually prevent the common attacks.
  • Part 2 - what LuxID enforces for you covers the server-side protections LuxID provides. You do not implement these, but knowing they exist tells you what your integration can rely on - and what you should not try to probe against production.
This is a defensive self-test, not an attack script

The items below are written as checks on your own integration. Do not run active penetration tests, fuzzing, or bypass attempts against LuxID production - that is indistinguishable from an attack on a shared production identity service used by many organisations, and may get your client blocked. If you want to security-test the flow itself, use the sandbox / UAT environment, and report any suspected LuxID-side weakness through the responsible-disclosure channel on the Contact and support channels page (also published as /.well-known/security.txt).

Before you start - know your flow

A quick orientation, so the rest of the checklist is concrete:

  • You use the Authorization Code flow with PKCE (S256). LuxID does not support the deprecated Implicit flow.
  • You know whether you consume OpenID Connect (you receive an ID Token and identify the user) or only OAuth 2.0 (you receive an access token to call an API). Most sign-in integrations are OIDC.
  • You know your client_id, your registered exact redirect_uri(s), and where your client_secret lives (confidential clients only - never in a mobile app or SPA).
  • Your integration reads endpoints from the discovery document (/.well-known/openid-configuration) rather than hardcoding them.

Part 1 - what you must verify in your integration

These are your responsibility. A gap here is a vulnerability in your application.

state - CSRF protection on the callback

  • Your app generates a unique, unpredictable state value for every authorization request (cryptographically random, not a counter or timestamp).
  • Your app stores the value it sent (in the user's session) and rejects the callback if the returned state does not match.
  • Each state is single-use: a replayed or reused state is rejected.
  • A callback that arrives with no state is rejected.

nonce - replay protection on the ID Token (OIDC)

  • Your app sends a unique, unpredictable nonce on every authentication request.
  • Your app validates that the nonce claim in the returned ID Token equals the value it sent, and rejects the token otherwise.
  • Each nonce is single-use; a replayed ID Token (old nonce) is rejected.

ID Token validation (OIDC)

Validate every ID Token against all five OpenID Connect Core 1.0 §3.1.3.7 checks - do not trust a token because it merely decodes:

  • Signature verified against LuxID's JWKS (RS256). See Key management.
  • iss matches the LuxID issuer exactly.
  • aud contains your client_id.
  • If aud contains more than one value, azp is present and equals your client_id.
  • exp is in the future and iat is sane (apply a small clock-skew tolerance - use the smallest your infrastructure allows).
  • nonce matches (see above).

See Tokens and claims and Token validation issues.

redirect_uri and scopes

  • Every redirect_uri your app uses is registered exactly with LuxID and served over HTTPS. LuxID matches redirect URIs exactly; there are no wildcards.
  • Your app requests only the scopes it actually needs; it does not request extra or speculative scopes "just in case".
  • Your app treats the set of claims it receives as the source of truth for what the user consented to - it does not assume it received a scope it did not request.

Token handling and storage

  • Access and refresh tokens are never placed in URLs (no tokens in query strings, no tokens in redirects).
  • Tokens and the authorization code are never written to logs, analytics, or error trackers.
  • Refresh tokens are held in platform secure storage (Keychain / Keystore / encrypted server-side store), never in localStorage or a plain file.
  • client_secret (confidential clients) is held server-side only, never shipped in mobile or SPA code.
  • Your app validates the access token's exp before use and refreshes proactively rather than on error.

Session and logout

  • Signing out of your application clears your own application session; you do not assume it ends the LuxID SSO session (it does not - see Session management).
  • Where appropriate, you revoke refresh/access tokens on logout via the revocation endpoint.

Part 2 - what LuxID enforces for you

You do not implement these - LuxID does. They are listed so you know the protections your integration relies on. Do not actively test these against production (see the caution above); if you need to see the behaviour, use the sandbox / UAT.

  • redirect_uri validation. LuxID rejects any redirect_uri that does not exactly match a registered value. There is no partial or wildcard matching to bypass.
  • response_type handling. LuxID accepts only the response types it supports (Authorization Code); it does not silently fall back to weaker modes.
  • Malformed authorization requests. Missing, duplicated, or empty required parameters are rejected rather than guessed.
  • Authorization code single-use. A code can be redeemed once. Reuse, replay, or redemption of an expired code is rejected, and reuse of an already-redeemed code invalidates the associated tokens.
  • Code binding. An authorization code is bound to the client and the PKCE code_verifier that requested it - a code issued for one client/session cannot be redeemed by another.
  • Concurrency. Race conditions on code redemption resolve to a single successful exchange.
  • state and nonce are echoed, not validated for you. LuxID returns your state and reflects your nonce into the ID Token, but validating them is your job (Part 1) - their security value comes from your check, not from LuxID.
remarque

If, while building against the sandbox, you observe behaviour that contradicts this list, treat it as a potential finding and report it through the responsible-disclosure channel - do not keep probing. LuxID commissions its own authenticated penetration tests; coordinated reports are welcome, unsolicited production attacks are not.

How to use this checklist

  • Before go-live: walk Part 1 end to end. Every box must be checked for relying-party approval - it maps directly to the security baseline.
  • During a security review: use Part 1 as the audit scope for your own code, and Part 2 as the boundary of what belongs to LuxID.
  • When something looks wrong on LuxID's side: stop testing and use Contact and support channels.
Mise à jour le 2026-07-03