hwchen / keyring-rs

Cross-platform library and utility to manage passwords
Apache License 2.0
450 stars 49 forks source link

Allow using biometric auth (e.g. Touch ID) to get passwords #149

Closed gibfahn closed 7 months ago

gibfahn commented 7 months ago

it would be great to be able to allow enabling user presence (e.g. Face ID on an iPhone, Touch ID on a Mac) when storing a password in the keychain.

macOS docs: Accessing keychain items with Face ID or Touch ID say to create the keychain item with SecAccessControlCreateFlags to use kSecAccessControlUserPresence (or similar constraints)

brotskydotcom commented 7 months ago

What an interesting idea! To be sure I understand where you're going, is the idea here to increase security, so that an app which wrote a keychain item would not be able to later retrieve it without the user being present? Typically the user's presence is required to unlock the device, rather than again later when the item is being retrieved.

This kind of enhancement would have to be based on an enhancement in the underlying security-framework crate which this crate relies on for macOS and iOS. Currently that crate doesn't allow callers to pass in additional flags.

The other concern I would have about this enhancement is that it's very macOS/iOS-specific (at least to my knowledge). While other platforms support user presence for unlocking the device, they don't support it on an item-by-item basis. So while I can imagine the macOS and iOS keystore implementations in this crate being enhanced to support this feature, I think clients would probably have to use keystore-specific APIs to set these options rather than the generic keyring interface itself being enhanced to allow setting them.

Do you have a usage context in mind? I find those very useful when considering enhancements.

gibfahn commented 7 months ago

To be sure I understand where you're going, is the idea here to increase security, so that an app which wrote a keychain item would not be able to later retrieve it without the user being present?

For me it would be to more easily allow a different app to access the keychain without me having to type a password, for example when testing an unsigned app version locally, being able to use Touch ID / Watch unlock instead of this would be helpful:

image

I might also not want to "always allow" my app to access the credential, and always require auth, in which case Touch ID is much more convenient (similar to using Touch ID for sudo).

Currently that crate doesn't allow callers to pass in additional flags.

I took a look at that and it seems there was an attempt to allow this in https://github.com/kornelski/rust-security-framework/pull/178 , but (see https://github.com/kornelski/rust-security-framework/pull/178#issuecomment-1824344482) I couldn't see how to actually use it. Might well be me using it wrong though.

Also side-note but given https://github.com/kornelski/rust-security-framework/issues/188 I'm not sure how responsive that crate is to feature requests / PRs.

The other concern I would have about this enhancement is that it's very macOS/iOS-specific (at least to my knowledge). While other platforms support user presence for unlocking the device, they don't support it on an item-by-item basis.

Interesting, so there's no way to say in Windows/Linux "this item can/cannot be unlocked by biometrics as well as by typing in a password"?

brotskydotcom commented 7 months ago

Thanks for the use case; that clarifies things.

The dialog you mention is actually Mac-only and appears when the "scope" of an existing item created by one app doesn't allow access by an app with a different developer signature. There's no way to use biometrics to do that unlock, and the security attributes you're talking about don't affect it. That's actually part of Apple's "weaker Mac-only" sandboxing strategy, which is why it isn't on iOS where all apps are sandboxed (and why you always get it when running an unsigned app). It's never shown to the app that authored the item (unless its build has changed and it's not signed).

The security attributes you are talking about are meant to enhance security on items so that not even the author app of the item can get access to the item unless the user is present. This is a level of security above the standard security of requiring the keychain itself to be unlocked (which can always be done with presence).

To answer your other question, yes: this kind of security is very much macOS/iOS-only; it's part of Apple's walled-garden strategy and far beyond what's offered in other OSes whose platforms are intentionally more open.

Let me know if you have another use case.

gibfahn commented 7 months ago

There's no way to use biometrics to do that unlock, and the security attributes you're talking about don't affect it.

Ahh my mistake. I guess that would be a feature request for Apple then (although I understand it might be intentionally not supported).

This is a level of security above the standard security of requiring the keychain itself to be unlocked (which can always be done with presence).

Fair enough, I guess this is my second use-case:

I might also not want to "always allow" my app to access the credential, and always require auth, in which case Touch ID is much more convenient (similar to using Touch ID for sudo).

This is definitely also something that would be rather useful, for when you want to store really sensitive data. One concern I'd have is that users might unwittingly "Always allow" the security CLI access to the data, which would mean any shell script could then read it.

Looking at Restricting keychain item accessibility, I think a toggle to allow requesting User Presence would be the most useful bit.

gibfahn commented 7 months ago

it's part of Apple's walled-garden strategy and far beyond what's offered in other OSes whose platforms are intentionally more open.

Fair enough, although having an opt-in way to say "this data really shouldn't be read without someone actually confirming" seems rather useful to me even as an end-user :grin:,

brotskydotcom commented 7 months ago

OK, thanks for getting back on this. I think it's potentially a useful enhancement, definitely, but not something I'm planning to add (for the reasons outlined above about cross-platform applicability).