Video hosted by Apple at devstreaming-cdn.apple.com

Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2020-10666
$eventId
ID of event: wwdc2020
$eventContentId
ID of session without event part: 10666
$eventShortId
Shortened ID of event: wwdc20
$year
Year of session: 2020
$extension
Extension of original filename: mp4
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: [2020] [Session 10666] One-tap a...

WWDC20 • Session 10666

One-tap account security upgrades

Frameworks • iOS, macOS • 24:06

When you adopt the Account Authentication Modification Extension, you can provide people with fast, easy account security upgrades to use Sign in with Apple and strong passwords in the iCloud Keychain Password Manager. We’ll show you how to add these upgrade flows to your app with the Account Authentication Modification Extension, the AuthenticationServices Framework API, and best practices required for a smooth password transition.

Speaker: Jay S. Mulani

Open in Apple Developer site

Transcript

Hello and welcome to WWDC. Hi there, my name is Jay Mulani, and I'm gonna talk to you about one-tap account security upgrades. I'm so excited to talk to you today about what we've added in iOS this year to help improve your users' account security. We've got some great new features that raise user awareness about account security risks, and with your buy-in, make addressing those risks faster and easier than ever.

We'll get started with a brief discussion on account security, and then walk through security recommendations new in iOS this year. I'll show you how to adopt our new extension point to offer your users fast, easy security upgrades on the operating system. And then how to add those flows within your app. We'll close with some best practices on adopting the extension.

Let's start by talking about account security. Accounts are staples of our identities. We use them to manage our most personal, private data, and to access services that power our lives. Accounts manage our finances, health, emails, social media profiles, and more. Accounts are so important. Their ever-growing integral role in our lives means that we have a lot of them to keep track of and that they need to be carefully protected. Most accounts are unlocked with passwords, and so account management is heavily dependent on password management. Many of you are already using iOS and macOS features to make password management easy for your users.

Password AutoFill provides users with a super-fast and convenient login experience. AuthenticationServices takes this a step further and removes a keyboard from the sign-in process. Security Code AutoFill streamlines the login process for accounts that have SMS two-factor authentication enabled. And Sign in with Apple completely removes the password component of account management. It's the fastest way for users to get a new account and sign in. Accounts should be convenient to use and secure.

These features I just mentioned, integrated into your apps, make signing in super easy. In this year's iOS, we've added new account management features and APIs to help you keep your users' accounts secure. My goal today is to show you how beneficial it is, and how easy it is, for you to use these new features to continue our joint mission of keeping users' accounts secure. To motivate that, let's talk about the new Security Recommendations feature.

Every iPhone and iPad has the built-in iCloud Keychain password manager. It's deeply integrated with the operating system and securely synchronizes passwords across all of a user's devices. It provides easy password lookup and powers Password AutoFill, and now it's home to Security Recommendations. This new section of the password manager will show all of the warnings the system has found with passwords saved in Keychain. Security Recommendations educates users about why certain passwords are flagged and motivates them to take action.

High-priority recommendations will be highlighted based on the severity of the warning and the type of account. The system will flag passwords that are reused across sites, easily guessed, and, new this year, iOS will flag passwords that are seen in public data breaches. In fact, iCloud Keychain will show users notifications when one of their passwords has been seen in a data breach. Tapping on one of those notifications will bring them into Security Recommendations to view the warning for the password.

Having a password be publicly breached puts all accounts using that password at risk. We'll show this notification for any account using a password that has been breached, even if the breach came from another service. Each of the warnings in Security Recommendations will include actions the user can take to fix the corresponding account.

One option users will have to fix their accounts is the "Change Password on Website" button. This will take the user to the web to the credential's Well-Known-Change-Password-URL, if the service has adopted that standard. This is great for motivated users, but navigating through a website to change your password is a hassle. Most users avoid changing passwords because doing so feels like so much work. Ideally, users should be able to visit Security Recommendations and quickly make progress on addressing their warnings.

New in iOS this year, it will be possible with just the tap of a button in the password manager for users to upgrade at-risk password-based accounts to an automatically-generated strong password... or even to use Sign in with Apple. These upgrades are powered by the new account authentication modification extension. These extensions change user perception on fixing accounts. They provide fast, easy account security upgrades.

The extension point offers two upgrade options: upgrading to Sign in with Apple, and upgrading to a strong password. If necessary, extensions allow the opportunity for additional user authentication before completing an upgrade. For example, you may want a user to enter an SMS two-factor authentication code before they switch their account to use Sign in with Apple.

With just one extension implementation, these upgrades can be accessed from three places: in the password manager, when looking at a password detail view... directly off of a high-priority recommendation item in Security Recommendations, or, third, via automatic system prompts when users sign in to your apps. The system will prompt users with security recommendations when they sign in to your app with a weak or breached password.

Once you've implemented an extension, you can also add these upgrade flows within your app using new AuthenticationServices framework API. This is an awesome way that you can offer system-integrated account security upgrades with the user experience you want your users to have in your app. We'll walk through how to do this towards the end.

Now that I've introduced the new account authentication modification extension point, let's walk through how to implement an extension. Throughout the presentation, I'll be adding upgrades to my test app, Shiny. We're going to walk through four different aspects of implementing the extension. Depending on which upgrades you choose to support, some of these steps may not apply to you. Regardless, they'll all help you better understand what's involved in this process. We'll start by discussing how to associate your app with your domain.

For your app to be able to upgrade users' accounts saved in the password manager, you'll need to securely associate your app and domain. If you haven't already done this for your app to support Password AutoFill, it's really easy. You'll serve a JSON file on your domain's server that identifies that the domain is affiliated with your app. For the purpose of tying your app and domain together for authentication, use the "webcredentials" service. Then you'll add a matching associated domain entitlement to your app. You can do that in Xcode by adding the associated domain capability and specifying the domain for your app.

Once you've associated your app with the webcredentials service, your app will be eligible to offer an upgrade for a password saved in the user's iCloud Keychain. For more information about associating apps and domains, check out the WWDC session, "Introducing Password AutoFill for Apps." And that was associating your app with your domain.

Now, it's time to implement a strong password upgrade. A strong password upgrade helps users by giving them a strong, unique password for your service. The very first step will be to create a new target in your project using the new account authentication modification extension template in Xcode. Next, you'll need to declare support for strong password upgrades in your extension's Info.plist.

Setting the ASAccountAuthenticationModification- SupportsStrongPasswordChange key to "yes" will tell the system to offer the strong password extension upgrade option for credentials for your app. The template will declare support for both upgrades by default. If you don't want to support this upgrade, you can just set the key to "no." You'll implement your extension in a special subclass, which will be the brain of the operation and contains the business logic for the upgrade, including communicating with your back-end server to commit account changes. It's exposed out of the AuthenticationServices framework, and you'll notice that it's a ViewController.

The reason it's a ViewController is because you'll have the flexibility to show security step-up UI to have the user fully authorize before performing an upgrade, if necessary. We'll talk about that later, and for right now, we'll cover upgrade flows without security step-up UI. When users tap an extension upgrade button within the password manager, or just after signing into your app, the system will launch your extension and start an upgrade request with a system-generated strong password and an existing credential.

The system will call changePasswordWithoutUserInteraction on the ViewController to begin the request, passing in a serviceIdentifier which provides the domain or URL for the passed-in credential. The serviceIdentifier is useful if your extension offers upgrades for several different services. You'll also be passed a new, unique, strong password generated by the system, and userInfo, which we will revisit when we talk about in-app upgrades. This argument will always be nil for system-initiated upgrades. Upon receiving this initial request, your extension needs to authorize the upgrade before proceeding, communicating with your back-end server to do so. The result of the authorization will decide what your ViewController should do next.

Your extension should check with your back-end server to see if it is authorized to perform the upgrade for the passed-in credential. You can also leverage any existing login cookies or tokens stored in a data container shared between your app and extension. If the upgrade is authorized, you can continue with the upgrade. If not, you'll need to cancel the upgrade. When your extension is informed that the authorization failed, it should cancel the request.

In your extension implementation, you should do this by canceling the request with the failed error code. If you'd like to provide a failure message to be shown to the user, you can specify one in the userInfo using the ASExtensionLocalized- FailureReasonErrorKey. If not, the system will provide a default error message and encourage the user to try again later. If upgrade authorization succeeds, you can commit the change on your end and complete the request.

In this successful case, your extension should commit the change on your back-end server. If the change commits successfully, you can complete the upgrade by calling completeChangePasswordRequest using an ASPasswordCredential with the username and updated password. Note that you can change the new password passed in from the system if you need to. If you end up doing so, you should be sure to pass the correct password to the completion method. That's the password that will be saved to Keychain.

This is an example password that iCloud Keychain could generate. It's a strong password designed to be easily typeable for those times that AutoFill can't help the user with using the password. It's also designed with a length and character set to be compatible with most services. That said, if the iCloud Keychain-generated passwords aren't compatible with your service, you can specify your own password rules to ensure iCloud Keychain generates a compatible password. You can specify password requirements for your app with a technology called Password Rules.

At the Password Rules website, you'll find a validation tool that you can use to make your passwordrules string. You can then add it to your extension's Info.plist using the ASAccountAuthenticationModification- PasswordGenerationRequirements key. Once again, you should only need to do this if you find the default passwords generated by the system are not compatible with your password rules.

And that's how you support strong password upgrades. Next, let's look at supporting upgrades to Sign in with Apple. Before adding Sign in with Apple upgrades, you'll need to support Sign in with Apple. Check out these talks for more information on adding Sign in with Apple support to your apps.

Just as we saw with strong password upgrades, you'll need to declare that your extension supports Sign in with Apple upgrades in your extension's Info.plist. You'll do this by setting the ASAccountAuthenticationModification- SupportsUpgradeToSignInWithApple key to "yes." By default, the template will declare support for both upgrades. If you don't want to support this upgrade, you can just set it to "no." Sign in with Apple upgrades start just like strong password upgrades. The system will launch your extension and make the upgrade request with an existing credential.

The system will call convertAccountToSignInWithApple- WithoutUserInteraction on the ViewController to begin the request... passing in a serviceIdentifier and an existing password credential. And finally, userInfo, which we'll ignore until we talk about in-app upgrades. UserInfo will always be nil for system-initiated upgrades. Once again, your extension will need to authorize the upgrade.

Your extension should check with your back-end server to see if it is authorized to perform the upgrade for the passed-in credential. You can also leverage any existing login cookies or tokens stored in a data container shared between your app and extension. If the upgrade is authorized, you can continue with the upgrade. If not, you'll need to cancel the upgrade. When your extension is informed that the authorization failed, it should cancel the request.

In your extension implementation, you should do this by canceling the request with the failure error code. You can use the ASExtension- LocalizedFailureReasonErrorKey to communicate the reason for the failure to the user, if you'd like. When upgrade authorization succeeds, your extension should request a Sign in with Apple credential for the upgrade.

In code, your extension will request the credential from the system by calling getSignInWithAppleUpgrade- Authorization on the extension context. This method takes state and nonce arguments that you can use to securely verify the Apple ID credential for the upgrade. To learn more about this, you should check out the Sign in with Apple talks referenced earlier.

It's possible that when you call this method, the system won't be able to return a credential and your extension will need to fail the request. The system may fail to return a credential here for various reasons, such as the user tapping the cancel button on the system Sign in with Apple sheet, or if there's a bad network connection. In this case, your extension will cancel the request with the failure error code. If the system returns a Sign in with Apple credential successfully, you should do the necessary bookkeeping to process the upgrade on your end, and then successfully complete the request.

In code, once your extension has successfully committed the upgrade on your back-end server, it can complete the request by simply calling completeUpgradeToSignInWithApple on the extensionContext. One of the promises of Sign in with Apple is having one fewer password to manage and keep track of. Once the upgrade is completed, the system will delete the Keychain password credential used for the upgrade.

These flows cover the ideal scenarios for upgrades, with minimal user interaction. However, in some cases, your extension may require some additional user authentication to complete an upgrade. Your extension will have the capability to show security step-up UI in upgrade flows. As an example, you may want the user to enter a two-factor authentication code to complete an upgrade. Let's pick back up on the flow when your extension is verifying the credential passed in for the upgrade.

When your extension is checking with your back-end server to authorize the upgrade, we saw that if the upgrade is authorized, you can continue with the upgrade, or if not, you'll need to cancel the upgrade. But now, we'll consider a third possibility in which further authorization is required to complete the upgrade. When further authorization is required, your extension can cancel the initial request and specify that it needs to show security step-up UI.

Your extension can do this by canceling the initial request with the userInteractionRequired error code. In response, the system will create a new request configured to allow user interaction. The system will call prepareInterfaceToChangePassword on your ViewController subclass for strong password upgrades. For Sign in with Apple upgrades, the system will call prepareInterface- ToConvertAccountToSignInWithApple. In each of these methods, your extension should quickly do any work necessary to prepare the interface to be presented. Once this method finishes, the system will present your interface.

Your interface will be presented with a system-provided navigation bar with the name of the containing app for the extension as the title, and a cancel button. Once your interface is presented, there are three possible scenarios. If the additional user authentication fails or something else goes wrong, you can fail the request by canceling with the failure error code. The second scenario is that all goes well, and you can continue with the upgrade. For a strong password upgrade, the next step will be to commit the password change.

For a Sign in with Apple upgrade, your extension's next step will be to request the Sign in with Apple credential. The system will take this as a sign that the work in your security step-up UI is complete, and will dismiss it to show the system Sign in with Apple sheet. From here, the upgrade will continue the same exact way we saw earlier.

The third possibility, regardless of the upgrade type, is that the user taps the system-provided cancel button. In this case, your extension will need to cancel the request. The system will call cancelRequest on your ViewController subclass. The superclass implementation of this method simply cancels the request with the userCanceled error code.

If you want the ability to clean up state before the request is canceled, you should override this method, and be sure to still cancel the request at the end. We've completed the core implementation for the extension and the hard work is done. Now, if you want to use the upgrades from within your app, all you have to do is invoke the extension. Let's talk about in-app upgrades. In-app upgrades begin when your app creates and performs an upgrade request. Performing the request will launch your extension.

The request will have a username and will not have a password. There's no password in this flow because your app should not be able to provide plaintext passwords, and because, unlike the system, you won't have a handle to a Keychain credential to perform the upgrade with. However, you may pass any information you'd like to your extension for the upgrade with the userInfo property of the request object. We ignored this earlier because it's always nil for system-initiated upgrades.

Your extension can use this information to authorize the upgrade. The upgrade authorization process works as outlined before, where your extension will need to talk to your back-end server to ensure the account is authorized to perform the upgrade, with the same three possible outcomes of successful authorization, failed authorization, or finding that further authorization is required. Ideally, you shouldn't need any further authorization in this flow as the user is already logged into the app.

Let's add in-app upgrades to the account settings section of the Shiny app. Let's start with in-app strong password upgrades. The upgrade will be added here in the handler for the changeToStrongPassword button in the account settings section. The first step is to specify the serviceIdentifier for the credential to be upgraded by creating an ASCredential- ServiceIdentifier for the Shiny app. The next step is to get the username for the upgrade.

Remember that for in-app upgrades, your extension will not receive a password. You can authorize the upgrade by passing authorization information in on the request's userInfo. In this example, I'm passing in the auth token for the current user logged into the Shiny app for the Shiny extension to use to authorize the upgrade. These three pieces of information are used to create a strong password upgrade request. Next, we need to create an ASAccount- AuthenticationModificationController to perform the request.

In order to be informed of the results of the upgrade, the ViewController needs to be set as the upgrade controller's delegate. Lastly, a presentationContextProvider must always be provided to tell the system the window to show UI in. Once this is all done, the request can be performed. Now, let's quickly see how to add in-app Sign in with Apple upgrades. They're very, very similar to the strong password upgrades we just saw. The only difference for the in-app Sign in with Apple upgrades will be to create and use a Sign in with Apple request object.

For in-app upgrades, you are in control for communicating upgrade results to the user with your user interface. The ASAccountAuthentication- ModificationController delegate protocol has two methods to handle upgrade results. There's a method that will be called for successful upgrades where you should inform the user that the upgrade succeeded.

After a successful upgrade, the system will look for a Keychain credential for your service with the username used in the upgrade. If a Keychain credential is found, it will either be updated or removed, depending on the type of upgrade. There's also a method to indicate an upgrade has failed where you should inform the user that it failed and provide the reason why, if possible. Here's a successful Sign in with Apple upgrade in the Shiny app.

People love Sign in with Apple. Providing this upgrade flow in your app allows your users to convert existing accounts to Sign in with Apple without having to create a new account. We just looked at adding upgrades in an account settings view. Another great opportunity to offer upgrades is when a user transitions into using your app after using your App Clip. Let's quickly review some best practices for adopting the account authentication modification extension point.

Keep upgrades as quick and as effortless as possible. Only request to show your extension's UI when absolutely necessary. Your extension can authorize upgrades by communicating with your back-end server, but you can also leverage any existing login cookies or tokens that you have saved in a data container shared between your app and extension. Once an account upgrades to use Sign in with Apple, do not allow the account to log in using a password anymore. If you override the system cancel button method, cancel the request as soon as possible.

Consider offering account security upgrade options when a user signs into your service with an App Clip and is later upgraded to the full app. Those are some best practices to keep in mind when implementing your extension. Let's wrap up by reviewing the experience you can provide for your users by adopting the account authentication modification extension point.

The new Security Recommendations feature warns users about at-risk password-based accounts. It educates users about why certain passwords have been flagged and motivates them to take action. Users will even get notifications about breached passwords that will take them to the password manager to secure their accounts. If you choose to adopt the new account authentication modification extension, they'll have access to upgrades to secure their accounts with the tap of a button and use Sign in with Apple, or change to a new, strong password. When the system alerts your users about a security warning for an account with your service, they'll be able to address it instantly and seamlessly. Lastly, we saw that once you've implemented an extension, you can easily add the upgrade flows within your application using new AuthenticationServices framework API.

This buys you system-integrated account security upgrades with the experience you want your users to have in your app. I hope you'll choose to adopt the account authentication modification extension to provide your users with a first-class experience when they need to secure their accounts. Thank you so much for watching. I hope you enjoy WWDC 2020.