localhost - per the W3C WebAuthn
Level 3 specification (March 2025). An HTTP origin on a LAN IP address is not a Secure
Context and is blocked by 100% of major browsers, which is why Wi-Fi-only testing fails
on phones.mkcert trust chains during cross-device
passkey testing.abc123.ngrok-free.app). Passkeys registered against one RPID are rejected against
another - the #1 cause of failed login ceremonies in dev.The WebAuthn API requires the browser to be in a Secure Context before it exposes
navigator.credentials.create() for registration or navigator.credentials.get() for
login. The W3C Secure Contexts specification
restricts passkey operations to https:// origins and the localhost loopback. A LAN IP
such as 192.168.1.42 served over HTTP is explicitly excluded. The browser does not
surface the API to JavaScript at all.

Looking for a dev-focused passkey reference? Download our Passkeys Cheat Sheet. Trusted by dev teams at Ally, Stanford CS & more.
Plugging a laptop and phone into the same router does not work for
passkey testing. Any call to the WebAuthn API from a plain HTTP
origin throws a SecurityError in the DevTools console. The
platform authenticator UI never appears. The fix:
expose the local dev server under a public HTTPS URL - exactly what a reverse-proxy tunnel
provides.
ngrok is a reverse proxy that forwards inbound traffic from a
public HTTPS endpoint to a local port on the developer's machine. The
free tier assigns one persistent dev domain on
ngrok-free.app and terminates TLS at the edge using a Let's Encrypt certificate, so
every test device sees a fully trusted origin without any local TLS configuration.
For passkey testing, the tunnel turns http://localhost:19915
into something like https://abc123.ngrok-free.app. That URL is a valid Secure Context on
iOS Safari, Android
Chrome, desktop Chrome, Edge, Firefox and Safari - covering 95%+ of the passkey-capable
browser market as of Q1 2026 per
StatCounter browser share data. The
added latency is typically 50-150 ms depending on region, which is fine for
functional testing but unsuitable for
performance benchmarking.
The W3C WebAuthn specification Secure Context restriction is defined normatively in §5.1.3 of WebAuthn Level 3 and cannot be bypassed through browser flags or developer-mode settings on shipped browsers.
The following diagram illustrates the end-to-end tunnel architecture from your local dev server through ngrok to the test devices.
The end-to-end setup is 3 commands and 1 config change in the passkey backend.
ngrok config add-authtoken <token> to persist it to ~/.config/ngrok/ngrok.yml
(approximately 256 bytes on disk).localhost:19915, run
ngrok http 19915. The forwarding URL prints to stdout - something like
https://abc123.ngrok-free.app. That URL is the new test origin for the entire
session.rpId to
the tunnel's domain (no https://, no path) and add the full
https://abc123.ngrok-free.app URL to the allowed-origins list the backend verifies
during WebAuthn assertion. The
W3C WebAuthn L3 specification §5.1.3
requires the RP ID to be the origin's effective domain or a registrable-domain suffix
of the current origin. Popular server SDKs expose this as rpID + expectedOrigin
(SimpleWebAuthn), rp.id + origin
(py_webauthn), or relyingParty.id +
origins in Java libraries.The free plan's assigned dev domain persists across restarts, so the RPID stays stable. For custom or branded domains, the ngrok Hobbyist plan ($10/month, 1 user) or a higher tier is required.
Want to experiment with passkey flows? Try our Passkeys Debugger.
Open the HTTPS tunnel URL on each test device. On iOS 16+ and macOS 13+, the passkey prompt uses the iCloud Keychain UI and syncs the credential across Apple devices signed in to the same Apple ID, typically within 30-60 seconds per Apple's Passkeys developer documentation. On Android 9+ with Google Play Services 22.15 or later Google Password Manager stores the passkey and syncs it via the Google account. On Windows 10 1903+ and Windows 11, Windows Hello prompts for biometrics or PIN and stores the credential in the TPM 2.0 chip.
Minimum device matrix for a realistic passkey rollout test in 2026:
The following matrix summarizes the minimum device coverage and known quirks per platform.
Each combination has documented quirks - for example, Chrome on
iOS
incorrectly reports passkey_ready=false on some 2025 builds,
affecting roughly 5% of iOS Chrome sessions in December 2025 and cascading into
passkey-intelligence
filtering logic in production. Manual device testing is the cheapest way to surface these
before deployment - an average full-matrix manual pass takes 15-25 minutes per release.
Three errors account for roughly 85% of failed tunnel-based passkey tests across SDKs and languages:
SecurityError: The operation is insecure - the page loaded over HTTP or the RPID
does not match the current origin. Verify the browser URL bar shows https:// and that
rpId in the backend exactly matches the public subdomain.NotAllowedError on registration - the user canceled (62% of this error code's
occurrences in typical deployments) or the platform
authenticator is unavailable (no screen lock on Android, no
Touch ID on pre-2016 Macs). Confirm the device has a biometric or PIN configured.Invalid origin on assertion verification - the backend's allowed-origins list does
not contain the full tunnel URL. The check is case-sensitive and includes the scheme, so
https://abc123.ngrok-free.app must be added verbatim.As shown below, a simple decision tree covers the diagnosis path for all three errors.
Subscribe to our Passkeys Substack for the latest news.
The MDN reference for the
Web Authentication API
lists 8 additional DOMException types but the 3 above dominate real-world developer
debugging sessions.
Tunnel-based testing catches developer-environment bugs - wrong RPID, missing origins, TLS mismatches and forgotten authorized origins. It does not catch the failure modes that dominate production passkey adoption: stale credentials after an OS reset (12-18% of login failures in iOS deployments measured over 2025), iCloud Keychain sync lag, password managers intercepting the WebAuthn ceremony, silent Safari abort on iOS or hybrid flow drop-off at the QR-scan step (roughly 35% of CDA attempts never complete). Those failure modes surface only once real users are on real devices at real scale.
Per the FIDO Alliance 2025 State of Passkey Authentication report, 53% of consumers had signed into at least one site with a passkey by late 2025. Cross-platform completion rates still lag account-password flows by 10-20 percentage points on mobile. Closing that gap requires telemetry the browser does not expose natively.
Per Google's Identity team, platform authenticators are the fastest-growing passkey authenticator class, and closing the gap between passkey registration and first successful passkey login remains a central focus of their consumer-passkey work. (Paraphrased from the Google Identity passkeys developer documentation.)
Corbado Observe instruments the full passkey ceremony across registration, login, and recovery, and surfaces per-device and per-browser success rates so enterprise CIAM teams can see which OS and browser combinations are dragging down adoption. Local testing gets a codebase through development; production observability is how enterprises run passkeys at scale.
Igor Gjorgjioski
Head of Digital Channels & Platform Enablement, VicRoads
Corbado proved to be a trusted partner. Their hands-on, 24/7 support and on-site assistance enabled a seamless integration into VicRoads' complex systems, offering passkeys to 5 million users.
Passkeys that millions adopt, fast. Start with Corbado's Adoption Platform.
Start Free TrialWebAuthn's HTTPS requirement is the #1 blocker for teams testing passkeys across multiple
devices. A tunnel service removes it in 3 commands: install the binary, authenticate once,
run ngrok http <port>. Set the RPID and authorized origins in the passkey backend to
match the tunnel domain, and passkey registration and login work from an iPhone on LTE, an
Android on 5G or a Windows laptop on any network - all hitting the same laptop running the
dev server.
Local testing catches developer-environment bugs in minutes. It does not measure real-user passkey success rates across the 40+ OS-browser combinations that show up once passkeys are in production, where cross-platform completion lags account-password flows by 10-20 percentage points per 2025 industry data. Enterprise CIAM teams running passkeys at scale pair local multi-device testing with passkey observability - the failure-mode telemetry exposed by Corbado Observe and the broader enterprise passkey platform.
Yes. Any reverse-proxy tunnel that terminates TLS at a publicly trusted certificate will
satisfy WebAuthn's Secure Context requirement. Cloudflare
Tunnel provides stable subdomains on a custom domain. Tailscale Funnel gives you a
ts.net subdomain. Functionally all three work - the choice comes down to latency,
stability of the subdomain and whether your team needs the tunnel to persist across
machine restarts.
Yes, with 1 caveat. CDA (formerly "hybrid transport", defined in CTAP 2.2 §11.5) uses a QR code scanned by a separate device running Bluetooth Low Energy. The QR payload embeds the RPID, so it must match the tunnel domain exactly. If using a custom domain that changes between sessions, any QR code issued under the old domain becomes invalid. For extended CDA testing, use the free plan's persistent dev domain or a staging domain with a stable DNS record.
For functional testing, yes - the tunnel is scoped to your laptop and terminates when you stop the process. For anything touching real user data, use ngrok's IP-allowlist or basic-auth features or switch to an authenticated staging environment. Passkeys created against an ngrok subdomain are bound to that RPID and cannot be reused on production, so there is no credential bleed-through risk.
The passkey syncs through iCloud Keychain, which requires both devices to be signed in to the same Apple ID with iCloud Keychain enabled. Sync is not instant - typically 30-60 seconds, occasionally longer than 5 minutes under constrained network conditions per Apple Support documentation. If the MacBook never receives the credential, verify iCloud Keychain is enabled under System Settings > Apple ID > iCloud and that both devices run iOS 16+ and macOS 13+.
Use virtual authenticators for CI - the Chrome DevTools Protocol exposes a WebAuthn virtual authenticator that Playwright and Puppeteer drive for automated regression runs. Dedicated coverage for the Playwright integration lives at /blog/passkeys-e2e-playwright-testing-webauthn-virtual-authenticator. Virtual authenticators cover roughly 60% of the production bug surface; real-device testing covers the remaining 40% - iCloud Keychain sync edge cases, Android autofill UI regressions and Windows Hello prompt timing issues that virtual authenticators cannot reproduce.
Free ngrok tunnels stay up as long as the ngrok http process runs; there is no fixed
session duration limit on the current free plan. Closing the terminal or killing the
process terminates the tunnel immediately and the subdomain is released. For multi-hour
testing sessions, start ngrok inside tmux or a background process manager.
Related Articles
Table of Contents