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

No keyring support for authentication #1520

Closed
AngellusMortis opened this issue Feb 16, 2024 · 12 comments
Closed

No keyring support for authentication #1520

AngellusMortis opened this issue Feb 16, 2024 · 12 comments
Assignees
Labels
compatibility Compatibility with a specification or another tool enhancement New feature or improvement to existing functionality

Comments

@AngellusMortis
Copy link

It appears uv does not have support for keyring like pip does.

https://pip.pypa.io/en/stable/topics/authentication/#keyring-support

@zanieb zanieb added enhancement New feature or improvement to existing functionality compatibility Compatibility with a specification or another tool labels Feb 16, 2024
@zanieb
Copy link
Member

zanieb commented Feb 16, 2024

This seems reasonable. We'll need to find a Rust equivalent to https://pypi.org/project/keyring/

Perhaps https://github.com/hwchen/keyring-rs

@AngellusMortis
Copy link
Author

AngellusMortis commented Feb 16, 2024

keyring is a cli app already. Probably want to add support for existing Python one first to maximize compatibility. Different auth methods need different plugins. AWS, Azure and Google Cloud each have their own plugins to use the more secure auth methods (no username/password).

Then you could migrate to a native only solution.

@chris-hartfield
Copy link

Agreed that calling the cli is probably easiest. The cli equivalent of what pip is calling in python is really simple: keyring get <url> <username_which_is_often_empty>

@judahrand
Copy link

judahrand commented Feb 21, 2024

Agreed that calling the cli is probably easiest. The cli equivalent of what pip is calling in python is really simple: keyring get <url> <username_which_is_often_empty>

pip does already actually directly call the CLI tool if keyring isn't installed in the Python environment but is available on PATH or --keyring-provider subprocess is passed - so this behaviour would be consistent.

https://pip.pypa.io/en/stable/topics/authentication/#using-keyring-as-a-command-line-application

@zanieb
Copy link
Member

zanieb commented Feb 21, 2024

Thanks for the details! Much appreciated.

@zanieb zanieb self-assigned this Feb 21, 2024
@judahrand
Copy link

judahrand commented Feb 22, 2024

This seems reasonable. We'll need to find a Rust equivalent to https://pypi.org/project/keyring/

Perhaps https://github.com/hwchen/keyring-rs

I'd also discourage this approach. There are many Python plugins to keyring for various cloud hosted private Pypi registries (eg. Google Artifact Registry, Azure DevOps, etc). I imagine these would be incompatible with keyring-rs and so you'd lose a lot of the benefit of the keyring integration unless all of these plugins were also reimplemented.

https://github.com/Microsoft/artifacts-keyring
https://github.com/GoogleCloudPlatform/artifact-registry-python-tools

zanieb added a commit that referenced this issue Mar 13, 2024
<!--
Thank you for contributing to uv! To help us out with reviewing, please
consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->

## Summary

<!-- What's the purpose of the change? What does it do, and why? -->

Adds basic keyring auth support for `uv` commands. Adds clone of `pip`'s
`--keyring-provider subprocess` argument (using CLI `keyring` tool).

See issue: #1520

## Test Plan

<!-- How was it tested? -->

Hard to write full-suite unit tests due to reliance on
`process::Command` for `keyring` cli

Manually tested end-to-end in a project with GCP artifact registry using
keyring password:
```bash
➜  uv pip uninstall watchdog
Uninstalled 1 package in 46ms
 - watchdog==4.0.0

➜  cargo run -- pip install --index-url https://<redacted>/python/simple/ --extra-index-url https://<redacted>/pypi-mirror/simple/ watchdog
    Finished dev [unoptimized + debuginfo] target(s) in 0.18s
     Running `target/debug/uv pip install --index-url 'https://<redacted>/python/simple/' --extra-index-url 'https://<redacted>/pypi-mirror/simple/' watchdog`
error: HTTP status client error (401 Unauthorized) for url (https://<redacted>/pypi-mirror/simple/watchdog/)

➜  cargo run -- pip install --keyring-provider subprocess --index-url https://<redacted>/python/simple/ --extra-index-url https://<redacted>/pypi-mirror/simple/ watchdog
    Finished dev [unoptimized + debuginfo] target(s) in 0.17s
     Running `target/debug/uv pip install --keyring-provider subprocess --index-url 'https://<redacted>/python/simple/' --extra-index-url 'https://<redacted>/pypi-mirror/simple/' watchdog`
Resolved 1 package in 2.34s
Installed 1 package in 27ms
 + watchdog==4.0.0
```

`requirements.txt`
```
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
#    .bin/generate-requirements
#
--index-url https://<redacted>/python/simple/
--extra-index-url https://<redacted>/pypi-mirror/simple/

...
```

```bash
➜  cargo run -- pip install --keyring-provider subprocess -r requirements.txt
    Finished dev [unoptimized + debuginfo] target(s) in 0.19s
     Running `target/debug/uv pip install --keyring-provider subprocess -r requirements.txt`
Resolved 205 packages in 23.52s
   Built <redacted>
   ...
Downloaded 47 packages in 19.32s
Installed 195 packages in 276ms
 + <redacted>
  ...
```

---------

Co-authored-by: Thomas Gilgenast <thomas@vant.ai>
Co-authored-by: Zanie Blue <contact@zanie.dev>
@BakerNet
Copy link
Contributor

BakerNet commented Mar 14, 2024

As of #2254 --keyring-provider subprocess is available. It has been tested on at least two Google artifact registry projects (using keyrings.google-artifactregistry-auth plugin) as working.

@zanieb zanieb closed this as completed Mar 14, 2024
@jonataseduardo
Copy link

Sorry for continuing on this topic, but I'm trying to create a uv project that uses an --extra-index-url with Google Cloud Artifact Registry. However, it returns an error indicating that my package can't be found. I am using uv 0.4.18

Here's what I've tried so far:

  gcloud auth application-default login --project ${PROJECT_ID}                      
  uv venv
  source .venv/bin/activate
  uv pip install keyring keyrings.google-artifactregistry-auth
  uv pip install --keyring-provider subprocess ${MY_PACKAGE} --extra-index-url https://${REGION}-python.pkg.dev/${PROJECT_ID}/${REPOSITORY_ID}/simple                            

Interestingly, when I use standard pip, I can install my private package without any issues. Here's the code that works:

  gcloud auth application-default login --project ${PROJECT_ID}                      
  python -m venv .venv
  source .venv/bin/activate
  pip install keyring keyrings.google-artifactregistry-auth
  pip install ${MY_PACKAGE} --extra-index-url https://${REGION}-python.pkg.dev/${PROJECT_ID}/${REPOSITORY_ID}/simple                            

Am I missing something? Any help would be appreciated!

@ffissore
Copy link

ffissore commented Oct 8, 2024

Try --extra-index-url=https://oauth2accesstoken@${REGION}...

@jonataseduardo
Copy link

Try --extra-index-url=https://oauth2accesstoken@${REGION}...

Thanks, it worked when I used this command:

uv pip install ${MY_PACKAGE} --extra-index-url https://oauth2accesstoken:$(gcloud auth print-access-token)@${REGION}-python.pkg.dev/${PROJECT_ID}/${REPOSITORY_ID}/simple

Does this not defeat the purpose of using a keyring?

@zanieb
Copy link
Member

zanieb commented Oct 8, 2024

@jonataseduardo keyring requires a username to retrieve a password via the CLI — you can just provide the username in the index URL you don't need to include the token too.

@jonataseduardo
Copy link

Sure!

The command

uv pip install ${MY_PACKAGE} --keyring-provider subprocess --extra-index-url https://oauth2accesstoken@${REGION}-python.pkg.dev/${PROJECT_ID}/${REPOSITORY_ID}/simple

worked. I had forgotten to include the --keyring-provider subprocess in my last attempt.

It would be helpful to include something like the following in the documentation:

  gcloud auth application-default login --project ${PROJECT_ID}                      
  uv venv
  source .venv/bin/activate
  uv pip install keyring keyrings.google-artifactregistry-auth
  uv pip install --keyring-provider subprocess ${MY_PACKAGE} --extra-index-url https://oauth2accesstoken@${REGION}-python.pkg.dev/${PROJECT_ID}/${REPOSITORY_ID}/simple                              

Thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compatibility Compatibility with a specification or another tool enhancement New feature or improvement to existing functionality
Projects
None yet
Development

No branches or pull requests

7 participants