Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I save passwords in shared web credentials AND (local) keychain

I am in the process to design a login for a new app that will be associated with a domain, i.e. be the counterpart to an SPA. Obviously I want to use

  • iOS 11 Password Autofill, and
  • Shared Web Credentials

I have read the documentation on autofill as well as watched the WWDC video about it. Also, I checked the article on Shared Web credentials, which I think is older than the new, reworked autofill. Said article recommends:

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.

This strikes me a little odd, because it - Means I have to cover more possible inconsistencies, i.e. synchronize the keychain somehow wit the shared web credentials (what if I have credentials in the keychain as well as the shared web credentials, but they're different?) - Potentially leaves "garbage" behind in the keychain if my user user uninstalls my app (naturally I hope they won't ever do this, but let's be realistic, some will)

Especially the last point had always bothered me in the past (before shared web credentials and autofill were a thing, or when my app doesn't have an associated domain). Unlike on macOS, the iOS Accounts & Passwords feature (in the Settings app) doesn't list ALL passwords, but only the ones used by Safari (i.e. the shared web credentials), correct? Keychain Access on macOS instead offers a means to view and manage all credentials, even those that aren't synchronized over iCloud.

I understand why the same is not offered on iOS, but it also means that for those passwords that my app saves (locally) to "its" keychain "part" can only be managed if I offer a UI for this in my app. And if the user uninstalls the app before using this, the item will stay in the keychain, at least it was that way when I tried it a couple of years ago.

My main question now is, wouldn't it be easier to disregard the article's advice and only rely on the shared web credentials for password storage? That's the part they can edit in Settings (if ever need be) and also it will reflect any password changes done on the website. I would design my app like this then:

  • First launch: App starts on the Login screen and offers the username/password via Autofill
  • User logs in: App saves a simple flag in the shared user defaults indicating the user is logged in.
  • App gets relaunched, e.g. after a device reboot: The app skips the login screen due to the flag and gets the password and user name from the shared web credentials (assuming the user previously granted it permission, of course)
  • User explicitly logs out: The app deletes the flag, basically setting everything back to first launch
  • User deletes the username and password from the shared web credentials (e.g. in the Settings app or with Keychain Access on macOS): The app falls back to the login screen as soon as it detects this (e.g. when attempting a remote request, or after relaunch), regardless of the flag. I think this matches the user intention best (if you delete a password you don't want some apps to hold onto it until you log them out)

This setup would avoid any issues with different items in the keychain and shared web storage and it would immediately propagate updates done in the webpage to the app as well (which is what I'd intent for my app anyways). Is there anything that would keep this app flow from working?

(Note: I asked the same question on the apple developer forums, so if you see that as well don't be confused. I will update any potential answers from there to here and vice versa.)


Edit to address @Aaron's answer:

Thank you so much for the info. Your answer helped me realize I misunderstood something about shared web credentials: I assumed that for an app with associated domain, you can access the credentials without user interaction (after perhaps an initial authorization). Like you can set the checkbox on macOS when an application requests credentials. I now realize this is wrong and on iOS you would always have to verify with the user, thanks.

For completeness sake, I still want to point out some of the other things you said:

  • You are right, we will eventually use token based authentication, so I will save that in the keychain (probably in addition to the password, see below). I just tried to keep the question simple enough at first.
  • Our app is like an email client where you update new incoming "mail". The mentioned "login flag" in something like the user defaults would thus just indicate whether the app should behave as if subscribed to an inbox or not. Like in Mail, you wouldn't expect to have to login even after relaunch.
  • For this reason I will probably eventually save the user's password in the (local) keychain along with a token. If the token expires, I can request a new one without user interaction, that's important in our general site and app design. Only if that request fails I would use the shared web credentials (updating my local copy of the creds in the process).
  • For what it's worth, the last point you mentioned is probably debatable. On macOS, for example (where you can edit the entire keychain, not just Safari passwords) de facto logs you out of an app. Mail, again, as an example. If the keychain item for an inbox is gone, Mail re-asks that the next time it is launched and tries to access the content (effectively a "kind of" login in a way).

Again, thank you a lot for answering, now I can close an open todo. :) Also thanks to @HamZa for giving out a bounty!

like image 866
Gero Avatar asked Jan 30 '18 08:01

Gero


People also ask

Is Apple Keychain A good password manager?

Management. Apple Keychain isn't the best when it comes to password management. Although Safari on Mac offers a well-organized website password viewer and manager, the all-encompassing Keychain Access app (which stores items such as Wi-Fi passwords and secure notes) can be confusing unless you learn how it works.

What are shared web credentials?

With shared web credentials, the app can access the credentials stored for the website instead of requiring the user to reenter a username and password. Users can also create new accounts, update passwords, or delete their accounts from within the app. These changes are then saved and used by Safari.

What is the best way to securely share the secret credentials among a family of apps in the device?

The ideal setup for sharing secure information is to use end-to-end encryption. This means that as soon as the first user inputs the information, like a password, it is automatically encrypted.

Is Apple Keychain secure?

It's safe and secure, but limited in some areas. All of my devices have the Apple logo on them, but if you have a Windows computer or Android device in your life, it won't work there, and for a password manager to be effective, it needs to work on every device you use.


1 Answers

Considering this advice:

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.

The main issue here is that the shared web credentials process is a little clunky — it requires user interaction and takes time to resolve the credentials. So if the user has already authenticated with your app you want to avoid showing them the login page at all. You can do this by storing credentials in your app's keychain where you can access them immediately without a network connection or user permission.

This doesn't mean you need to store the user's password in the keychain. Typically you would store something like an OAuth access token in the keychain. The presence of this token means the user is authenticated - and if an API endpoint rejects your token then you can take them back to the login page.

This suggestion:

User logs in: App saves a simple flag in the shared user defaults indicating the user is logged in.

is possibly insecure depending on what you're hiding behind the login page, but typically any content belonging to the user should require a valid token to access, not just a bool in the user defaults.


I think this matches the user intention best (if you delete a password you don't want some apps to hold onto it until you log them out)

I disagree with this; I would not expect an iOS app to log out because I deleted a password from my Safari keychain.

like image 170
Aaron Brager Avatar answered Nov 22 '22 23:11

Aaron Brager