Expose session AMR / MFA-this-session signal in access JWT or webhook
## 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](https://workos.com/docs/authkit/jwt-templates) (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](https://github.com/workos/workos-python/blob/master/workos/session.py) (`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](https://workos.com/docs/authkit/actions); 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:
1. **`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.
2. **`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.
3. **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)
1 条评论