Shared web credentials is a programming interface that enables native iOS apps to share credentials with their website counterparts. For example, a user may log in to a website in Safari, entering a user name and password, and save those credentials using the iCloud Keychain. Later, the user may run a native app from the same developer, and instead of the app requiring the user to reenter a user name and password, shared web credentials gives it access to the credentials that were entered earlier in Safari. The user can also create new accounts, update passwords, or delete her account from within the app. These changes are then saved and used by Safari.
The shared web credentials API defines Core Foundation–based functions for storing and requesting shared password-based credentials. There are four steps to sharing credentials:
comentitlement to your app. This entitlement must include all the domains with which you want to share credentials.
.apple .developer .associated-domains
apple-app-site-associationfile to your website. This file must include application identifiers for all the apps with which the site wants to share credentials.
When the app is installed, the system downloads and verifies the site association file for each of its associated domains. If the verification is successful, the app is associated with the domain.
Adding the Associated Domains Entitlement
To enable shared credentials in your app, add the
com key to your app’s entitlements. You can add this entitlement using the target’s capabilities pane (see Figure 1).
Include a list of all the domains with which your app wants to share credentials. Keep the number of domains to about 20 to 30. To match all subdomains of an associated domain, you can specify a wildcard by prefixing
*. before the beginning of a specific domain (the period is required).
Each domain you specify uses the following format:
<service>:<fully qualified domain>[:
For shared web credentials, always use the
Adding the Site Association File
apple-app-site-association file on a website that matches one of the domains in your app’s associated domains entitlement (you can also place it in the
.well-known subdirectory). The file’s URL should match the following format:
https://<fully qualified domain>/apple-app-site-association
The file’s JSON content must contain a
webcredentials dictionary with an
apps array. The
apps array lists the application identifiers for all the apps that can access the shared credentials for this site. For an example, see Listing 1.
apple-app-site-association file must meet the following requirements:
The file must be hosted on an
https://site with a valid certificate (for example, Safari must not issue a certificate warning when viewing the site).
The file must not use any redirects.
In iOS 9.3.1 and later, the file must be no larger than 128 KB (uncompressed), regardless of whether it is signed.
If your app runs in iOS 9 and later and you use HTTPS to serve the file, you can create a plain text file that uses the
application/jsonMIME type and you don’t need to sign it.
If your app runs in iOS 8, the file must have the MIME type
application/pkcs7-mimeand it must be CMS signed by a valid TLS certificate.
You can sign the JSON file using Terminal commands such as those shown in Listing 2. The
echo command puts the server-side web credentials from Listing 2 into a file named
json, removing most of the white space from the text to minimize the required bandwidth. The line beginning with the
cat command reads the file and pipes the output to the
openssl command, which signs the file using the certificate and key for an identity valid for
The output of the
openssl command is the signed JSON file that you put on your website at the
apple-app-site-association URL, in this example
The certificate used to sign the JSON file must meet the following requirements:
The certificate must be a valid TLS certificate for the domain name. For example, the certificate must have a Common Name or Subject Alternative Name that matches the domain (example.com in the example).
The certificate must not be expired.
The server’s certificate chain must lead to a root certificate issued by a certificate authority (CA) trusted by iOS.
For the complete list of certificate authorities trusted by iOS, see the Apple support article Lists of available trusted root certificates in iOS.
Validating the Site Association File
When the app is installed, iOS attempts to associate it with all the domains listed in its associated domains entitlement. iOS performs the following steps:
Takes each domain from the associated domains element.
“/apple-app-site-association”to the end of the domain, and downloads the contents at the resulting URL.
Verifies the JSON file’s signature.
Makes sure the JSON file includes the app’s application identifier.
If all of these steps succeed, the app is associated with the domain and you can use
Sec to access and modify the shared web credentials. After an app is successfully associated with a domain, it remains associated until the app is deleted from the device.
A number of issues might cause the validation to fail.
The JSON signature is invalid. The association is denied.
JSON file is invalid or does not contain the application identifier. The association is denied.
The server returns a 300-499 code. This includes redirects. The association is denied.
The server returns a 500-599 code. The system assumes that the file is temporarily unavailable and tries again. By default, the system tries every 3 hours for up to eight tries. It also tries whenever the app calls the
Add Shared Web Credential(_: _: _: _:)
Request Shared Web Credential(_: _: _:)
There are a wide range of common situations where you may want to use shared web credentials. This section covers four: logging in to a remote server, creating a user account in the app, changing a user’s password, and deleting a user’s account.
Logging In to a Remote Server
Typically, when an app needs to log in to a remote service, you start by checking for the user’s credentials in the iOS keychain. If you have current credentials for the user, you can log them in directly. If not, prompt the users for their user name and password, and then try to log them in. You will also want to save their credentials after the login is successful. This workflow is shown in Figure 2.
When using shared web credentials, you add two steps to this procedure. As before, you start by checking if the user’s credentials are stored in the keychain. If you cannot find the user’s credentials, you check for shared web credentials. If you still cannot find any credentials, or if the user declines to use the shared credentials, you must prompt the user for her name and password. Try to log the user in, and if the login is successful, save the credentials to both the keychain and the shared web credentials. This ensures that the user has access to the credentials in Safari as well as within your app. This workflow is shown in Figure 3.
Do not use the shared web credentials as your primary storage for secure user credentials. Instead, save the user’s credentials in the keychain, and only use the shared web credentials when you can’t find the login credentials in the keychain.
To read the user’s credentials from the shared web credentials, use the
Sec function as shown in Listing 3.
Creating a User Account in the App
If the user can create new accounts in your app, you should save the user name and password to the shared web credentials. In this way, the user can easily access the account from Safari, as well as from within your app. You can save the user’s name and password to the shared web credentials using the
Sec function as shown.
If there are no existing credentials for this user name and domain, this method completes without prompting the user for permission.
Changing a User’s Password
If the user changes her password in the app, you must update both the credentials stored in the keychain and in the shared web credentials. You can change a password using the
Sec function. This is exactly the same procedure used when creating a new user account (see Listing 4). However, if credentials already exist for the given user name and domain, this method prompts the user for permission before making the change. The user can cancel this change.
Deleting a User’s Account
If the user deletes her account, you should remove the credentials from both the keychain and the shared web credentials. You can remove the credentials for a given domain and user name by calling the
Sec function and passing
NULL for the password.
The system prompts the user for permission before deleting their user name and password from the shared web credentials. Users can cancel this change.