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

Provide feedback and improve doc on keyring index authentication #12280

Open
LSerranoPEReN opened this issue Mar 18, 2025 · 4 comments
Open

Provide feedback and improve doc on keyring index authentication #12280

LSerranoPEReN opened this issue Mar 18, 2025 · 4 comments
Labels
enhancement New feature or improvement to existing functionality error messages Messaging when something goes wrong

Comments

@LSerranoPEReN
Copy link

Summary

Hello,
I tried using uv with custom package indexes and found the way to configure the authentication with keyring really very counter-intuitive.

Foremost, the services names that uv tries to access with keyring is, to the best of my knowledge, not documented.
By looking at the traces it seems that uv tries at least two services names:

  • <package_index_url>/<package_name>
  • <package_index_fqdn>

Moreover, invalid credentials or missing credentials gives the same error:
An index URL (<package_index_url>) could not be queried due to a lack of valid authentication credentials (401 Unauthorized). This become more confusing as the documentation clearly states that:

When authenticate is set to always, uv will eagerly search for credentials and error if credentials cannot be found.

But I personally could not get uv to return a different error in this case.

I think that using custom package indexes would be a lot less frustrating if :

  1. Services names looked up by uv were documented in the authentication section
  2. Failures due to missing credentials printed a different error from failures due to invalid credentials.
  3. Failures due to missing credentials listed the service name tried.
  4. Failures due to invalid credentials printed the service name used for the index authentication.

Example

No response

@LSerranoPEReN LSerranoPEReN added the enhancement New feature or improvement to existing functionality label Mar 18, 2025
@zanieb
Copy link
Member

zanieb commented Mar 18, 2025

Regarding (1), we do link to the providers in https://docs.astral.sh/uv/configuration/indexes/#using-credential-providers — I'm hesitant to repeat them all there because they are relevant for other requests than those for indexes. We're interested in broadly improving the credential provider experience though, I expect the documentation to be expanded.

The rest sound like nice improvements to the error messages.

@zanieb zanieb added the error messages Messaging when something goes wrong label Mar 18, 2025
@jtfmumm
Copy link
Contributor

jtfmumm commented Mar 18, 2025

Would you mind sharing more details about your environment (including uv version) and what you ran using authenticate = "always"? With the latest uv, I would have expected you to see different errors if there are missing vs. incorrect credentials.

With the following pyproject.toml:

[project]
name = "example"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = []

[[tool.uv.index]]
name = "example-index"
url = "https://pypi-proxy.fly.dev/basic-auth/simple"
authenticate = "always"
default = true

if I run uv add anyio with uv 0.6.7, it produces the following error for me on both macOS and ubuntu:

error: Failed to fetch: `https://pypi.org/simple/anyio/`
  Caused by: Missing credentials for https://pypi.org/simple/anyio/

Whereas running with incorrect credentials produces the lack of valid authentication credentials error.

@LSerranoPEReN
Copy link
Author

LSerranoPEReN commented Mar 19, 2025

@zanieb & @jtfmumm thank you for taking the time to look at my issue.

I think a bit more context of my use case will be useful.

My team and I are using GitLab package registries to distribute our internal packages.
If you don't already know, a GitLab package registry can hold many python packages. If the repository is private then the package registry can be accessed with a personal (or project) assess token. This token should be provided as the password for authentication and in this case the username is completely ignored by GitLab (but is by convention usually set to __token__ in the documentation).

For instance GitLab provides the following example to use package registry with pip:

pip install <package_name> --index-url https://__token__:<your_personal_token>@<gitlab_domain>/api/v4/projects/<project_id>/packages/pypi/simple

At the moment, we are using poetry as a package and project manager, but I'm looking for alternatives. In poetry, credentials are managed using poetry own subcommand and are stored using python keyring (or plaintext if no keyring is available). My understanding that uv does not manage credentials for you, and that this feature is not in the work pipeline at the moment.

Still, uv can retrieve credentials from keyring using the --keyring-provider subprocess, which call the following command keyring get <service_name> <username> internally, which is great. So as a user I can simply keyring set <service_name> <username> to store my credentials, and everything should work.
But as a user, I have no idea what to set <service_name> to. By comparison, it's not a problem in poetry because since it can manage credentials for you, it sets its own <service_name>.

Using enough verbosity when calling uv I can see that if "https://pypi-proxy.fly.dev/basic-auth/simple" is configured as the index URL, the following services names are tried:

  • https://pypi-proxy.fly.dev/basic-auth/simple/<package_name>/
  • pypi-proxy.fly.dev

I don't think I saw this behavior in the documentation, bringing point (1).
(Weirdly https://pypi-proxy.fly.dev/basic-auth/simple/ is not tested as a service name)

Concerning @jtfmumm remark, I can indeed reproduce this behavior.
I had made the mistake of providing a username in the URL https://[email protected]/basic-auth/simple to match my GitLab use case. In this situation, if no credentials are found with keyring get, I think uv still tries to connect using only a username and no password which brings the 401 Unauthorized error.

So I guess it's technically not a bug, but it is still frustrating to not be able to distinguish between credentials being invalid and credentials not being found. Keep in mind that, for uv to use keyring you need to provide a username, otherwise you get a Skipping keyring lookup for https://pypi-proxy.fly.dev/basic-auth/simple/anyio/ with no username.

Edit: all experiments were done uv 0.6.7+1 (e0f81f0d4 2025-03-17) on Debian 12 - amd64

jtfmumm added a commit that referenced this issue Mar 19, 2025

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
)

This addresses a small part of #12280, namely when you have
`authenticate` set to `always`, it will output a distinct error message
for the case where you have a username but are missing a password.
@zanieb
Copy link
Member

zanieb commented Mar 20, 2025

We added keyring lookups for usernames in #12316

I think your other note is a case of #4056

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or improvement to existing functionality error messages Messaging when something goes wrong
Projects
None yet
Development

No branches or pull requests

3 participants