At a Glance
- 70 percent of new users were bouncing at sign-up. The three options we offered (email plus OTP, Apple Sign In, Google Sign In) were each broken in their own way for a cross-platform multi-app ecosystem.
- We removed all three. New users now tap once and land in the app, already authenticated.
- Passkeys carry the weight. Face ID, Touch ID, Windows Hello, or Android biometrics unlock a credential that lives in the device’s secure hardware.
- iCloud Keychain and Google Password Manager handle most cross-device sync. For platform jumps (iPhone to Android), a five-second QR pairing flow takes over.
- One Relying Party covers every Zovia app. Sign in to one app, the passkey works for all of them. Move to a new phone, the passkey moves with you.
The first time someone opened a Zovia app, they hit a wall. Three doors: type your email and wait for a code, sign in with Apple, or sign in with Google. Pick one. Most picked none, and most never came back.
Seventy percent never came back.
We knew the number for months. We tried every variation of the same screen. Friendlier copy, softer illustration, a “skip for now” link that bounced into a guest mode that bounced right back to the same wall the moment a user tried to do anything real. Nothing moved the needle, because the screen itself was the problem.
So we deleted it.
The three doors that all failed
Each option we offered was an answer to “how do we identify the user?” None of them was an answer to the question that actually mattered: how do we get the user into the app without making them think about us?
Email plus OTP. The classic friction loop. Open the app, type your email, switch to your mail client, wait, switch back, type the six-digit code. Most users never make it back. The code arrives faster on some networks than others, but the context switch is the part where you lose them. A user who has to leave your app to authenticate is a user who has to be convinced to return.
Apple Sign In. Beautiful on iOS. Useless to Android users. And even iOS users who signed up via Apple are locked out the day they try the app on Android. The credential cannot follow them. For a multi-platform ecosystem, this is a one-way street with a “no exit” sign at the end.
Google Sign In. Glitchy in single-app contexts, brittle across apps and platforms. Google’s session model assumes an OAuth token belongs to one app at a time, which fights everything we wanted to do. Account chooser sheets that pick the wrong account. Silent re-auth failures. Redirect loops on iOS. We chased these bugs for months and they kept coming back like weather.
The shared problem, the one that connected all three: every option was a vendor identity system wearing a “Continue with” button. We did not need a vendor identity system. We needed a way for our app to recognize the same person on the next launch.
The reframe: identity belongs on the device, not in our database
Here is the move. The user’s identity does not have to be an email address we own a row for. It can be a private key the user’s device holds and never has to type. Sign-up becomes a tap. The account is real from the first moment. Full feature access. Full session. Nothing degraded, nothing labeled “guest.”
We stopped treating the email field as a load-bearing primitive. It was always a customer service convenience dressed up as authentication. People do not sign up for an app because they wanted us to have their email. They sign up because they want to use the app. The email was something we asked for so we could find them later. There are better ways to be findable.
Passkeys, the hero
A passkey is a keypair. The private half lives in the Secure Enclave on iOS or the StrongBox on Android, unlocked by the user’s face or fingerprint. The public half lives on our server. Signing in means proving you can sign a challenge with the private key. Nothing typed. Nothing remembered. Nothing to phish.
Both Apple and Google ship passkey support natively now. iCloud Keychain syncs passkeys across every Apple device a user owns. Google Password Manager syncs across every Android device. Cross-device used to be the hard part of biometric authentication. The platform vendors solved it.
We picked one Associated Domain for every Zovia app to share. A passkey enrolled in one app is recognized by every app. iOS Universal Links and Android App Links handle the trust verification automatically. Sign into Zupply, then open Zots, and Zots already knows you. No second prompt.
When platform sync isn’t enough: scan a QR code
iCloud Keychain only syncs across Apple devices. Google Password Manager only syncs across Android. The day a user moves from iPhone to a Pixel, the platform vendor cannot help them. So we built a QR pairing flow.
Open the app on the new device. Tap “I have a Zovia account.” Your existing signed-in device generates a one-time QR code with a short five-minute window. Scan it. The new device is enrolled, a passkey is provisioned for it, and you are in. Cross-platform was the gap nobody else was filling. We closed it with a five-second flow.
What this kills
No password to forget. No code to wait for. No third-party identity provider locking you to one platform. No glitchy account chooser sheet picking the wrong account. No “you signed up with Google but you’re using a different Google account on this device” dead end. The class of bugs we used to file weekly is gone.
Cross-app inside a single device
The cross-device story is the new part. The cross-app story already existed. We covered it in detail in How We Built Google-Like Cross-App Authentication for a Flutter Ecosystem. Short version: a shared keychain group on iOS and a content provider mirror on Android mean any Zovia app can read the session another Zovia app wrote.
With passkeys layered on top, the experience for a user installing a second Zovia app is not “sign in with your account.” It is just opening the app. They are already in. The combination of cross-device passkey sync and cross-app session sharing means a user who set up Zupply on their iPhone last week can install Zots on their iPad today and never see a sign-in screen on either of them.
The analog escape hatch
A recovery code is shown once at sign-up. It exists for the rare case where a user loses every paired device and has no other way back in. We do not lean on it. Save it or do not. Most users will never need it.
The code is the third fallback, not the first. Passkey sync handles cross-device within a vendor’s ecosystem. QR pairing handles cross-platform. The code is the last resort.
Email, when you actually want one
Email becomes an opt-in contact channel, attached later from the profile screen with a one-time code exchange. It does not change how you sign in. The passkey remains the credential. Email is just where we send a monthly summary, a security notification, or a recovery message if you ask for one.
Many users never add an email. That is the point. We do not block any feature behind it. We do not nag for it. If you want notifications by email someday, the field is there. Until then, it stays empty.
Where friction still belongs
Frictionless sign-in does not mean frictionless everything. There are five operations where we still ask for a face or fingerprint confirmation:
- Regenerating the recovery code
- Signing out other devices
- Deleting the account
- Deleting app data
- Changing the email on file
Each is destructive or sensitive. Each is intentional friction in the right place. Removing friction at the welcome screen does not mean removing it from the moments where a user might do something they cannot undo. The discipline is to put friction where the user benefits from it, not where the product benefits from it.
Build this yourself, the eight decisions that matter
If you are designing authentication for a multi-app or multi-platform product, these are the calls we would make again.
1. Make anonymous-first the default. Single tap into a real account with full feature parity. No “guest” tier. No degraded mode. No asterisks on what they can do. The first time someone opens your app should not feel like a transaction.
2. Pick passkeys as the primary credential. Symmetric secrets, OAuth tokens, and one-time codes are all transitional. Passkeys are the destination. The platform vendors carry the weight of cross-device sync within their ecosystems, which is the part that used to be hard.
3. Choose one Relying Party domain across every app. A single Associated Domain configured for iOS Universal Links and Android App Links means one passkey covers your entire ecosystem. Do not fragment by app. That throws away the best property of the system.
4. Build a QR pairing flow for cross-platform. iCloud Keychain does not reach Android. Google Password Manager does not reach iOS. The platform vendors stop at the edge of their own walls. A short-lived QR code generated on an existing signed-in device, scanned on the new device, closes the gap in seconds. This is the part you have to build yourself.
5. Treat recovery codes as the third fallback, not the first. Show once at sign-up. Do not nag. Do not require it to be saved before the user can continue. Most users will never lose every paired device and never need it. It exists because edge cases exist, not because users should think about it.
6. Make email an opt-in contact channel, not an identity primitive. Attach later from the profile screen. The credential stays the passkey. Email is just where you send the summary or the security notification. Many of your users will never add one. That is fine.
7. Keep biometric friction at the right call sites. Destructive operations should still ask for face or fingerprint. Per call site, not as a global gate. Frictionless sign-in does not mean frictionless deletion.
8. Do not build vendor-bound identity. Apple Sign In and Google Sign In each lock you to one platform’s identity graph. For multi-platform ecosystems, the user’s device is the right anchor, not the vendor’s account system. The moment a user moves to the other platform, vendor-bound identity becomes a wall.
The takeaway
The reason 70 percent of users were bouncing was not that they hated authentication. It was that we were charging them for the privilege of trying our product, and the currency was their email address and three minutes of context switching. Passkeys let us stop charging that price. Apple Sign In and Google Sign In tried to solve the same problem at a different layer and could not, because they were still vendor identity systems wearing a “Continue with” button.
The user’s device is the right place to anchor identity. The platform vendors finally agree.
If you are building anything users have to sign up for, the next year is the right time to delete your email field.
Built at Zovia Studio. We ship apps that families use every day, and we take the “every day” part seriously.