Shared web credentials: A simpler way to log in

Pinterest Engineering
Pinterest Engineering Blog
4 min readApr 17, 2015

Garrett Moon | Pinterest engineer, iOS Core Experience

Our top priority is to create a great user experience in everything we build, and across platforms. As part of that, each day we work to reduce the effort it takes to use Pinterest. So when Apple announced support for shared web credentials, we were excited to make it easier for Pinners to log in.

Shared web credentials allows an iOS app to read and write passwords to the same store that Safari uses on iOS and Mac. For example, if a Pinner signed up for Pinterest on their Mac, they could download our iPhone app and immediately login without needing to remember or tap in their credentials. Magic!

How To

Before you can start using the APIs, there are two requirements to get iOS to trust your app with shared web credentials.

  • Add your domain to “Associated Domains” in the Capabilities section of your Xcode project:
  • Sign a JSON file and host it at https://<yourdomain.com>/apple-app-site-association. Note the https.
  • The file should contain a dictionary that lists your approved app identifier and is signed to ensure it has not been tampered with. The listing below shows an example JSON file formatted for reading:
  • Listing 1–1 Server-side web credentials:
  • { "webcredentials": { "apps": [ "YWBN8XTPBJ.com.example.myApp"] } }
  • We used our pinterest.com certificate and key to sign the JSON file (more on the requirements of the certificate here). To sign the certificate, use the commands below:
  • Listing 1–2 Signing the credentials file:
  • echo '{"webcredentials":{"apps":["YWBN8XTPBJ.com.example.myApp"]}}' > json.txt cat json.txt | openssl smime -sign -inkey pinterest.com.key -signer pinterest.com.pem -certfile intermediate.pem -noattr -nodetach -outform DER > apple-app-site-association
  • As a final step, host the produced file on your website under https://example.com/apple-app-site-association.
  • This process should be relatively straightforward, however there are a couple of gotchas.
  • First, be sure you have credentials in iCloud Keychain that match your domain. Without them the API methods will fail with an error (-25300, No matching items found). If the user clicks “Not Now” there will be no error, but zero credentials returned.
  • Also, if you don’t get everything set up correctly the first time, you’ll want to delete the app between tests. Apple verifies your domain app link when your app is installed, so relaunching the app after fixing the issue won’t result in a new check.
  • Now, to request the user’s credentials in the app, just make a simple function call:
  • SecRequestSharedWebCredential(NULL, NULL, ^(CFArrayRef credentials, CFErrorRef error) { if (error) { //handle error } else { if ([(__bridge NSArray *)credentials count] > 0) { NSDictionary *dictionary = [(__bridge NSArray *)credentials objectAtIndex:0]; NSString *accountName = dictionary[(__bridge id)(kSecAttrAccount)]; NSString *password = dictionary[(__bridge id)(kSecSharedPassword)]; } else { // No accounts } } });

Design

Imagine you’ve just signed up for Pinterest on the web and then download our iOS app. Upon loading the app, you’re offered to immediately log in with your credentials, which is the ideal experience.

However, you don’t want to annoy users who have no interest in using the feature. So if the user clicks “Not Now,” offer to stop showing the dialog every time they’re on the login screen.

To create the most seamless experience, integrate shared web credentials in other parts of your app.

  • When the user logs in successfully, call SecAddSharedWebCredential to update the user’s credentials so that they can use them when they visit your website later.
  • If you have a password change feature, be sure to also update credentials in the keychain as above.
  • Finally, make sure to have a button to login with the credentials on your login screen.

Results

After introducing support for shared web credentials we saw modest increase in engagement of our Pinners, which made the small effort well worth the time. Encouraging people to use features like iCloud Keychain will help users create more secure passwords without having to remember them, which is a win for everyone involved.

Garrett Moon is an iOS engineer on the Mobile team.

Acknowledgements: Thanks to Amine Kamel, senior security engineer, for providing the how-to on signing JSON files properly.

For Pinterest engineering news and updates, follow our engineering Pinterest, Facebook and Twitter. Interested in joining the team? Check out our Careers site.

--

--