Testing Authenticated Flows with JWT Input
Some flows are designed to run in the context of an already-authenticated user — for example, a step-up MFA challenge, a profile update flow, an impersonation flow, or any other post-authentication journey. When you click Run in the Descope Console to test these flows, the runner starts a fresh, unauthenticated session by default. This means user.loggedIn will be false and any flow logic that depends on an existing session (user context, jwtClaims, refresh token presence) will follow the unauthenticated path.
To simulate an authenticated user in the flow runner, you can provide a refresh JWT as input before running the flow. The runner will use it to establish a user session, populating user.loggedIn, user.* dynamic values, and jwtClaims — exactly the same way the mobile SDKs pass a refreshJwt when starting authenticated flows.
What the JWT input does and doesn't do
Providing a JWT sets the session context for the flow run — it makes user.loggedIn true and populates user.* values from the token. It does not automatically skip authentication steps within the flow. Whether those steps are bypassed depends on how the flow is designed: a flow that checks user.loggedIn and branches around its email/OTP step will skip it; a flow that always presents that step regardless will still present it. The JWT is most useful when testing flows that are explicitly built to detect and act on an existing session.
How to Provide a JWT to the Flow Runner
- Open the flow you want to test in the Descope Console.
- Click the Run button at the top right of the flow editor.
- In the runner panel, click the Configure button.
- Add a new Input and set
jwtas the key. - Paste a valid refresh JWT as the value for the user you want to test as.
- Click Run to start the flow — the session will be initialized with that user's context.
You can obtain a refresh JWT for a test user by completing a sign-in flow and copying the refreshJwt from the browser's session storage or by calling the appropriate Descope SDK method in your application.
Common Use Cases
Post-authentication flows
Flows that update user profile data, add authentication methods, or branch based on user.loggedIn require an active session to take the correct path. Providing a JWT makes user.loggedIn true so the flow follows the authenticated branch — without it, the runner would always follow the unauthenticated path regardless of how the flow is designed.
Step-up authentication
Step-up flows prompt an already-authenticated user to re-verify their identity before accessing sensitive resources (e.g., re-entering a password or completing an MFA challenge). The JWT doesn't skip the step-up challenge itself — the user still needs to complete it — but it ensures the flow reaches the step-up screen rather than falling back to a full login screen. Without a JWT, the flow would treat the runner as an unauthenticated session and route to the login path instead.
Impersonation
Impersonation flows allow an admin to act on behalf of another user. Because these flows check the identity and roles of the initiating user via user.project.roles or similar dynamic values, providing a JWT for the admin account lets you confirm that role checks and impersonation actions behave correctly.
Multi-factor enrollment
Flows that enroll a user in TOTP, passkeys, or other additional factors typically check whether the user already has a factor set (e.g., user.totp, user.webauthn) before presenting the enrollment screen. Supplying a JWT for an existing user lets you test both the already-enrolled and not-yet-enrolled branches.
Related Resources
- Authenticated Flows (mobile) — how to pass a refresh JWT when starting flows from mobile SDKs
- Troubleshooting Flows — full flow runner documentation
user.loggedIncondition — branching based on authentication status- Dynamic Values — full reference for
user,jwtClaims, and other context keys available in flows