Skip to content

Auth bypass for deterministic recordings

Most real apps need real auth. Recordings need determinism: the same flow on the same build must produce the same screens every time, in CI, with no human in the loop.

OAuth, magic links, SMS one-time codes, biometric prompts, and rate-limited IDPs all break that contract:

  • Tokens expire between recording and replay
  • Real users can’t be rotated through CI on every run
  • Magic-link emails and SMS codes are out-of-band by design
  • IDPs rate-limit; CI is the easiest thing to get banned
  • A flaky third-party login turns every replay flake into a “SimDrive bug”

The fix is an app-side launch arg that swaps in a deterministic fixture user, plus a backend env flag that accepts a non-secret bypass token only in non-production environments.

  1. Launch the app under SimDrive with a bypass flag. Pass SimDriveAuthInject as a launch arg from your session_start call (or from xcrun simctl launch --console). The app reads ProcessInfo.arguments on boot and, only when the flag is present and the build is non-Release, short-circuits the login flow with a fixture user.

  2. Backend accepts a fixed AUTH_BYPASS_TOKEN. Stand up your backend in a recording env (compose profile, k8s overlay, whatever you use) that reads AUTH_BYPASS_TOKEN from the environment. Requests carrying that token in Authorization: Bypass <token> resolve to the fixture user.

  3. Seed a deterministic fixture user. Pick a stable id (00000000-0000-0000-0000-000000000001 works), seed it on backend boot, keep all replay-relevant state attached to it.

  4. Record + replay normally. SimDrive captures the flow as if the user were really logged in. Replay drives the same launch args, hits the same backend env, and gets pixel-stable screens every time — no IDP, no email, no SMS, no expiry.

  5. Guard the bypass three ways. Compile-time build-flag check, runtime env check, and server-side env check. Any one of them slipping is fine. All three slipping at once is the only way you ship the bug.

A minimal Swift entry point that honours the flag only on non-Release builds. Drop this into your App.init() or your AppDelegate.application(_:didFinishLaunchingWithOptions:).

App+AuthBypass.swift
import Foundation
enum AuthBypass {
/// Returns the fixture user iff:
/// 1. the build is NOT Release (compile-time guard), AND
/// 2. the SimDriveAuthInject launch arg is present (runtime guard), AND
/// 3. AUTH_BYPASS_TOKEN is set in the process env (runtime guard).
static func fixtureUserIfEnabled() -> FixtureUser? {
#if DEBUG || RECORDING
let args = ProcessInfo.processInfo.arguments
let env = ProcessInfo.processInfo.environment
guard args.contains("SimDriveAuthInject"),
let token = env["AUTH_BYPASS_TOKEN"], !token.isEmpty else {
return nil
}
return FixtureUser(
id: "00000000-0000-0000-0000-000000000001",
email: "fixture@simdrive.local",
bypassToken: token
)
#else
return nil // App Store builds: bypass is physically not in the binary
#endif
}
}
struct FixtureUser {
let id: String
let email: String
let bypassToken: String
}

Use it at startup:

MyApp.swift
@main
struct MyApp: App {
init() {
if let user = AuthBypass.fixtureUserIfEnabled() {
Session.shared.adopt(user) // skip the real login screens
}
}
var body: some Scene { /* ... */ }
}

From your MCP client, pass the launch arg when starting the SimDrive session:

MCP / Claude prompt
session_start(
bundle_id="com.acme.familybag",
device="iPhone 17",
os_version="26.3",
launch_args=["SimDriveAuthInject"],
env={"AUTH_BYPASS_TOKEN": "rec_dev_only_not_a_real_secret"},
)

Or from the CLI, if you boot the app yourself before session_start:

Terminal window
xcrun simctl launch --console <udid> com.acme.familybag \
SimDriveAuthInject \
AUTH_BYPASS_TOKEN=rec_dev_only_not_a_real_secret

Stand up your backend in a recording env that knows it must accept the bypass header. The compose snippet below uses Docker; adapt to your stack.

docker-compose.recording.yml
services:
api:
image: acme/api:latest
environment:
APP_ENV: recording # NOT "production"
AUTH_BYPASS_TOKEN: rec_dev_only_not_a_real_secret
AUTH_BYPASS_USER_ID: "00000000-0000-0000-0000-000000000001"
ports:
- "8080:8080"
seed:
image: acme/api:latest
command: ["./bin/seed-fixture-user"]
environment:
DATABASE_URL: postgres://...
FIXTURE_USER_ID: "00000000-0000-0000-0000-000000000001"
FIXTURE_USER_EMAIL: fixture@simdrive.local
depends_on: [db]

The fixture user shape your seeder writes:

fixture-user.json
{
"id": "00000000-0000-0000-0000-000000000001",
"email": "fixture@simdrive.local",
"display_name": "Fixture User",
"created_at": "2026-01-01T00:00:00Z",
"tier": "pro",
"onboarding_completed": true
}

Server-side, the auth middleware checks the bypass token only when APP_ENV is one of dev | recording | ci:

middleware/auth.py (pseudocode)
ALLOWED_ENVS = {"dev", "recording", "ci"}
def authenticate(request):
env = os.environ["APP_ENV"]
auth = request.headers.get("Authorization", "")
if auth.startswith("Bypass ") and env in ALLOWED_ENVS:
token = auth.removeprefix("Bypass ").strip()
if token == os.environ["AUTH_BYPASS_TOKEN"]:
return load_user(os.environ["AUTH_BYPASS_USER_ID"])
# fall through to real auth
return real_oauth_flow(request)

The middleware rejects the bypass token outright in production — even if someone leaks the token to the wrong env, the server still says no.

  • DON’T enable the bypass code path in App Store / TestFlight Release builds. Wrap it in #if DEBUG || RECORDING so the symbols are physically absent from the production binary.
  • DON’T bake the bypass token into the iOS binary. Read it from ProcessInfo.environment at runtime — never hardcode.
  • DON’T check the bypass token into your iOS source tree, your backend source tree, or your CI logs. Treat it as a non-secret config value managed in env / .env.recording (gitignored).
  • DON’T name the token in a way that suggests it’s safe (AUTH_BYPASS_TOKEN is fine — it’s explicit). If you call it API_KEY someone will paste it.
  • MUST have the server reject the bypass token whenever APP_ENV ∉ {dev, recording, ci}. This is the defence-in-depth backstop.
  • MUST have a CI lint or release check that fails the build if SimDriveAuthInject appears in any string scanned from a Release .ipa. (strings MyApp.app/MyApp | grep -q SimDriveAuthInject && exit 1.)
  • MUST rotate AUTH_BYPASS_TOKEN if it ever appears in a chat, screenshot, bug report, or pasted log. The token itself is non-secret in principle, but rotating costs nothing and removes ambiguity.

CI replay

Quickstart → CI replay — wire the recording into a GitHub Actions job that uses the recording backend profile.