Loading…
Supporting Passkeys in Shop's Authentication Flows
2023-10-18
- Source
- Shopify
- Published
- Added to Yomu
Summary
Shop Pay and the Shop app began deploying passkeys in December 2022 across web and native app authentication, initially as an additional method for existing users and as a replacement for email and SMS verification. Passkeys use public-key cryptography: the private key remains on the device, while the service stores a public key, with platform or roaming authenticators providing options such as biometrics or hardware keys. Built on Ruby on Rails, Shop used webauthn-ruby to store a server challenge during registration, verify the allowed domain and challenge, and save the credential identifier; login looks up that identifier and verifies authentication while updating the sign count. The team also integrated passkeys into an iframe-capable login component for use across Shopify interactions, including merchant storefronts. Domain scoping, authenticator settings, challenge handling, Conditional UI, and cross-device interoperability are identified as important implementation considerations.
Context
Shop Pay authentication relied on codes sent to a verified email address or phone number, leaving account security dependent on the security of those external accounts. The team wanted a more secure and frictionless authentication experience, while passkey adoption and support across devices, browsers, and operating systems were still developing.
Approach / What changed
Shop deployed passkeys in Shop Pay and Shop authentication flows using public-key credentials and WebAuthn. The Ruby on Rails implementation uses the webauthn-ruby gem, server-stored challenges, domain verification, credential identifiers, and authentication sign-count updates. Passkeys were also integrated into a login component that can be rendered in an iframe for use on Shopify merchant storefronts.
Takeaways
- A registration challenge is stored for the verification period, checked when the device returns its public key, and removed after verification to protect against replay attacks.
- Setting authenticator_selection to "platform" and require_resident_key to true requests platform authenticators and discoverable credentials, respectively.
- Conditional UI could remove the need for an explicit passkey-button tap, but its passkey-not-available experience can confuse desktop users; Shop is still testing it.