Streaming is available in most browsers,
and in the Developer app.
-
Move beyond passwords
Despite their prevalence, passwords inherently come with challenges that make them poorly suited to securing someone's online accounts. Learn more about the challenges passwords pose to modern security and how to move beyond them. Explore the next frontier in account security with secure-by-design, public-key-based credentials that use the Web Authentication standard. Discover in this technology preview how Apple is approaching this standard in iOS 15 and macOS Monterey.
Resources
- 2020 Data Breach Investigations Report
- Connecting to a service with passkeys
- Supporting passkeys
- Supporting Security Key Authentication Using Physical Keys
Related Videos
WWDC21
-
Download
♪ Bass music playing ♪ ♪ Garrett Davidson: Hi, I’m Garrett, an engineer on the Authentication Experience team, and I'm very excited to give you a peek into what we’ve been working on: the first step Apple is taking to support the industry-wide transition away from passwords. Every time you sign in to an app or website today, you’re probably entering a password. The iconic User name and Password field pair is instantly recognizable and really easy to use, and most people immediately know what to do when they encounter it. But developers, users, and the industry as whole have collectively learned that this great convenience of being able to quickly authenticate to sign in to an account comes at a cost to account security. As authentication technologies have evolved over the years, there are a few fundamental lessons that the industry has learned. First off, protecting secrets is hard, especially when those secrets are shared. Most authentication today relies on the user and server sharing a secret -- like a password -- when the account is created, and resharing that secret during every authentication. Each time that secret is shared, there’s a risk that someone other than the intended recipient learns that secret. Phishing -- such as fake emails and phone calls or misleading websites -- is the most common way for the wrong party to learn a secret. And if a secret like a password does get out, using weak passwords or reusing the same password across multiple accounts can quickly compound the problem. In fact, according to the 2020 Verizon Data Breach Investigation Report, more than 80 percent of hacking-related data breaches involved the brute force of credentials or using lost or stolen credentials. It doesn’t have to be this way. Authentication technology has continued to evolve to try to mitigate some of these risks. At first, passwords were mostly stored in people’s heads. But it turns out that people generally aren’t good at coming up with and remembering strong and unique passwords for every account. Password managers can create strong, unique passwords per account, and can provide hints about some forms of possible phishing. iCloud Keychain’s password manager is built in to your Apple devices, and we’ve made APIs available for third parties to integrate their own password managers into the system. Service owners can also add additional steps to the login flow, such as requiring a password plus an additional factor like an OTP; for instance, an SMS or a generated one-time verification code. macOS Monterey and iOS 15 even have a code generator built in to the iCloud Keychain password manager, which you can learn more about in the “Secure login with iCloud Keychain verification codes” video from my teammate Eryn. Some apps and websites alternatively choose to outsource authentication entirely to a third party through federated authentication, such as Sign in with Apple. Federated authentication lets people keep their trust confined to a small number of highly protected accounts. But for this video, I’m going to be focusing on nonfederated authentication options. Let’s talk about how these compare. They’re all pretty easy to use, they all work on most devices, and they’re more or less always with you. But the security level could be better. Passwords that can be remembered probably aren’t strong and unique for every account. A password manager can be used to create strong and unique passwords, but it is only as strong as the password -- and potentially additional factors -- that you use to protect it. And single-use codes can also help but are still subject to many of the same problems as passwords, since they’re still typeable, phishable, shared secrets. Also, if passwords are in your head, you can forget them. This means apps and websites need a separate recovery flow, which today is usually a link in an email. This can reduce the entire account’s security level to the level of security of the email provider, which is generally not something you control. Some password managers and second-factor solutions can help with recovery but tend to face similar problems. Remembered passwords also don’t offer any kind of phishing resistance. Password managers can provide hints about phishing -- such as not offering to fill a password on a phishing site that looks otherwise legitimate -- but they still can’t prevent someone from manually entering the password themselves and getting phished. One-time codes have similar problems, though there are some modern mitigations you can put in place. And finally, all of these methods rely on a shared secret between the user and a server, making them fundamentally no stronger than the weakest protection of that shared secret. With that chart in mind, let’s talk about the properties of an actual solution to the password problem. First off, a replacement for passwords needs to be secure by design. Passwords can be reasonably secure, if all of the best practices are followed. However, experience has shown us that that’s pretty hard for everyone to do all of the time. A replacement for passwords should build that security in from the beginning. But we don’t want to go backwards in usability either. Passwords have been with us for so long because they’re so easy to use. We don’t want to lose that. Being easy includes always being available and being usable everywhere. Today, as long as I know or can look up my password, I can pretty much assume that the device I want to sign into supports it. Any additional friction to authenticating on new devices is going to hurt adoption from people who just want to quickly get signed in. And finally, recovery should be a first-class feature not something that gets added as an afterthought. People make mistakes, bad things happen, and a solution to passwords should be fault tolerant enough to handle humans being human without compromising the overall security. One of the strongest security options out there today is security keys, the hardware dongles or fobs that are generally used as a second factor in especially high security contexts. They are based on the web authentication -- or WebAuthn -- standard, which is open to everyone. And most of them are pretty easy to use after the initial learning curve. And they’re way more secure than just a password. Most of this strength comes from WebAuthn, which I’ll talk about more in a bit. Modern web browsers also support security keys on most modern devices. Safari on macOS and iOS has supported USB, NFC, and Lightning security keys for a while. Most security keys also support more than one connection method, so a single hardware key can be used on many different devices. Let’s compare WebAuthn and passwords. One of the biggest advantages of WebAuthn is it uses public/private key pairs instead of shared secrets. If we examine how passwords work today, first you enter your password. Then, it’s usually obfuscated through something like hashing plus salting, and the resulting salted hash is sent to the server. Now, both you and the server have a copy of the secret, even though the server’s copy is obfuscated, and you’re both equally responsible for protecting that secret. This is what we’re getting rid of. With public/private key pairs, instead of a password, your device creates a pair of keys. One of these keys is public; just as public as your username. It can be shared with anyone and everyone, and is not a secret. The other key is private. This private key is a secret and is protected by your device. Your device never shares this key with anyone else, not even the server. When you create an account, your device generates these two associated keys. It then shares the public key with the server. Now, the server has a copy of the public key, which does not have the same protection requirements as a password because it’s public information. The private key stays on your device, and only that device is responsible for protecting it. Later, when you want to sign in, you don’t send the server anything secret. Instead you prove that it’s your account by proving that your device knows the private key associated with your account’s public key. That exchange works like this. First, I go to sign in to my account. Then, the website asks my device to prove that it’s actually my account. It does this by performing what’s called a "challenge" for me to prove that my device has the private key associated with my account’s public key without actually saying what my private key is. To do so, the server sends back a single-use challenge. My device has the private key, so it takes that challenge and does something called “signing” of the challenge, using my private key. Only my private key can produce a valid signature for my account. This signature then gets sent back to the server. The server already has my public key, so it can check this signature against that public key. Anyone who has my public key can easily check if a signature matches that key. However, only I can create a valid signature for the challenge because only I have the private key. Therefore, anyone can easily verify my identity without ever learning what my secret is. And finally, assuming the signature does actually match my public key, the server tells me I’m signed in! Notice that my private key never left my device. The server was able to verify that this is my account without ever learning what my secret -- my private key -- actually is.
Because public/private key pairs mean credentials are created and managed by the device -- and private keys are never shared with a server -- these keys are never going to be guessable, reused, weak, or vulnerable to your server being breached. WebAuthn also roots its trust in the browser and operating system, not the human. The software strictly enforces that credentials are only ever usable on the websites and apps that they were created for, preventing someone from even attempting to authenticate on the incorrect website. And because all credentials in WebAuthn are public/private key pairs, the server is no longer responsible for maintaining authentication secrets. This means less work on the server side to keep secrets safe, and servers are less valuable targets for attackers because there are no authentication secrets for an attacker to steal. Let’s compare security keys to the other items in that chart. They’re fairly easy to use after the initial learning curve. They work on all of your Apple devices and many modern non-Apple devices. But they’re not necessarily always with you. You need to purchase and carry around additional hardware at all times. This can be a barrier to entry for adoption, and is a step back in usability compared to passwords. The security level is very good, though. Credentials on a security key are guaranteed to never be easily guessable or reused across multiple accounts, and have phishing protection built in at the OS level. That security comes at a price, though. If credentials are tied to single security key and that security key is ever lost, stolen, or damaged, so are all of those credentials. Adopters must have a backup system in place, such as purchasing an additional security key, storing it somewhere safe, and hoping they never lose both at the same time. Thanks to WebAuthn, though, they do provide very strong phishing resistance and remove the need for server-stored secrets. In iOS 14.5, we extended security key support to work in all browsers on iOS. New in macOS Monterey and iOS 15, we’re also making security key API available for the first time for all apps on macOS and iOS. This API is being added to the ASAuthorization API family in the AuthenticationServices framework, as a native equivalent to the WebAuthn API on the web. ASAuthorization is your one-stop shop for getting signed in with whatever mechanisms the system supports, including passwords, Sign in with Apple, and now security keys. Carrying around additional hardware, like a security key, isn’t necessarily for everyone, though. We believe this API will be useful for apps in especially high-security contexts, where the usability tradeoffs for your users are outweighed by special security needs, and we’re excited for you to try it out if you fall in that category. Now, passwordless authentication using key pairs is the next big thing in authentication technology. The standard has been a collaborative effort across the industry from both platform vendors and service owners with the goal of pushing account security forward. Support for WebAuthn is growing across operating systems, app platforms, web browsers, and websites. What I’m going to be talking about for the rest of this video, and what I’m really excited to introduce here, is a preview of Apple’s contribution to a postpassword world; a new feature that builds the security of WebAuthn into every iPhone, iPad, and Mac, so it can be used everywhere as a replacement for passwords. It’s called "passkeys in iCloud Keychain". This new feature stores a new type of credential, called a "passkey", in your iCloud Keychain. Passkeys are WebAuthn credentials with the amazing security that the standard provides combined with the usability of being backed up, synced, and working on all of your devices. We’re storing them in iCloud Keychain. Just like everything else in your iCloud Keychain, they’re end-to-end encrypted, so not even Apple can read them. Your secrets are your secrets. And they’re very easy to use. In most cases, it just takes a single tap or click to sign in. And they’re stronger than most password-plus-second-factor solutions out there today, thanks to the combined security of WebAuthn and iCloud Keychain. And because it’s just a single tap to sign in, it’s simultaneously easier, faster, and more secure than almost all common forms of authentication today. Let’s add it to that chart. As I just said, it’s super easy to use; usually just one tap, or click, to sign in. What we’re releasing as part of macOS Monterey and iOS 15 works on all of your Apple devices. Of course, to replace passwords for everyone, this technology needs to work on all of your devices, including those that don’t support iCloud Keychain. That functionality is not present in macOS Monterey and iOS 15. Because it’s built in to all of your Apple devices, it’s available any time you have your iPhone, iPad, or Mac nearby. No additional hardware required. It builds on all of the advanced protections that are part of both the WebAuthn standard and iCloud Keychain. And since it’s backed by iCloud Keychain, you can still get your credentials back, even if you lose all of your Apple devices. It has the same strong platform-provided phishing resistance as security keys. And because it uses public/private key pairs, it also means servers can get out of the business of storing authentication secrets, making them less valuable targets for attackers. So here’s how it works. This is Shiny, our favorite authentication demo app, whose source code you can find in the related links for this video. First, I need to create my account. I’m going to type in my username and tap the Create Account button. Then, a trusted system sheet comes up with some information about the credential and where I can expect to use it. I’m going to tap Continue, Face ID, and I’m done. I didn’t really have to think about it, but I now have a very strong public/private key credential for this account, which is safely stored in my iCloud Keychain. When I come back to this app and want to sign in, it’s just as easy. When the sheet comes up, I get asked a very clear question, including the name of the app I’m signing into and my account. That’s what I want, so I’m going to tap Continue, Face ID, and I’m done. That’s it! This is all it takes for people to create and use these new credentials. And because they’re system-managed public/private key pairs, they won’t be reused or guessable, they’re not vulnerable to breaches of the app or website, and very strong phishing protections are built in to the operating system and browser. Speaking of browsers, these credentials also work on the web. Here I am in Safari on the Shiny website’s home page, which has adopted WebAuthn. When I tap the Sign In button, I get options here to use the credential that I just created or a security key if I want to use that. I can tap Continue here, Face ID, and I’m signed in, just like in the app. This also works in all web browser apps on iOS. And it works on Mac, too! These credentials are stored in iCloud Keychain, so they sync across all of your devices, and they work in all kinds of Mac apps, as well as on the web in Safari. Now let’s take a peek at the implementation. First off, for that strong, platform-provided phishing protection to work for your apps, the device needs a strong association between your app and website. This is done through associated domains, using the “webcredentials” association type. I won’t go into too much detail here, but you can learn more by watching the “Introducing Password AutoFill for Apps” video from a few years ago. Next, let’s talk about creating an account. The code here is actually pretty straightforward. Let’s break it down. Our createAccount function needs three inputs: a single-use challenge fetched from your server, the username for the account, and the userID, which is generally the identifier for the account on your backend. First, you need a request provider to create request objects. The relyingPartyIdentifier depends on your WebAuthn setup, but it’s usually your domain name. Use that provider to create a registrationRequest and pass the request to an authorization controller. Finally, set the delegate and presentationContextProvider on the authorization controller and start your request. This will cause that sheet from earlier to pop up and ask you to create a credential. When the transaction is finished, you’ll receive a delegate callback with the details of the new credential. Now, signing in is very similar. Just a few things need to change. Instead of creating a registrationRequest, you now create an assertionRequest, which is the WebAuthn terminology used when signing in. The assertionRequest only needs a challenge. And that’s all you need to change. I want to take a second to highlight that this parameter to the authorization controller is an array. You can pass in a list here of requests for all of the different authentication mechanisms that your app supports, including passwords and Sign in with Apple. That sheet from earlier will be populated with whatever credentials are currently available. The only caveat is that public key registration requests can’t be mixed with nonregistration options. OK, so finally, let’s talk about the callback to your delegate object when the authorization completes. The credential is a property of the provided authorization object. If the user registered a new platform credential, you’ll receive a platform credential registration. If they signed in with an existing platform credential, you’ll receive a platform credential assertion. Or if they signed in with something else that you support, you can handle that here, too. In any case, you should read the properties that you need from the credential object just like you would on the web, send those values off to your server, verify them, and finish the operation. And that’s how it works. Now, I just want to mention a few more details. A transition away from passwords is going to take time, and it’s important to get the details right. In macOS Monterey and iOS 15, passkeys in iCloud Keychain is being released as a technology preview and is off by default. On iOS, there’s a new switch in the Developer settings section of the Settings app. Turning this on will allow you to use these synced keys in both apps and on the web. And on macOS, the switch lives in Safari’s Develop menu. First, you’ll need to turn on the Develop menu, in Safari’s Advanced settings. You’ll find the setting for this at the bottom of the Advanced pane in Safari’s preferences. Then, you can find the option to turn on the Syncing Platform Authenticator in the Develop menu. Make sure to turn the feature on when testing. In macOS Monterey and iOS 15, these passkeys are only meant for testing, not for production accounts. The emphasis of this preview is the authentication technology, an iCloud Keychain-backed WebAuthn implementation. An industry-wide transition away from passwords will need thoughtful and consistently applied design patterns, which are not part of this preview. And finally, since this is a preview, we've made sure it behaves gracefully when turned off. Platform registration requests will return an error, and platform assertion requests will be silently ignored when the switch is off, even when mixed with other credential request types. So here’s what you can do next. Public key-based, phishing-resistant credentials are the next frontier in account authentication. Go check out our developer documentation and the sample code linked from this video to help you get started. And if you don’t already have one, bring up a WebAuthn implementation on your server, so that you can start trying out WebAuthn-based credentials. Now, my favorite part: try out this technology preview of passkeys in iCloud Keychain to see how it fits into your existing workflows in your websites and apps. As you’re trying it out, please let us know what you think in the developer forums and Feedback Assistant. We really want to hear from you. As I mentioned earlier, this is the first step of a multiyear effort in replacing passwords, and we’re very interested in what you all have to say. Thank you for watching! ♪
-
-
17:32 - Register an account
// Register an account func createAccount(with challenge: Data, name: String, userID: Data) { let provider = ASAuthorizationPlatformPublicKeyCredentialProvider( relyingPartyIdentifier: "example.com") let registrationRequest = provider.createCredentialRegistrationRequest( challenge: challenge, name: name, userID: userID) let controller = ASAuthorizationController( authorizationRequests: [ registrationRequest ]) controller.delegate = … controller.presentationContextProvider = … controller.performRequests() }
-
17:39 - Sign in
// Sign in func signIn(with challenge: Data) { let provider = ASAuthorizationPlatformPublicKeyCredentialProvider( relyingPartyIdentifier: "example.com") let assertionRequest = provider.createCredentialAssertionRequest(challenge: challenge) let controller = ASAuthorizationController( authorizationRequests: [ assertionRequest ]) controller.delegate = … controller.presentationContextProvider = … controller.performRequests() }
-
17:41 - Handle returned credentials
// Handle returned credentials func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) { switch authorization.credential { case let registration as ASAuthorizationPlatformPublicKeyCredentialRegistration: let attestationObject = registration.rawAttestationObject let clientDataJSON = registration.rawClientDataJSON // Verify on your server and finish creating the account. case let assertion as ASAuthorizationPlatformPublicKeyCredentialAssertion: let signature = assertion.signature let clientDataJSON = assertion.rawClientDataJSON // Verify on your server and finish signing in. case …: … } }
-
-
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.