Raxx · internal docs

internal · gated ↑ index

ADR 0005 — iOS WebAuthn: Reuse raxx.app as the RP ID (scope: web + iOS only)

Status: Accepted (amended 2026-04-22: scope narrowed to web + iOS only; console is NOT in scope and uses its own RP ID — see ADR 0012) Date: 2026-04-22 Deciders: software-architect Scope: WebAuthn relying-party configuration for the Raxx iOS app

Context

WebAuthn credentials are scoped to a Relying Party ID (RP ID). For a native iOS app, Apple's AuthenticationServices framework maps an app to an RP ID via an Associated Domains entitlement (webcredentials:<rp-id>) and a hosted apple-app-site-association (AASA) file at https://<rp-id>/.well-known/apple-app-site-association.

We must decide: should the iOS app share the web RP ID (raxx.app) or use its own (e.g. ios.raxx.app)?

This decision is load-bearing and effectively immutable: once users register passkeys under an RP ID, those passkeys cannot be migrated to a different RP ID without forcing every user to re-register.

The existing web auth design (auth.md) previously flagged this as open question #2. Resolved 2026-04-22 by user: raxx.app is the production RP ID. This is immutable once users start registering passkeys — the web, iOS, and console all bind to it.

Decision

Reuse raxx.app as the RP ID for the iOS app. This applies to web + iOS only. Configure an AASA file at https://raxx.app/.well-known/apple-app-site-association listing the iOS app's bundle ID under the webcredentials service. Add the webcredentials:raxx.app entitlement to the Xcode project.

This makes passkeys created on the web natively usable on iOS (iCloud Keychain syncs them), and vice versa. The user signs in once on any device and has access everywhere without re-registering.

Important scope narrowing (2026-04-22): The operator admin console (console.raxx.app) is not in scope for this ADR. Console passkeys live under a separate RP ID — see ADR 0012 for the rationale. Web + iOS share raxx.app; console is isolated.

Consequences

Positive

Negative / risks

Neutral

Alternatives considered

Separate RP ID for iOS (ios.raxx.app)

Rejected. Forces users to register a separate passkey for the iOS app even if they already have one from the web. Doubles the credential management surface. No security benefit — the iOS AuthenticationServices framework already binds the passkey to the app via the AASA trust, so a separate RP ID adds process complexity without adding trust separation.

Use an app-specific RP ID that the web also trusts

Rejected. Web browsers do not honor app-specific RP IDs via cross-origin association. The only clean shared-RP approach is the one above.

Compliance checklist

Revisit when