Use case
We're a B2B SaaS running AuthKit-managed SSO via workos-python 5.x. Our ISMS (SOC 2 / ISO 27001 controls) requires us to enforce MFA for the current session at the API request boundary — not "is the user MFA-enrolled". For a privileged action we need to answer "did this user MFA when this session was established?", and 403 if not.
What's missing
We can't answer that question with WorkOS today:
- JWT templates explicitly cannot expose
session.amr or MFA info (template surface is user / organization / organization_membership only).
- Standard access JWT has no
amr or acr claim. Confirmed in our dev environment — the JWT contains:
client_id, email, email_verified, exp, iat, iss, jti, name,
org_id, permissions, role, roles, sid, sub
load_sealed_session().authenticate() / authenticate_with_session_cookie decode the JWT internally but only surface named claims (sid, org_id, role, roles, permissions, entitlements, feature_flags). Anything else is dropped.
authentication.mfa_succeeded webhook has user_id, email, ip_address, user_agent but no session_id, so correlation with session.created is heuristic (user_id + close timestamp + IP/UA match). Not cryptographically tied to a session; insufficient for audit evidence.
list_authentication_factors answers enrollment, not session-MFA. A user with TOTP enrolled who logged in password-only would register as "MFA'd" under this signal.
- AuthKit Actions are Allow/Deny only; can't mint custom JWT claims or attach session attributes.
- Organization Authentication Policies can require MFA at the org level, but the policy is toggleable, doesn't appear in the token, and gives no per-request verification.
What we'd want (any one of these)
In priority order:
amr claim in the access JWT (standard OIDC, e.g. ["mfa"] or ["pwd", "totp"]). Would let the API verify session-MFA without an extra round-trip. Cleanest answer.
session_id on the authentication.mfa_succeeded webhook payload. Lets us build a (session_id → mfa_verified_at) table from webhook events and tie session establishment to MFA cryptographically. Less convenient than (1) but workable.
- Custom-claim minting in AuthKit Actions. Lets us write a one-line Action that copies AMR from session context to a JWT claim ourselves. Most flexible; works for adjacent use cases (custom roles, feature flags, etc.).
Why filing here
Not strictly an SDK issue — the underlying API change is what unblocks this. But since workos-python is the SDK we use, and the SDK's AuthenticateWithSessionCookieSuccessResponse would need to surface amr even if the API shipped it, recording the request here.
If there's a better place to route this (internal tracker, support ticket, public roadmap), happy to mirror.
Related
- Cross-link: same ask filed on
workos/authkit-nextjs for the consumer-side SDK helper. (will paste link after filing)
Use case
We're a B2B SaaS running AuthKit-managed SSO via
workos-python5.x. Our ISMS (SOC 2 / ISO 27001 controls) requires us to enforce MFA for the current session at the API request boundary — not "is the user MFA-enrolled". For a privileged action we need to answer "did this user MFA when this session was established?", and 403 if not.What's missing
We can't answer that question with WorkOS today:
session.amror MFA info (template surface isuser/organization/organization_membershiponly).amroracrclaim. Confirmed in our dev environment — the JWT contains:load_sealed_session().authenticate()/authenticate_with_session_cookiedecode the JWT internally but only surface named claims (sid,org_id,role,roles,permissions,entitlements,feature_flags). Anything else is dropped.authentication.mfa_succeededwebhook hasuser_id, email, ip_address, user_agentbut nosession_id, so correlation withsession.createdis heuristic (user_id + close timestamp + IP/UA match). Not cryptographically tied to a session; insufficient for audit evidence.list_authentication_factorsanswers enrollment, not session-MFA. A user with TOTP enrolled who logged in password-only would register as "MFA'd" under this signal.What we'd want (any one of these)
In priority order:
amrclaim in the access JWT (standard OIDC, e.g.["mfa"]or["pwd", "totp"]). Would let the API verify session-MFA without an extra round-trip. Cleanest answer.session_idon theauthentication.mfa_succeededwebhook payload. Lets us build a(session_id → mfa_verified_at)table from webhook events and tie session establishment to MFA cryptographically. Less convenient than (1) but workable.Why filing here
Not strictly an SDK issue — the underlying API change is what unblocks this. But since
workos-pythonis the SDK we use, and the SDK'sAuthenticateWithSessionCookieSuccessResponsewould need to surfaceamreven if the API shipped it, recording the request here.If there's a better place to route this (internal tracker, support ticket, public roadmap), happy to mirror.
Related
workos/authkit-nextjsfor the consumer-side SDK helper. (will paste link after filing)