Skip to main content

Native mobile signer contract

The iOS and Android shells should implement the same signer contract as the web client. This is a UI and platform integration note, not a second protocol.

  • Register the custom poweur://auth?request=… scheme for same-device links.
  • Also register the deployment's HTTPS universal/app link so sites can use a verified link with a browser fallback.
  • Treat QR contents and pasted codes as untrusted input sent through the same decoder. Never place a private key, session secret or relay token in a link.
  • Preserve the request while the user unlocks or selects an identity; discard it at expiry.

Approval screen​

Before unlocking a signing key, fetch /.well-known/poweur.json from the signed audience with no redirects. Display the verified app name and origin, action, statement, and every requested scope in plain language. Approval is one explicit biometric/passcode-gated action; denial and navigation away sign nothing.

The app you are signing in to is never in this app's browser, so every mobile approval is a cross-device approval: ask for the code shown on the screen that started the sign-in and send it with the delivery ({"response": …, "match": …}). Say plainly that the code must be on a screen in front of the user, and that a code someone sent them means cancel. When the RP publishes context_uri, show its line ("Started 12 seconds ago in Chrome on macOS, to sign in to …") beside the code field.

After approval, append the consent record first, then deliver to the allow-listed response_uri. If the receipt carries a resume_uri — possible only when a request reached the app without a code — check it is same-origin with the audience before opening it. Never build a URL containing the approval. If delivery fails, show a copyable response code. A cross-device flow must remain usable without the two devices sharing an account or push channel.

Platform lifecycle​

  • Redact the request and response from analytics, crash reports, notifications and recent-app snapshots.
  • Do not approve from a background callback; return to the visible consent screen.
  • Use the existing secure key-custody and session-key interfaces. The mobile shell must not invent a different key or shared-state format.
  • When the app resumes, revalidate the request window and refetch RP metadata before signing.

The conformance target is packages/identity/testdata/vectors/signin.json; a native signer must produce responses accepted by the existing Go and TypeScript verifiers.