Streaming is available in most browsers,
and in the Developer app.
-
Streamline sign-in with passkey upgrades and credential managers
Learn how to automatically upgrade existing, password-based accounts to use passkeys. We'll share why and how to improve account security and ease of sign-in, information about new features available for credential manager apps, and how to make your app information shine in the new Passwords app.
Chapters
- 0:00 - Introduction
- 0:38 - Automatic passkey upgrades
- 2:37 - The passkey journey
- 4:18 - Automatic passkey upgrade sequence
- 7:46 - Shipping and deploying passkey support
- 9:17 - Improvements for credential managers
- 10:14 - The new Passwords app!
- 11:30 - Updating appearance in the Passwords app
- 12:31 - One-tap verification code setup
Resources
- About the security of passkeys
- ASCredentialProviderExtensionCapabilities
- Authentication Services
- Connecting to a service with passkeys
- Forum: Privacy & Security
- Passkeys overview
- Public-Private Key Authentication
- Supporting passkeys
Related Videos
WWDC23
WWDC22
WWDC21
-
Download
Hi, I’m Garrett. I’m excited to talk about how you can deploy automatic passkey upgrades in your apps and websites, as well as several other new developments for providing a great sign-in experience. In this video I’ll talk about how you can automatically upgrade existing accounts to passkeys, several new features that are available for credential managers, and what you can do to make your app shine in the new Passwords app.
Let’s start with something that’s really exciting, automatic passkey upgrades. Here’s an example of a typical sign-in today. First, I fill my username.
Then, I fill my password.
Then, I wait for an SMS to come in, and fill that too.
And finally, I’m signed in.
Multi-step sign-in like this is a common way websites and apps offer improved security, though it can be slow or tedious. This is the point that some apps, may show some kind of interstitial upsell letting me know that there’s a faster alternative, using something like passkeys. But this app, has adopted automatic passkey upgrades. The system shows a notification, that a passkey has been created! No upsell screens, no interruptions, just a smooth pathway to an easier, more secure sign-in experience. And of course, this works on your websites, too.
This entire experience has been designed to make transitioning to stronger, more secure sign-in as easy and frictionless as possible. When I come back to the app, signing in is super fast and easy. Just one tap.
When comparing these flows side by side, the first step is identical. One button, to select your account.
For the traditional sign-in, there are several more steps to follow. But with a passkey, there is no step 2 or 3. You’re just signed in. And remember, the passkey is more secure.
Phishing, and other forms of stolen credential attacks, make up some of the most common forms of account compromise on the internet today.
The best way to prevent phishing, is to have accounts that don’t have any phishable factors. One of the best things you can do to protect new accounts, is to give them a passkey from the start. A passkey can’t be forgotten, is less likely to need a reset, and is just a single tap or click to sign in with. And by having just a passkey, the account isn’t vulnerable to phishing as we know it today.
But almost all existing accounts only use phishable factors, like passwords, SMS, email, push notifications, and time-based codes. Combining multiple of these factors helps, but they all still share the same fundamental vulnerability to phishing.
Right now the industry has begun a transition period, where it’s moving away from phishable sign-in, to unphishable authentication mechanisms, such as passkeys. The first step in this journey for existing accounts is to add an unphishable sign-in method, as an alternative way to sign in. This helps you introduce passkeys gradually, allowing people to proceed at their own pace.
The goal is still to eventually get rid of all phishable authentication factors. However, this video focuses on making that first step, by making it as smooth and easy as possible, for your users to get started, using passkeys.
Here’s a sequence diagram of an automatic passkey upgrade. Your app makes a request to the system, and the system decides whether it makes sense to create a passkey at this time, returning the new passkey if so.
To make that decision, here’s what the system is actually doing when it receives that request. First, the system performs a series of internal checks, to decide whether it thinks creating a passkey makes sense at this time. Some of these checks include whether a credential manager is currently set up on the device, and supports automatic passkey upgrades, whether the device is currently set up to use passkeys, such as if it has a passcode, or, for requests on the web, it checks to make sure this is a non-Private browsing tab. If the system is happy that the request can proceed, it passes that request on to available credential managers. The credential manager then applies its own set of conditions to the request. The most important condition is whether it was just used to fill a username and password for the same account. That is, an account with the same username as the passkey being registered.
If the answer is yes, and any other conditions the credential manager has are met, it returns a new passkey, which is passed along to your app. If any conditions weren’t met along the way, you get an error back. This doesn’t necessarily mean anything went wrong, just that a passkey wasn’t created this time.
Think of automatic passkey upgrades as a progressive enhancement. It won’t lead to the registration of a passkey 100% of the time, but when it does, it’s a smooth user experience that doesn’t require you to build an upsell screen or get in the way of using your app.
Here’s an example of a password-based sign-in flow, which offers to create a passkey. After signing in with a password, it checks whether the account has a passkey, and offers to create one if not.
Many apps currently present some kind of dialog shortly after signing in, offering this upgrade.
With automatic passkey upgrades, that step is no longer needed. You can instead pass a new registration request style of .conditional. If all of the preconditions of the system and passkey manager are met, you get a passkey back, and the device shows a notification that a passkey has been created, all without interrupting what was happening in your app.
If any preconditions weren’t met, you get an error back, and no UI is shown. At this point you can choose to either show your existing upsell dialog, or just try again next time.
On the web, the story is very similar. Here’s a standard passkey registration.
And here, adding the mediation, conditional parameter changes this request from modal passkey creation to an automatic upgrade style request. Before making this style of request on the web, make sure to use getClientCapabilities to check that the browser supports it.
The industry is transitioning away from passwords to passkeys and automatic passkey upgrades will accelerate this transition.
Shipping passkey support in your apps and on your websites is like developing and deploying any feature, with learning, building, testing, and shipping phases. But something unique to the passkey journey is that the ultimate goal is two-fold, to make sign-in easier and to improve account security.
Shipping support for passkeys makes sign-in dramatically easier, but if a password can still be used to sign in to an account, that means the account is still vulnerable to phishing and password reuse attacks. This means that ultimately, it’s time to start thinking about what it would take to eliminate all phishable factors as sign-in options from accounts. If your service notices that an account never uses its password anymore, thats a good signal to think about getting rid of it. Similarly for accounts that use multi-factor sign in, remember that most additional factors used today are also still phishable, which is why the industry is moving towards passkeys to begin with.
Offering passkeys makes it significantly faster and easier to sign in to your service, while also providing an even stronger security posture, than common forms of multi-factor sign-in today. You might not be able to eliminate the password yet, but keep in mind that it’s the ultimate goal of deploying passkeys.
Next up, I’ll talk about some of the new features available for credential managers.
Credential managers can of course participate in automatic passkey upgrades.
They can also now fill time-based verification codes.
As well as fill usernames, passwords, or one-time codes into any text field.
These are all additions to the existing credential manager API. To add support for these features, there are several new keys available for your Info.plist, and matching APIs which you can read about in the Authentication Services documentation. And with the credential provider extension mechanism now handling passwords, passkeys, and verification codes, you can now select up to three apps to use with AutoFill. So those are some of the improvements for credential managers. Finally, I’ll talk about the Passwords app, new in macOS Sequoia, iOS 18, and visionOS 2.
In the app, your website’s name and icon are in the spotlight, showing off its personality. And if you want to change how your website and app are displayed, there are existing, standards-based ways to do that, which I’ll cover in a moment.
Backing out to the top level, there’s a passkeys section, which highlights apps and websites that have adopted phishing-resistant sign-in. And there’s a section for verification codes, which makes it super easy to look up and copy a code, just like a dedicated authenticator app.
In the Security section, the Passwords app lists saved passwords that are weak, reused, or have appeared in a data leak. The Change Password button can open your change password web page, if you adopt the well-known URL for changing passwords.
On macOS, people can enable a menu bar item, to allow quick and easy access to their passwords and verification codes. It’s also easy to import passwords from another credential manager, as well as export passwords. Here’s an example, of what an account looks like in the Passwords app. This account has both a passkey and a password. When a passkey and password are saved for the same app or website, with the same user name, the Passwords app combines them into a single entry.
If your website has already adopted the OpenGraph metadata standard, the Passwords app displays your sitename for any saved accounts. If not, the Passwords app tries to figure out your website’s name, or falls back to your domain name.
The OpenGraph web standard lets you declare metadata about websites, by including specific meta tags in the page’s head tag. You should ensure the metadata is set for all pages and subdomains, and all user agents, so your website is always properly represented.
Also, double check that your website has high-resolution icons, so they look great next to your accounts.
Finally, for apps and websites that offer time-based verification codes, you can make setting up that code a one-tap experience by offering an otpauth: link in addition to the standard QR code.
This link opens the default verification code app on the system, making it easy to set up codes either on another device or directly on the device you’re already using.
Also, if you display a list of authenticator apps that can be used for verification codes, consider adding "Apple Passwords" to the list.
For more on verification codes, check out: "Secure login with iCloud Keychain verification codes".
So, here are some some next steps. If you haven’t done it yet, now is the time to deploy passkeys! They’re faster, easier, and so much more secure than passwords. And with automatic upgrades, it’s never been easier to start that transition.
Update your website’s metadata, so that the personality of your website comes through in the Passwords app.
And finally, streamline verification code setup so that it works great for any credential manager on any device.
Thanks for watching. So long and thanks for helping to eliminate phishing.
-
-
0:01 - Offering a passkey upsell
// Offering a passkey upsell func signIn() async throws { let userInfo = try await signInWithPassword() guard !userInfo.hasPasskey else { return } let provider = ASAuthorizationPlatformPublicKeyCredentialProvider( relyingPartyIdentifier: "example.com") guard try offerPasskeyUpsell() else { return } let request = provider.createCredentialRegistrationRequest( challenge: try await fetchChallenge(), name: userInfo.user, userID: userInfo.accountID) do { let passkey = try await authorizationController.performRequest(request) // Save new passkey to the backend } catch { … } }
-
0:02 - Automatic passkey upgrade
// Automatic passkey upgrade func signIn() async throws { let userInfo = try await signInWithPassword() guard !userInfo.hasPasskey else { return } let provider = ASAuthorizationPlatformPublicKeyCredentialProvider( relyingPartyIdentifier: "example.com") let request = provider.createCredentialRegistrationRequest( challenge: try await fetchChallenge(), name: userInfo.user, userID: userInfo.accountID, requestStyle: .conditional) do { let passkey = try await authorizationController.performRequest(request) // Save new passkey to the backend } catch { … } }
-
0:03 - Modal passkey creation (web)
// Modal passkey creation const options = { "publicKey": { "rp": { … }, "user": { "name": userInfo.user, … }, "challenge": …, "pubKeyCredParams": [ … ] }, }; await navigator.credentials.create(options);
-
0:04 - Automatic passkey creation (web)
// Automatic passkey creation let capabilities = await PublicKeyCredential.getClientCapabilities(); if (!capabilities.conditionalCreate) { return; } const options = { "publicKey": { "rp": { … }, "user": { "name": userInfo.user, … }, "challenge": …, "pubKeyCredParams": [ … ] }, "mediation": "conditional" }; await navigator.credentials.create(options);
-
0:05 - New Credential provider Info.plist keys
<dict> <key>NSExtensionAttributes</key> <dict> <key>ASCredentialProviderExtensionCapabilities</key> <dict> <key>ProvidesPasswords</key> <true/> <key>ProvidesPasskeys</key> <true/> <key>SupportsConditionalPasskeyRegistration</key> <true/> <key>ProvidesOneTimeCodes</key> <true/> <key>ProvidesTextToInsert</key> <true/> </dict> </dict> </dict>
-
-
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.