Passkeys and WebAuthn Fallback (UI Layer)#
The UI Layer renders WebAuthn / Passkeys flows natively on both platforms when the device supports them. When the device or account doesn’t — missing system configuration, unregistered associated domains, OS version too old, no biometric enrolled — the framework can either fall back to a browser-based Passkeys flow or stop with a user-facing error. This page documents the knob and the prerequisites.
For the conceptual background, see Attestation and Fallback (Passkeys and attestation share the “device-capability fallback” pattern).
When the Fallback Kicks In#
The framework attempts a native Passkeys flow first. The fallback runs when any of the following failure categories applies at runtime:
- OS-version gap — the device’s OS doesn’t expose the required Passkeys APIs.
- No enrolled credentials — the user hasn’t enrolled biometrics or a device PIN.
- Missing account prerequisite — Android-only: no Google account is signed in (Credential Manager requires one).
- Domain-association gap — the relying-party / associated-domain configuration is missing or unreachable.
- Server-version gap — the Curity Identity Server version doesn’t support Passkeys for the current platform.
Platform-specific version cutoffs and configuration steps live in the per-platform setup below.
Whether the native flow or the browser fallback runs, the result handler receives the same outcome — HaapiFlowResult.didReceiveOAuthTokenModel(_:) on iOS, OauthModel.Token in the Activity Result on Android. The fallback is transparent at the application code level; only the user experience differs.
If the fallback is disabled (setUsePasskeysBrowserFallback(false)) and any of the above failure categories applies, the framework interrupts the flow and surfaces an error with the localized string hui_webauth_passkeys_not_supported.
Platform Setup#
Pick your platform; each tab covers the configuration call and the prerequisites that must be in place for the native flow to run.
Configuration#
HaapiUIKitConfigurationBuilder(...)
.setUsePasskeysBrowserFallback(true) // default
.build()true (default) — when the native flow can’t run, present the browser fallback automatically.
false — when the native flow can’t run, surface an error to HaapiFlowResult.didReceiveError(_:) and let the host app explain. Customize the user-facing message via hui_webauth_passkeys_not_supported in Localizable.strings.
Prerequisites for the Native Flow#
- iOS 16.0 or later on the device.
- Associated domains configured on the app (
com.apple.developer.associated-domainsentitlement,webcredentials:idsvr.example.com). - The server-side relying-party origin matches the associated domain.
- Curity Identity Server 8.7.0 or later for native WebAuthn support.
Configuration#
WidgetConfiguration.Builder(...)
.setUsePasskeysBrowserFallback(true) // default
.build()true (default) — when the native flow can’t run, present the browser fallback automatically.
false — when the native flow can’t run, interrupt the flow with an error in the Activity Result.
Prerequisites for the Native Flow#
⚠️ Native WebAuthn on Android is currently flagged as experimental in the framework. Provide feedback to Curity if you hit bugs.
- Android 9.0 (API 28) or later for Passkeys; Android 8.0 (API 26) for older WebAuthn flows.
- Google Play Services FIDO2 and Credential Manager available (standard on Google-certified devices; not all Android variants ship with them).
- User must be signed in to a Google Account on the device.
- Digital Asset Links configured in the manifest (
asset_statementsmeta-data + anassetlinks.jsonpublished athttps://<your-domain>/.well-known/). - Curity Identity Server 9.3.0 or later for discoverable-credentials support.
The browser fallback shares cookies with the system browser, so a user already signed in there gets a smoother experience — but the browser session is outside your app’s process and any analytics / telemetry you have wired into the app does not see it. If your compliance posture requires keeping authentication entirely in-app, set the fallback to false and require users on unsupported devices to upgrade or use a different authentication method.
How to implement this: Configuration · Presentation Options · Attestation and Fallback (concept)