- Add a test-only deep link handler in your app.
- Gate that handler with Revyl launch variables.
- Open one deep link from
revyl device navigateor a YAMLnavigatestep.
Fastest Path For Expo Cloud Agents
Use this path when you already run an Expo development client throughrevyl dev.
Copy This Contract
Use one route shape across every framework:App Checklist
Your app owns four small pieces:- Read
REVYL_AUTH_BYPASS_ENABLEDandREVYL_AUTH_BYPASS_TOKENat app launch. - Register a handler for
myapp://revyl-auth. - Verify the token, role, and redirect before changing app state.
- Create a test-only session and route only to an allowlisted destination.
Framework Recipes
Pick the recipe closest to your app. The session creation and route names are app-specific, but the Revyl contract stays the same.Expo / Expo Router
Expo / Expo Router
Put the handler near your root layout so it catches initial links and links opened while the app is running.In managed Expo apps, JavaScript may not receive native launch values automatically. Use a small native config bridge, verify the token with a staging backend, or follow the Bug Bazaar sample’s demo fallback for a local fixture only.For Expo Router apps, add a route backstop such as
app/revyl-auth.tsx that calls the same handler from route params. Expo Router may treat myapp://revyl-auth?... as a normal app route while the development client is already running; the route backstop keeps rejected links visible instead of landing on an unmatched-route screen.React Native CLI
React Native CLI
Use React Native For iOS simulators and physical devices, expose environment-variable
configurations from the compatible
Linking for the deep link and read launch config from your native layer or staging backend.-KEY value pairs in
ProcessInfo.processInfo.arguments. These pairs are distinct from explicit
iOS argument sets, which are passed as raw ordered tokens. For Android,
expose environment configurations from the launch Intent extras.Native iOS
Native iOS
On iOS simulators and physical devices, Revyl encodes environment-variable
configurations as compatible launch-argument pairs:
Call
-REVYL_AUTH_BYPASS_ENABLED true -REVYL_AUTH_BYPASS_TOKEN <token>.handleRevylAuthBypass(_:) from your SwiftUI .onOpenURL handler or your app delegate URL handler.Native Android
Native Android
Revyl injects launch variables into Android as string extras on the app launch intent.Store
revylAuthConfig(launchIntent) when the app starts, then call handleRevylAuthBypass(intent, config) from onCreate and onNewIntent.Flutter
Flutter
Flutter apps usually handle the link in Dart and read launch config through a platform channel or staging backend.Implement the platform channel with the native iOS and Android launch-config snippets above, or verify the token against your staging backend from Dart.
Mint The Token Per Session
The contract above expectsREVYL_AUTH_BYPASS_TOKEN to already exist as an
organization launch variable. That works while the token is long-lived, but
breaks as soon as it expires or has to be minted per run. Add
session.before_script and the CLI mints it for you before every iOS or
Android device session. Web (alpha) starts do not run session.before_script; use
session.auth_bypass.sign_in
for worker-minted Web sign-in, and make sure any data a Web proof needs already
exists in the preview environment, for example seeded by the preview’s own
deploy or a test-login route. For the exact attach order on
revyl device start (config discovery, mint → launch env → deep link), see
Auth And Session Prep.
session.before_script produces values and session.auth_bypass consumes them.
The script is any executable resolved relative to the Revyl project root (the
directory that owns .revyl/) and run with that directory as the working
directory. The path may leave the project directory via ../ as long as it
stays inside the git worktree. Every KEY=VALUE line it prints on standard
output becomes a launch variable for that one session; every other line is
ignored, so it can log freely:
- A non-zero exit fails session start. Validating an unprepared app is worse
than not validating it, so setup failures are never downgraded to warnings. -
A deep link must take all of its
${VAR}placeholders from the script or none of them. Mixing the two sources is rejected before the session starts, because only organization launch variables resolve server-side. - Keep the script executable (chmod +x). Resolve it relative to the Revyl project root; it may leave that directory via../but paths outside the git worktree are rejected. - Depend only on credentials already in the environment, such asREVYL_API_KEY. A coding agent runningrevyl device startin a fresh checkout has no other repository secrets.
revyl dev status reports
the produced key names only (the runtime status field remains before_session):
revyl dev auth refresh re-fires the configured deep link; it does not remint
before-script values. Launch environment is fixed at session start. If a
minted token expired, run revyl dev stop then revyl dev so a fresh mint is
applied.
Give Proofs An Account That Can Reach The Change
Auth bypass decides which account a session signs in to. A proof of changes can only exercise the screens that account can reach. A bypass can work and still block the proof when the account is in the wrong state. For example, it may still be in a setup or calibration period, have no data for the changed screens, or have already finished the onboarding a pull request changes. Use one of these, simplest first:- A dedicated proof account. Create a non-production account that already has the data, progress, and permissions your proofs need. Use it only for Revyl sessions, so people and other tests do not change its state.
- Reset the account when the link signs in. Have the
revyl-authhandler call a staging-only endpoint that checks the bypass token, resets or seeds the proof account, and returns its session. For example, the endpoint can finish calibration, add sample data, or clear onboarding. - Reset it before the device starts. Add a
session.before_scriptthat resets or seeds the account and prints the launch values for that session (see Mint The Token Per Session). The script runs in the proof’s checkout with only credentials already in its environment, such asREVYL_API_KEY, so the endpoint it calls cannot need another repository secret. - One account per state. Use the contract’s
roleparameter to choose between prepared accounts, for examplerole=onboardedandrole=new-user. Allowlist each role in the handler.
What To Verify
Before relying on the bypass in a test, confirm each case is visible:- Valid token, role, and redirect signs in and routes to the target screen.
- Wrong token is rejected.
- Missing or disabled
REVYL_AUTH_BYPASS_ENABLEDis rejected. - Unknown role is rejected.
- Unknown redirect is rejected.
- The handler is unavailable in production builds.
Bug Bazaar Sample
The public Bug Bazaar repository is a runnable Expo sample of this pattern:REVYL_AUTH_BYPASS_TOKEN into native launch config or verify the token with a staging backend.