Skip to content

Surface session AMR in withAuth()/useAuth() result #426

@brett

Description

@brett

Proposed helper

When the WorkOS access JWT carries an amr claim (or equivalent session-MFA signal — see workos/workos-python#655 for the underlying API request), expose it as a typed field on the result of withAuth() and useAuth():

const { user, accessToken, amr } = await withAuth();
// amr: ReadonlyArray<string> | undefined
// e.g. ["mfa", "pwd"] when MFA was used in this session

if (privilegedRoute && !amr?.includes("mfa")) {
  return new Response(null, { status: 403 });
}

Why this is useful

For B2B SaaS apps with compliance constraints (SOC 2 / ISO 27001 ISMS), the BFF often needs to enforce session-MFA (not just MFA-enrollment) before passing requests to the backend. Today withAuth() returns the access token's payload but doesn't surface AMR, so consumers either:

  • Manually decode the JWT in their proxy/BFF (defeats the SDK's value)
  • Make a round-trip to the WorkOS factors API (returns enrollment, not session-MFA)
  • Rely on org-level authentication policies (no per-request verification, no audit trail)

A typed pass-through of amr from the decoded JWT to the withAuth() result keeps consumers in the SDK's idiomatic path.

Dependency

This helper is only useful once the underlying API exposes the signal. Tracking that in workos/workos-python#655 (filed in parallel — same use case, API-shape vs SDK-shape).

If WorkOS internally tracks API-side AMR exposure, this issue is a "pre-stage the SDK helper" ask so authkit-nextjs ships the consumer-side change in lock-step.

Specifics

  • Type: ReadonlyArray<string> | undefined — array form matches the OIDC amr claim spec.
  • Optional in the response type — undefined when the underlying token doesn't carry the claim.
  • Available on both withAuth() (server) and useAuth() (client) for parity.
  • Read from the decoded access JWT in getSession() and forwarded through; no extra network calls.

Happy to send a PR if there's interest. Confirm route first since this depends on the API change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestinvalidThis doesn't seem right

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions