Streaming is available in most browsers,
and in the Developer app.
-
What’s new in passkeys
Discover how iOS, iPadOS, macOS, and visionOS 26 enhance passkeys. We'll explore key updates including: the new account creation API for streamlined sign-up, keeping passkeys up-to-date, new ways to drive passkey upgrades through automatic passkey upgrades and passkey management endpoints, and the secure import/export of passkeys. Learn how these improvements enhance user experience and security, and how to implement these updates in your apps to provide a smoother, more secure authentication experience. To get the most out of this video, first watch “Meet passkeys” from WWDC22.
Chapters
- 0:00 - Introduction
- 0:58 - The passkey journey
- 3:30 - Account creation API
- 10:48 - Keep passkeys up-to-date
- 14:41 - Automatic passkey upgrades
- 16:59 - Passkey management endpoints
- 19:12 - Importing and exporting passkeys
Resources
- ASCredentialExportManager
- ASCredentialProviderViewController
- Performing fast account creation with passkeys
Related Videos
WWDC24
WWDC22
-
Search this video…
Hey, I’m Andrew, an engineer on the Authentication Experience team. We care a lot about making sign-in simple, fast, and secure.
Passwords are the root cause of many of the problems with sign-in and account security. The industry has been working to solve these problems at their source by eliminating the use of passwords for online accounts in favor of passkeys. Passkeys fundamentally solve the security and usability problems with passwords, including eliminating phishing as we know it today, all while delivering a delightful sign-in experience.
And since you're watching this video, you’re on the team that’s making this happen. We’re working toward that important, overarching goal of replacing passwords with passkeys.
The passkey journey is the path to this goal, an industry-wide transition to authentication secured only by non-phishable factors. It involves moving through stages. Prior to passkeys, many accounts were created relying only on phishable factors, like passwords or one-time codes sent over SMS or email.
The journey began by adding a non-phishable method, like passkeys, as an additional sign-in method. This is where much of the industry is today. The goal is for all accounts to reach a state of having no phishable factors, and passkeys are how the industry will get everyone there.
There is fantastic momentum across the board with growing adoption from users and increasing support across services. In 2025, the FIDO Alliance, the standards body behind passkeys, did a study and found 69% of people surveyed have at least one passkey.
Google published that people signing in with passkeys are four times more successful at getting into their accounts than those using passwords. And TikTok has observed a stunning 97% sign-in success rate for people using passkeys. This kind of sign-in success with passkeys is common across the industry and unheard of with passwords.
This growing and successful adoption shows clear progress on the passkey journey. iOS, iPadOS, macOS, and visionOS 26 build on passkeys with new enhancements that make it even easier for people to discover, create, and use them across your apps and websites.
I’ll cover five key updates. First, the new account creation API. It’s the fastest, easiest way to create a new account, and it gives you a passkey from the start.
Then, I’ll cover keeping passkeys up to date, showing you how to sync account changes with credential managers.
Next, automatic passkey upgrades, providing a seamless path for adding passkeys to existing password-based accounts. After that, passkey management endpoints, a way to showcase your service’s passkey adoption directly within credential managers.
And finally, importing and exporting passkeys, an important ecosystem advancement that gives people more flexibility and control over their passkeys.
First up, the new account creation API. Unlike traditional password-based sign-ups, setting up a passkey isn’t a lengthy or complex process. A quick, simple sign-up feels effortless. Passkeys don’t rely on someone creating a complex password and trying to recall it.
Passkeys make sign-in fast and effortless, and they’re resistant to phishing. With the account creation API and the latest OS releases, sign-ups can be a delightful, fast, and a fundamentally more secure experience.
I’ll show you on my iPhone in my demo app, Shiny. It promises one cute picture a day.
Like anyone encountering a new app, the first step is signing up. This is the traditional way before adopting the account creation API.
I’ll start by creating a new account with my email.
I'm immediately asked to fill out a form, starting with the email. Fortunately, autofill does help me out here.
That's the email done.
Now I’ll do my first name and my last name.
And the dreaded password, of course. I’ll go with the best case scenario and use the automatic strong password.
And finally, after all that tap continue and I’m signed up. There’s the cute picture. How adorable.
Now I’ll try this again after adopting the account creation API. In a similar fashion, I’ll create a new account with my email.
But notice, instead of the multi-step form, the system presents a sheet that shows exactly what Shiny is requesting. In this case, my name and email and a passkey that will be saved in the Passwords app. And the best part, it’s all prefilled for me.
This is the new streamlined flow powered by the account creation API.
The info I share is editable. When I tap a field, I get a picker that offers suggestions and I can switch between them or manually enter something. I’m happy with the defaults here. So I’ll tap continue, Face ID authenticates me, and that’s it. I'm signed up and into Shiny. Much faster, simpler, and more secure.
And signing in is just as effortless.
If I later grab my iPad and launch Shiny for the first time on it, I immediately get a sign-in prompt because the app is set up to check for existing credentials right at launch. And the passkey I created earlier is available across all my devices.
Tap continue, Face ID, and I’m in. So easy! This experience is available on apps on iOS, iPadOS, macOS, and visionOS, and it works with the Passwords app and third-party credential managers.
Now, I’ll go through the implementation that powers that sign-up experience.
Here’s a function showing the core steps for account creation. Start by initializing the new account creation provider. Next, with that provider, create a passkey registration request. This method is where the key details are specified. The first parameter is accepted contact identifiers. This tells the system what kind of account identifiers your app supports. Your app receives only the one chosen identifier for creating the account, which is also used as a passkey’s user name label.
Should request name determines whether to request the user’s name. You should only set this to true if it’s necessary for account creation.
The next three pertain to the passkey that’ll be created. These match standard passkey registration, so provide the same data as you would for that request.
The relying party to register the passkey with, generally a domain name, a single use challenge to be signed by the created passkey, fetched from your server, and the user ID is a stable, unique identifier you create for the account.
Next, get an instance to ASAuthorizationController. In a SwiftUI view, you can access that using the Environment property wrapper.
Then, perform the request. When someone successfully completes the sign-up flow, you’ll get back an ASAuthorizationResult. Unwrap it and you’ll now have access to a contact identifier, the name if requested, as well as a passkey object. Go ahead and create a new account on your server and sign them in.
And that's really the core of adoption.
If something goes wrong, the perform method will throw an error that you can handle to make the experience great in all cases. Alongside the standard AuthenticationServices errors, there are three errors to handle especially relevant to this API. The first is deviceNotConfiguredForPasskeyCreation This means the device isn’t in a state to create a passkey right now, such as if it doesn’t have a passcode set. You can present your standard sign-up form knowing they aren’t eligible for passkey creation at this time. When tapping the use email or phone number button in Shiny, this error is handled by presenting a custom sign-up form.
The next is canceled. This error is thrown if someone dismisses the sign-up sheet without completing it. In this case, you can present your standard sign-up form. When the system sheet is dismissed in Shiny, this error is handled by presenting a custom sign-up form. And the last is preferSignInWithApple. You’ll only ever get this error back if your app supports Sign in with Apple. It’s designed to help prevent accidental duplicate accounts. If someone initiates the account creation flow but already has an account for your service using Sign in with Apple, the system reminds them by showing an alert like this.
They’re given a choice: use their existing Sign in with Apple account or continue creating a new account. If they use their existing account, that’s when this error is thrown. So when you receive this error, the best practice is to initiate a Sign in with Apple request, which presents the Sign in with Apple sheet. That respects their choice and gets them signed into their existing account without extra taps.
That’s all for errors. Another best practice is to offer any existing accounts immediately on app launch, helping guide people to get signed back into your app. Recall from the iPad demo, I was immediately prompted to sign in with my passkey, without needing to think about whether I had an existing account or how I signed in last time.
This happened because Shiny used a combined sign in request with the prefer immediately available credentials option set. If someone has any available account credentials on their device, whether a passkey or password from any credential manager app or an account using Sign in with Apple, they’ll be offered for sign in. And if there aren’t any credentials immediately available, no UI is shown, leaving your sign-in screen uninterrupted.
To learn about adopting this, watch the “Meet Passkeys” video from WWDC22.
And that’s the account creation API, a brand new feature that makes sign-up effortless and secure.
Once an account is created, ensuring its passkey information stays accurate in credential managers helps maintain a smooth experience. This brings me to the next topic, keeping passkeys up to date.
Accounts aren't static. People update their information, like user names or email addresses, and can revoke passkeys. If credential managers show outdated information during sign-in, it can cause confusion and slow down or prevent someone from signing into your service. There's a new collection of API that enable your app or website to signal to credential managers about changes to an account. Adopting these signal APIs keep entries accurate, ensuring sign-ins are fast, reliable, and just work.
Here’s how this works in Shiny. Imagine I’ve recently graduated from university and want to switch my account for my old student email to my personal one.
I go into the app settings, tap email, and enter my new email.
Then I save.
Immediately after, my credential manager, The Passwords app notifies me that the user name changed.
And if I tap on it, Passwords authenticates me and then presents the details for the account.
Notably, the user name reflects the new personal email. The credential manager now matches what's on the app's backend.
How neat is that! This is enabled by a new API available for apps and the web. For apps, the new ASCredentialUpdater class provides methods to report specific credential changes. For the web, equivalent methods are part of the WebAuthn standard supported in Safari 19 and other browsers.
The first signal is for changing the user name. Like in the demo, if someone updates their user name, email address, or whatever label is shown for the account, use the reportPublicKeyCredentialUpdate method to inform the credential manager. This ensures that the label displayed during sign-in is always up to date, preventing any confusion. As a reminder, user names on passkeys are a local only label. They are not returned to the server during authentication.
For the web, use the signalCurrentUserDetails method on PublicKeyCredential to accomplish the same thing.
Next, revoking a passkey.
Many apps and websites have passkey management pages where someone can revoke an individual passkey or create a new one.
Anytime a passkey gets revoked, call the reportAllAcceptedPublicKeyCredentials method, specifying the credential IDs that remain valid.
When you do this, credential managers will delete any passkeys they have that aren’t in the set of what you provided. That will prevent any invalid passkey from being offered when someone signs in. You can also call this periodically as a health check for an account. If something has changed, this will help make sure credential managers are in the loop.
And you can do the same on the web too, using the signalAllAcceptedCredentials method.
Ultimately, the most secure accounts are the ones that don’t have a password at all. Accounts created with the new account creation API never have a password, so they’re secure from day one.
For existing accounts, you can now inform credential managers when a password is no longer needed. The reportUnusedPasswordCredential API signals that an account has taken that final step on the passkey journey, and is password-free.
And of course, all credential managers can participate in handling these signals. There is new API to adopt to listen to these update signals and keep managed credentials up to date.
For more information, check out developer documentation for the report methods on ASCredentialProviderViewController.
So these new API help maintain credential accuracy.
Next, I’ll focus on encouraging the adoption of passkeys, especially for people still signing in with passwords.
Automatic passkey upgrades provide a seamless path for adding passkeys to existing password-based accounts.
Your app or website can create one right after a password sign-in with zero friction. I'll show you. Back in Shiny, imagine I still use the password and want to sign in.
I’ll autofill my user name and password and tap sign in, and I'm in.
But because Shiny adopted automatic passkey upgrades, here's what happens now. I got a notification that a passkey has been created. No upsell screens or interruptions, just a seamless transition unlocking a simpler and more secure sign-in experience.
It’s important to note that the password I just used still works. This process simply adds the passkey as a secure way to sign in.
Drawn in code, this is an automatic passkey upgrade.
After someone signs in using a password, you have access to their account details. Start by ensuring the account doesn't already have a passkey.
If not, create a passkey registration request as you would when creating a passkey.
Setting the request style to conditional is what enables the automatic passkey upgrade. With that set, after you perform the request, the system and credential manager run checks in the background. These include verifying if a credential manager is available, if the password for this account was just used, and if the device is set up for passkeys. If all the preconditions are satisfied, the system creates a passkey and shows a notification, and your app receives that passkey object to save, all of which happens without interrupting or blocking the user.
If any of the preconditions weren’t satisfied, the call fails silently. The system will not show any UI and no specific error handling is needed.
Your app should attempt the upgrade on every password sign-in, if the user doesn’t already have a passkey.
There's also an equivalent web API. To learn even more about automatic passkey upgrades, watch the WWDC24 video “Streamline sign-in with passkey upgrades and credential managers”.
Automatic upgrades offer that ideal zero-friction path.
To complement this, adopting the well-known URL for passkey management endpoints, lets you surface direct links from credential managers to your passkey management pages. It’s a great way to highlight your passkey adoption. I'll show you. Here, I’m in the Passwords app, reviewing a saved entry for Shiny that still uses a password.
Notice the new section letting me know there's a passkey upgrade available. Tapping the add passkey button opens the website directly to the page specified for passkey enrollment.
Implementing this standard creates a direct link from credential managers right to your passkey enrollment pages. This enables another way for people to upgrade right from their credential manager. And because it's built on a standard, this works across all participating credential managers.
To support this, survey JSON response at the well known passkey end points path on your server.
The response must be directly from this path, not through a redirect.
Serve this response with a 200 OK status code and a content type header of application JSON.
The response content is a JSON dictionary pointing to relevant pages on your website.
Enroll is the URL where someone adds a passkey to their account. This is what the add passkey button in the Passwords app links to.
Manage is the URL where someone manages their existing passkeys, analogous to a changed password page. It’s where someone can revoke existing passkeys or add a new one.
All fields are optional, but it’s best to include both.
It’s important that these URLs correctly handle people that arrive without an authenticated session. If sign-in is necessary, first authenticate, then redirect back to the originally requested URL.
Also, ensure that this page is accessible and served to all user agents. It’s not just web browsers that’ll request this. Apps like credential managers will too.
By implementing the well-known URL for passkey management endpoints, you provide credential managers a hint to guide people toward adopting passkeys for your service.
Next, I’ll cover importing and exporting passkeys.
People own their credentials and should have the flexibility to manage them where they choose. That's why I'm happy to let you know, passkeys can now be transferred securely between participating credential manager apps on iOS, iPadOS, macOS, and visionOS 26. This gives people more control over their data and the choice of which credential manager they use.
This new process is fundamentally different and more secure than traditional credential export methods, which often involve exporting an unencrypted CSV or JSON file, then manually importing it into another app. The transfer process is user initiated, occurs directly between participating credential manager apps and is secured by local authentication like Face ID.
This transfer uses a data schema that was built in collaboration with the members of the FIDO Alliance. It standardizes the data format for passkeys, passwords, verification codes, and more data types.
The system provides a secure mechanism to move the data between apps. No insecure files are created on disk, eliminating the risk of credential leaks from exported files. It’s a modern, secure way to move credentials.
Apps and websites don’t need to do anything to accommodate credential transfer because the process happens directly between credential managers. Existing passkeys remain unchanged and will continue to work seamlessly.
For credential manager apps looking to support credential transfer, refer to the developer documentation for ASCredentialExportManager and ASCredentialImportManager.
Passkeys continue to advance, offering stronger security with simpler experiences. The new OS releases make them even easier to create, use, and discover. We’re on this journey together to a passwordless future, and your adoption of these features is key to making that a reality for everyone. So to help you continue to deliver the best authentication experience, here are the next steps. First, adopt the account creation API for secure and quick onboarding.
Next, keep passkeys up to date using the Signal API to keep credential managers informed about account changes like updated user names or passkey removals. Then enable automatic passkey upgrades for the most seamless transition from passwords. And finally, make passkey upgrades discoverable from credential managers by serving the passkey management endpoints from your website. That's what's new in passkeys. Thanks for watching.
-
-
6:33 - Account creation
// Account creation @Environment(\.authorizationController) var authorizationController func performPasskeySignUp() async throws { let provider = ASAuthorizationAccountCreationProvider() let request = provider.createPlatformPublicKeyCredentialRegistrationRequest( acceptedContactIdentifiers: [.email, .phoneNumber], shouldRequestName: true, relyingPartyIdentifier: "example.com", challenge: try await fetchChallenge(), userID: try await fetchUserID() ) do { let result = try await authorizationController.performRequest(request) if case .passkeyAccountCreation(let account) = result { // Register new account on backend } } catch ASAuthorizationError .deviceNotConfiguredForPasskeyCreation { showPasswordSignUpForm = true } catch ASAuthorizationError.canceled { showPasswordSignUpForm = true } catch ASAuthorizationError.preferSignInWithApple { await performSignInWithApple() } catch { ... } }
-
12:30 - Changing the user name
// Changing the user name try await ASCredentialUpdater() .reportPublicKeyCredentialUpdate( relyingPartyIdentifier: "example.com", userHandle: userHandle, newName: "andrew@example.com" )
-
12:58 - Changing the user name
// Changing the user name await PublicKeyCredential.signalCurrentUserDetails({ rpId: "example.com", userId: userHandle, name: "andrew@example.com", displayName: "andrew@example.com" });
-
13:07 - Revoking a passkey
// Revoking a passkey try await ASCredentialUpdater() .reportAllAcceptedPublicKeyCredentials( relyingPartyIdentifier: "example.com", userHandle: userHandle, acceptedCredentialIDs: acceptedCredentialIDs )
-
13:46 - Revoking a passkey
// Revoking a passkey await PublicKeyCredential.signalAllAcceptedCredentials({ rpId: "example.com", userId: userHandle, allAcceptedCredentalIds: acceptedCredentialIds });
-
14:04 - Removing a password
// Removing a password try await ASCredentialUpdater() .reportUnusedPasswordCredential( domain: "example.com", username: "andrew@example.com" )
-
15:36 - Automatic passkey upgrade
// Automatic passkey upgrade func signIn() async throws { let accountDetails = try await signInWithPassword() guard !accountDetails.hasPasskey else { return } let provider = ASAuthorizationPlatformPublicKeyCredentialProvider( relyingPartyIdentifier: "example.com") let request = provider.createCredentialRegistrationRequest( challenge: try await fetchChallenge(), name: accountDetails.userName, userID: accountDetails.userID, requestStyle: .conditional ) do { let passkey = try await authorizationController.performRequest(request) // Save new passkey to the backend } catch { ... } }
-
-
- 0:00 - Introduction
The entire industry is working to eliminate passwords in favor of passkeys — a more secure and user-friendly method that eradicates phishing, and streamlines the sign-in process.
- 0:58 - The passkey journey
Updates to iOS, iPadOS, macOS, and visionOS make passkey creation, management, and upgrading easier, accelerating passkey adoption. The industry is transitioning from phishable passwords and SMS/email codes to non-phishable passkeys. Many accounts offer passkeys as an additional sign-in method, but the goal is to eliminate phishable factors entirely. Adoption of passkeys is growing rapidly and passkeys have high sign-in success rates. The FIDO Alliance found that 69% of people have at least one passkey, Google found signing in with passkeys is four times more successful than passwords, and TikTok sees a 97% success rate with passkey sign-ins.
- 3:30 - Account creation API
The new account creation API revolutionizes the sign-up process for apps. This API is available on iOS, iPadOS, macOS, and visionOS, and works with the Passwords app and third-party credential managers. People can now create accounts with passkeys directly, which makes the experience more user-friendly, and reduces the risk of phishing attacks. The sign-up process with the account creation API is incredibly streamlined. Instead of a multi-step form, a pre-filled sheet shows exactly what the app is requesting for sign-up, and is customizable by the user. Upon completion, the system automatically generates a passkey, which is saved in the Passwords app. The benefits of passkeys extend beyond sign-up. Signing in is effortless, and passkeys are automatically synced across all devices. The account creation API is easy to adopt, and handles potential errors gracefully, providing a smooth sign-up experience even if a device is not configured for passkey creation, or already has an account using Sign in with Apple.
- 10:48 - Keep passkeys up-to-date
New signal APIs enable apps and websites to notify credential managers of account information changes, such as usernames, email addresses, or when passkeys are revoked. This ensures that credential managers remain up-to-date, preventing confusion and login issues. For example, when someone updates their email address in an app, the app immediately signals the credential manager, which then updates its records. These APIs support accounts without passwords which are the most secure accounts. The APIs also inform credential managers when passwords are no longer needed, enhancing overall security and improving user experience.
- 14:41 - Automatic passkey upgrades
Automatic passkey upgrades enhance account security for those still signing in with passwords without introducing friction. After a successful password login, apps and websites can create passkeys in the background. A notification informs when a passkey is added, providing a simpler and more secure sign-in option moving forward. The password remains valid, and the upgrade process occurs on every password sign-in attempt if a passkey doesn't already exist.
- 16:59 - Passkey management endpoints
By implementing the standard, well-known URL for passkey management endpoints, websites can directly link credential managers to their passkey enrollment and management pages. This approach streamlines the passkey-upgrade process, so people can easily switch from passwords within their credential managers. The JSON response from the server must include URLs for enrollment and management, be served with a '200 OK' status code, and be accessible to all user agents, including apps and web browsers.
- 19:12 - Importing and exporting passkeys
Passkeys can now be securely transferred between participating credential manager apps across iOS, iPadOS, macOS, and visionOS 26. This user-initiated process, secured by local authentication like Face ID, reduces the risk of credential leaks. The transfer uses a standardized data schema developed by the FIDO Alliance, ensuring compatibility between apps. Deliver the best authentication experience and help people move to a more secure future without passwords. Adopt the account creation API for secure and quick onboarding, keep passkeys up-to-date using the signal API, enable automatic passkey upgrades, and support passkey management endpoints.