Skip to main content
When .revyl/config.yaml declares session.before_script and/or session.auth_bypass, revyl device start (and revyl dev) run the before-script and apply mobile auth-bypass settings automatically for iOS and Android sessions. Web sessions use session.auth_bypass.sign_in instead. You do not pass tokens on the command line. For the app-side deep-link contract and mint-script shape, see Auth Bypass Deep Links. This page covers what the CLI does on device start.
Web is in alpha. To add it to your organization, email [email protected].
For a web app with a test-only sign-in route, configure a worker-minted link:
secret names a secret key-value launch variable in your organization, not its value. The CLI and MCP send only the name; the trusted worker reads the bound variable and opens <build-origin><path>?code=… before handing over the session. Web starts do not run session.before_script or the mobile launch-variable or deep-link preparation pipeline. Use session.auth_bypass.sign_in for Web sign-in; any data a Web proof needs must already exist in the preview environment, for example seeded by the preview’s own deploy or a test-login route. A pull request comment’s Open preview link signs its Web preview in with the project’s published sign_in, as mobile previews apply auth_bypass; the pull request’s own config cannot change it. For Next.js App Router and static Vite examples, see the manual Web setup guide. path must start with a single / and cannot contain a query, fragment, backslash, or whitespace. It is limited to 512 characters. Every code expires after 120 seconds. The app’s sign-in handler chooses the destination after exchanging the code; Revyl does not send a redirect parameter. The code is an HS256 compact JWS signed with the UTF-8 secret. The app must verify its signature, iss: "revyl", aud matching the lowercase build origin without a default port, sub: "default", and integer iat and exp: iat + 120 timestamps. It must consume each jti (16 random bytes encoded as unpadded base64url) only once, then exchange the code for its own session. The worker waits up to 30 seconds to leave the sign-in path on the same origin; otherwise startup fails with sign_in_failed. The secret and code are not included in workflow inputs or reports, and recording starts after the redirect. Session metadata retains only the selected variable ID to authorize the worker’s secret read. The config block is accepted in shared project configuration, but only Web sessions act on it. Existing mobile behavior below is unchanged.

Per-session environment overrides

A managed Web session can replace or add to its app’s environment for that session only, for example to point the app at a pull request’s backend behind a public tunnel. Pass each value with --launch-env, the same flag mobile starts use, and no configuration change is needed:
--launch-env KEY=VALUE is a plain override. --launch-env NAME with no = is a secret override: the CLI reads its value from the local environment variable NAME, so the value is never a command argument, never printed, and never written to session metadata. MCP launch_env takes plain values only, because a secret value would pass through the agent’s tool arguments. An override replaces the organization’s value for one of the run’s env_keys or adds a new variable to the app process. Names must match [A-Za-z_][A-Za-z0-9_]{0,127}. A session takes at most 32 overrides, each value is at most 4,096 bytes with no control characters, and names plus values together stay within the runtime’s 128 KiB environment limit. A pull request preview start (scm_preview_id) takes no overrides. The runtime owns PATH, HOME, LANG, PORT, HOSTNAME, and WEB_APP_BOOTSTRAP, and names starting with DYLD_, SIMCTL_CHILD_, or COGNISIM_ are reserved, so overrides can’t use them. A plain override can’t use a name in the run’s secret_names or an encrypted organization launch variable; pass those as secret overrides. A session with any override gets none of the organization’s secrets: no secret_names values and no organization sign-in secret. Secret overrides reach the app process as its secrets instead. If one is named by session.auth_bypass.sign_in.secret, it becomes the session’s sign-in secret: the worker signs the sign-in code with it, and it never enters the app’s environment. That name can’t be a plain override. Without it, sign-in is off for that session. Revyl stores override values encrypted for the session only and deletes them when the session ends. Sessions without overrides are unchanged, and overrides need a managed Web bundle. The session report lists each overridden name, marks secret ones, and shows only the host of plain values that parse as URLs.

Mobile Attach Order On revyl device start

iOS and Android starts use this pipeline:
  1. Read optional session settings from the nearest .revyl/config.yaml within the current Git worktree, or from the current directory outside Git. No config means command defaults and explicit flags. Legacy defaults.timeout, before_session, and auth_bypass settings work without migration; unrelated build and PR-review settings do not block device start. Malformed YAML and invalid session settings still fail before provisioning.
  2. Run session.before_script (if configured). The script must finish before the device boots. KEY=VALUE lines on stdout become session-scoped launch environment for this start only. A non-zero exit aborts start — Revyl will not boot an unprepared app.
  3. Apply session.auth_bypass.launch_vars. The CLI adds the configured org launch-variable keys to the explicit and inherited keys selected for this start. Keys that the before script already printed as inline values are not also looked up in org state.
  4. Boot the device with that launch environment fixed for the session. For iOS, selected --launch-arg-set values are flattened in flag order and inline --launch-arg tokens are appended. These explicit tokens are placed before legacy -KEY value pairs. Android rejects explicit arguments.
  5. Fire session.auth_bypass.deep_link (if configured and you did not pass --app-link). Placeholder substitution must use either only before-script values or only org launch variables — never a mix.

Config Reminder

Both settings live under the session section:
One produces values; the other consumes them. Full script contract: Mint The Token Per Session.

Working Directory Matters

Inside Git, config is found by walking up from your cwd to the nearest .revyl/config.yaml, stopping at the worktree root. Outside Git, only the current directory is checked. Use -C <project-dir> to choose the directory. In a monorepo where the Revyl project lives in a subdirectory (for example ios/.revyl/config.yaml), run device commands from that project directory (or below it):
If you start from the monorepo root and there is no root-level .revyl/, the CLI will not load the nested config — session.before_script and session.auth_bypass are skipped silently.

Overrides And Precedence

Launch environment is fixed at boot. revyl dev auth refresh re-fires the deep link with the same boot values; it does not remint. If the token expired, stop and start again so the before script runs fresh.

What Does Not Run session.before_script

The PR preview link in a GitHub comment has no checkout, so it cannot run your mint script. That path still uses organization launch variables only. Keep org vars fresh if reviewers rely on the preview link being signed in; mobile proof agents and local mobile revyl device start use the before script instead. Web starts do not run it; prepare any test data explicitly before Start.

Verify

revyl dev status reports the runtime before_session key names and state only — never token values.