Skip to main content

No-fuss, pure-Python keyring backend for Azure DevOps Artifacts feeds

Project description

artifacts-keyring-nofuss

Minimal, pure-Python keyring backend for Azure DevOps Artifacts feeds.

Replaces the official artifacts-keyring (which wraps a ~100 MB .NET binary) with a no-fuss implementation that covers the most common Linux auth scenarios using raw HTTP — no msal, no azure-identity, no .NET.

Install

pip install artifacts-keyring-nofuss

Or for development:

pip install -e .

How it works

When pip, uv, twine, etc. query the keyring for credentials to an Azure DevOps Artifacts feed, this backend:

  1. Discovers the Azure AD tenant by making an unauthenticated request to the feed URL and parsing the WWW-Authenticate header.
  2. Obtains a bearer token using one of the supported auth flows (see below).
  3. Exchanges the bearer token for a narrower VssSessionToken scoped to vso.packaging.
  4. Returns the session token to the caller as Basic auth credentials.

Auth flows (priority order)

# Flow How it works
1 Azure CLI Runs az account get-access-token. Most common for local dev.
2 Managed Identity Queries the Azure IMDS endpoint. For VMs/containers on Azure.

Configuration

Select a specific flow

By default, providers are tried in the order above. To force a specific one:

# Environment variable
export ARTIFACTS_KEYRING_NOFUSS_PROVIDER=azure_cli  # or: managed_identity

Or in ~/.config/python_keyring/keyringrc.cfg:

[artifacts_keyring_nofuss]
provider = azure_cli

User-assigned managed identity

Set AZURE_CLIENT_ID to the client ID of the user-assigned managed identity:

export AZURE_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

When unset, system-assigned managed identity is used.

Usage with pip

pip install --index-url https://pkgs.dev.azure.com/{org}/_packaging/{feed}/pypi/simple/ my-package

The keyring backend is automatically discovered by pip. No extra flags needed.

Usage with uv

  1. Install keyring with this backend:
pip install keyring artifacts-keyring-nofuss
# or
uv tool install keyring --with artifacts-keyring-nofuss
  1. Configure uv to use keyring for authentication. Either add it to your project config:
# pyproject.toml or uv.toml
[tool.uv]
keyring-provider = "subprocess"

Or set the environment variable:

export UV_KEYRING_PROVIDER=subprocess
  1. Use uv as normal with your private feed. A username in the URL (e.g. __token__@) is required to trigger keyring lookup:
uv pip install my-package --index-url https://__token__@pkgs.dev.azure.com/{org}/_packaging/{feed}/pypi/simple/

This also works with legacy subdomain-prefixed feed URLs:

uv pip install my-package --index-url https://__token__@myorg.pkgs.visualstudio.com/_packaging/{feed}/pypi/simple/

For pyproject.toml index configuration:

[[tool.uv.index]]
url = "https://__token__@pkgs.dev.azure.com/{org}/_packaging/{feed}/pypi/simple/"
name = "my-feed"

Supported feed URLs

Any URL whose host matches one of (including subdomain-prefixed variants):

  • pkgs.dev.azure.com (e.g. https://pkgs.dev.azure.com/myorg/…)
  • pkgs.visualstudio.com (e.g. https://myorg.pkgs.visualstudio.com/…)
  • pkgs.codedev.ms
  • pkgs.vsts.me

URLs with userinfo (e.g. https://__token__@host/…) and bare hostnames without a scheme are also handled correctly.

Troubleshooting

Enable verbose debug output to see the full authentication flow:

ARTIFACTS_KEYRING_NOFUSS_DEBUG=1 pip install --index-url https://pkgs.dev.azure.com/{org}/_packaging/{feed}/pypi/simple/ my-package

This prints the provider chain, token exchange steps, and any errors to stderr.

Security model

This package handles authentication tokens. Key security properties:

  • Endpoint validation: Discovery responses are validated against allowlists. The authorization_uri and VSTS authority must point to known hosts over HTTPS, with no non-default ports, userinfo, or deep paths. The authority must be a clean origin (https://host or https://host/). This prevents bearer token exfiltration via DNS hijacking or rogue proxy responses.
  • Short-lived tokens: Bearer tokens are not persisted to disk. In-memory caching has a 50-minute TTL (tokens typically live 60–75 minutes).
  • Narrow scope: Session tokens are scoped to vso.packaging (read-only, org-scoped).
  • No CWD config: Provider configuration is read only from ~/.config/ or environment variables, never from the working directory.
  • Minimal dependencies: Only keyring and requests — no large frameworks with broad attack surface.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

artifacts_keyring_nofuss-0.6.0.tar.gz (19.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

artifacts_keyring_nofuss-0.6.0-py3-none-any.whl (13.3 kB view details)

Uploaded Python 3

File details

Details for the file artifacts_keyring_nofuss-0.6.0.tar.gz.

File metadata

  • Download URL: artifacts_keyring_nofuss-0.6.0.tar.gz
  • Upload date:
  • Size: 19.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for artifacts_keyring_nofuss-0.6.0.tar.gz
Algorithm Hash digest
SHA256 e0f088a4950a14f2ec1c02ca1e910114c521be26ce82d9b6685fcbbdc75b8439
MD5 808a8a6c6d92732d9aa603c0a3fde495
BLAKE2b-256 c5940a23641425d7011429fe62669566e92393948e2d7de2fb1f68c7fb223dbd

See more details on using hashes here.

Provenance

The following attestation bundles were made for artifacts_keyring_nofuss-0.6.0.tar.gz:

Publisher: release.yml on microsoft/artifacts-keyring-nofuss

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file artifacts_keyring_nofuss-0.6.0-py3-none-any.whl.

File metadata

File hashes

Hashes for artifacts_keyring_nofuss-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 575e067ef01fda7fe8a122d1220124357be6d825994003c467030661c863de9f
MD5 3bcd52547dfff8ad4acfab21b7bb4638
BLAKE2b-256 4e539be07958e87d0210beb5c66e3770c40f93636c2dc13ca52399afb9213ffa

See more details on using hashes here.

Provenance

The following attestation bundles were made for artifacts_keyring_nofuss-0.6.0-py3-none-any.whl:

Publisher: release.yml on microsoft/artifacts-keyring-nofuss

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page