Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple Password Popups on macOS for Multiple Credentials When the Python Binary Updates #619

Open
ChristopherHammond13 opened this issue Jan 18, 2023 · 2 comments

Comments

@ChristopherHammond13
Copy link

ChristopherHammond13 commented Jan 18, 2023

Describe the bug
Firstly, I believe this may be related to #519?

When the Python binary updates (or a new virtual environment is created), I will receive a popup asking for my login/keychain password as usual. However, in my application (https://github.com/crowdstrike/Falcon-Toolkit) it is possible to configure many 'profiles', each of which will hold a separate secret (in the case of that application, it's an API Client Secret). Strangely, I will get the popup repeatedly, one per profile, so eight configurations with eight separate Client ID / Client Secret pairs will result in me needing to type my password eight times even if I click "Allow All". Given that I work at a security company, and my password is therefore pretty complex, typing my password n times every time I update Python or the virtual environment's Python binary is far from convenient :) I expect this to affect our MSSP and internal users a fair bit, too, if they use this tool across multiple client environments with separate sets of credentials.

I do not known if this is a bug in the way I am using keyring (I am always open to it being my fault!), keyring itself, or the macOS implementation of the binary validity checks. An example of the code I have that retrieves this value is here, in case this helps: https://github.com/CrowdStrike/Falcon-Toolkit/blob/main/falcon_toolkit/common/auth_backends/public_single_cid.py#L44. The code will run once per profile. I am using the Client ID as the username and the Client Secret as the password, with the service name defined as a constant in the code.

To Reproduce

  1. Create an application that stores multiple named secrets to the macOS secrets store
  2. Upgrade Python so that the binary changes
  3. Attempt to retrieve / load all those secrets in one go
  4. Observe one popup requesting the password for each loaded secret

I expect I can re-architect some of this code to defer the password request to later in the execution, but I still feel like there is a bug here as loading multiple credentials early in the execution is (in my opinion) quite a reasonable thing to do.

Expected behavior
I should be asked for my password once, and the "Allow All" button should stop future popups until I change the Python binary again.

Environment

  • OS: macOS Ventura
  • Virtual environments provided by pipx or Poetry (both are affected)
$ pip list | grep keyring
...

keyring 23.13.1

$ keyring --list-backends
...
keyring.backends.fail.Keyring (priority: 0)
keyring.backends.macOS.Keyring (priority: 5)
keyring.backends.chainer.ChainerBackend (priority: -1)

Additional context
Again, I am very open to this being a code issue on my part if I am doing something stupid here and/or invoking keyring in the wrong way. Apologies in advance if this is the case, and thank you for any tips you can provide!

@jaraco
Copy link
Owner

jaraco commented Feb 10, 2023

I use macOS and keyring quite a bit and I have a very similar experience. Every time the binary changes, it has to be authorized with each item in the keychain. In my experience, "Allow" means allow for this instance but prompt me for the keychain password again next time and "Allow All" means allow for this executable and item. I'm not aware of a way to authorize an executable for all items or to allow all items to work with a future executable.

I don't think you're doing anything wrong, but rather this interface is simply the security landscape provided by macOS. The keyring library has very little control over the user experience that macOS provides.

It's conceivable that Apple provides some more advanced API features that would enable a more streamlined experience, but my guess is not - that they've designed this behavior for security and wouldn't want an application to be able to compromise those choices.

Feel free to take a look at keyring.backends.macOS.api to see the implementation that interfaces with macOS and explore Apple's options for customizing the behavior.

@ChristopherHammond13
Copy link
Author

Hey @jaraco, thank you so much for taking the time to look at this! Whilst I'm glad I haven't done anything explicitly wrong here, it sucks that Apple has chosen to make this user experience objectively awful :( Right now, Keyring / the macOS Keychain is by far the best way to implement secure secrets storage in Python from what I can see. I am considering lazy loading the secrets at configuration parse time and then truly loading them on tool execution. It's not super ideal, but it means users not having to type their passwords in once per profile on running the tool.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants