LSC
LSC Tools

Concepts

Auth Flow

The LSC platform supports two integration patterns. External and vendor apps use standard OIDC. First-party LSC apps use a session bridge that skips the redirect loop.

Pattern 1 — OIDC (external apps)

Any application with a registered client_id can authenticate users through the LSC Identity Provider using the standard OpenID Connect authorization-code flow with PKCE. The IDP handles provider selection, MFA, and corporate SSO. Your app only sees the resulting ID token.

  1. 1

    User hits a protected route

    Your middleware detects no local session and redirects to your login route, passing ?callbackURL= so the user lands back where they started.

  2. 2

    Login route generates PKCE and redirects to the IDP

    Server-side: fetch the discovery document, generate code_verifier + code_challenge + state + nonce, store them in short-lived httpOnly cookies, and issue a 302 to the IDP authorize endpoint.

  3. 3

    IDP authenticates the user

    The IDP shows its own login UI — Microsoft Entra SSO by default. Your app is not involved. The user's corporate credentials are never sent to your application.

  4. 4

    Browser returns to your callback with ?code=&state=

    Read the stored state cookie and verify it matches. A mismatch means the request was not initiated by your app — abort immediately.

  5. 5

    Server-to-server token exchange

    POST to the IDP token endpoint with the code, code_verifier, client_id, client_secret, and redirect_uri. Receive an id_token. This exchange happens entirely on your server — the browser never sees the token.

  6. 6

    Verify the ID token and create a local session

    Verify the id_token signature using the IDP JWKS endpoint. Extract sub, email, name, and lsc_id. Write an encrypted local session cookie (AES-256-GCM). Redirect to the original callbackURL.

IDP endpoints — all derived from the discovery document at https://dev-auth.lifescienceconnect.com/.well-known/openid-configuration/api/auth. Fetch it at startup and cache — it changes rarely.

See the OIDC Integration example for complete, runnable route code.

Pattern 2 — Session bridge (first-party apps)

First-party apps hosted on LSC domains share a session with the IDP and use a bridge token handshake instead of a full OIDC redirect. This avoids the round-trip to the IDP authorize endpoint on every app load.

  1. 1

    App loads — check for an existing local session

    If the app's own encrypted session cookie is present and valid, the user is considered authenticated. No IDP call needed.

  2. 2

    No local session — check for a bridge token

    The IDP sets a short-lived signed bridge token in a shared cookie after sign-in. The app checks for this cookie on the callback route.

  3. 3

    Exchange the bridge token

    Verify the bridge token signature using the platform JWKS. Extract the lsc_id and user claims. Write the app's own encrypted local session. The bridge token is consumed — set it to expire.

  4. 4

    No bridge token — redirect to the IDP

    If neither session nor bridge token is present, redirect the user to the IDP sign-in page. After authentication the IDP issues a new bridge token and redirects back.

For external integrations — use OIDC (Pattern 1). The session bridge is an internal mechanism for first-party LSC apps sharing the IDP domain. External apps cannot access the bridge cookie.

Token types

ID tokenShort — minutes

sub, email, name, lsc_id, iss, aud, exp

Returned by the token exchange. Verify with IDP JWKS. Never store raw — extract claims into your own session.

Bridge tokenVery short — seconds to minutes

lsc_id, user claims, nonce

Shared-cookie mechanism for first-party apps only. Single-use.

Local sessionConfigurable — typically 8h

Whatever your app extracted from the ID token or bridge token

AES-256-GCM encrypted, httpOnly cookie. Your app owns this — the IDP never sees it again.

Security checklist

  • Always verify state before exchanging the code. A mismatch is a sign of a CSRF attempt.
  • Token exchange is server-to-server only. Never call the token endpoint from the browser — it requires your client_secret.
  • Never store the raw id_token in a cookie. Extract the claims you need and re-encrypt a short-lived local session.
  • Do not call /api/auth/sign-in/social directly. That is an internal IDP endpoint for first-party LSC apps. External apps must always go through /api/auth/oauth2/authorize.
  • Validate callbackURL before redirecting. If your login route accepts a ?callbackURL= parameter, anchor it to your own origin before using it — otherwise it is an open redirect. Use new URL(callbackURL, request.url) and verify the resulting .origin matches your app before issuing the redirect.
Your privacy choices