Chainguard Libraries for Python overview
Learn about Chainguard Libraries for Python, providing enhanced security for PyPI packages through automated …
For the complete documentation index, see llms.txt.
Python library consumption in a large organization is typically managed by a repository manager. Commonly used repository manager applications are Cloudsmith, JFrog Artifactory, and Sonatype Nexus Repository. The repository manager acts as a single point of access for developers and development tools to retrieve the required libraries.
The recommended approach is to use the upstream
fallback
feature of Chainguard Repository, which allows you to configure your repository
manager with a single upstream pointed at https://libraries.cgr.dev/python/. The
Chainguard Repository handles fallback and policy enforcement; your repository
manager handles local caching and access control. Chainguard proxies and serves
packages from the public PyPI repository on your behalf when upstream
fallback is enabled. All packages served from Chainguard are protected with
malware scanning and a configurable cooldown policy.
At a high level, adopting the use of Chainguard Libraries consists of the following steps:
https://libraries.cgr.dev/python/ as the single upstream source for Python package retrieval.You should also:
If your organization does not use a repository manager, you can still use Chainguard Libraries. However, this approach requires configuration of multiple build and development platforms and utilities to use Chainguard Libraries. For this reason, adopting the use of a repository manager is the recommended approach. Refer to the direct access documentation for build tools for more information.
Chainguard recommends using the Chainguard Repository built-in upstream fallback rather than configuring a public PyPI fallback in your repository manager. Configuring your own fallback bypasses the protection and policy behavior provided by Chainguard Repository.
However, if you intentionally want to manage fallback ordering yourself, you can continue using the repository manager patterns described on this page to combine Chainguard and PyPI sources.
If you are migrating an existing Python project to Chainguard Libraries through a repository manager, your lockfile likely contains integrity hashes generated against packages previously downloaded from PyPI or through your repository manager. The chainctl libraries update-hashes command automates lockfile hash updates
for all supported Python lockfile formats.
When you are using a repository manager, pass the full repository manager URL with --registry-url and authenticate with one of the supported methods: --username and --password, --token, or a .netrc entry for the registry host. For example:
chainctl libraries update-hashes \
--registry-url https://repo.example.com:8443/repository/python-all/ \
--token "$REPO_TOKEN"Note: Running
chainctl libraries update-hashesrequires thelibraries.python.pullpermission or the Owner role.
After updating the lockfile, keep your repository manager configuration in place and reinstall through the same repository manager endpoint to apply the updated hashes.
Learn more in the Build configuration page and in the chainctl docs.
Cloudsmith supports Python repositories for proxying and hosting and polyglot repositories that combine multiple repositories sources with compatible formats. Refer to the Cloudsmith Python Repository documentation and the Cloudsmith documentation for creating a repository for more information.
The recommended approach is to rely on Chainguard Repository’s upstream
fallback,
configuring a single upstream proxy pointed at https://libraries.cgr.dev/python/
rather than adding a separate public PyPI proxy. Refer to Manually managing
fallback if you need to control fallback ordering
yourself.
Use the following steps to add a repository with Chainguard Libraries for Python as the upstream source.
First, create a repository:
Next, configure the upstream proxies:
python-chainguard1https://libraries.cgr.dev/python/Cache and Proxypython-chainguard-remediated,
the priority 2, the same authentication details, and the URL
https://libraries.cgr.dev/python-remediated/.python-public3https://pypi.org/Cache and ProxyRefer to the page on build tool configuration for Chainguard Libraries for Python for information on accessing credentials and setting up build tools.
Google Artifact Registry supports
the Python format for hosting artifacts in Standard repositories and proxying
artifacts from public repositories in Remote repositories. Use Virtual
repositories to combine them for consumption with pip and other build tools.
Use the Python package documentation for Google Artifact
Registry as the starting
point for more details.
The recommended approach is to rely on Chainguard Repository’s upstream
fallback,
configuring a single remote repository pointed at https://libraries.cgr.dev/python/
rather than adding a separate public PyPI remote. Refer to Manually managing
fallback if you need to control fallback ordering
yourself.
Use the following steps to add the Chainguard Libraries for Python repository as a remote repository and expose it through a virtual repository.
Before configuring the repositories, you must create a secret with the password value as retrieved with chainctl:
chainguard-libraries-python.Navigate to Artifact Registry and select Repositories in the left hand navigation under the Artifact Registry label to configure a remote repository for Chainguard Libraries for Python:
python-chainguardPythonRemoteCustom. Set the URL for the Custom repository to https://libraries.cgr.dev/python/.Authenticated.python-chainguard-remediated, the same
authentication details, and the URL
https://libraries.cgr.dev/python-remediated/.If you are manually managing fallback rather than using the Chainguard Repository’s built-in fallback, configure an additional remote repository for the public PyPI.
Combine the python-chainguard repository, and optionally the python-chainguard-remediated repository, into a new virtual repository:
python-all.Python.Virtual.python-chainguard
repository as Repository 1 and set the Policy name 1 to
python-chainguard.If you are manually managing fallback rather than using the recommended
upstream fallback,
add the public PyPI index as a second remote repository (python-public) and
give the python-chainguard policy a higher priority than python-public.
JFrog Artifactory supports PyPI repositories for proxying and virtual repositories to combine multiple sources into a single repository. The following instructions are based on the PyPI Repository documentation for Artifactory.
If you follow the recommended approach to rely on Chainguard Repository’s upstream fallback, disable or remove any existing Artifactory remote repository that points at the public PyPI index, and remove it from the virtual repository your builds resolve against. A remote pointing directly at the public upstream bypasses those protections. Since Artifactory resolves through the virtual repository in order, a misconfiguration can result in Artifactory serving an unprotected package.
Use the following steps to add Chainguard Libraries for Python as a remote repository:
Configure a remote repository for the Chainguard Libraries for Python index:
PyPI.python-chainguard.https://libraries.cgr.dev/./python in
the URL. Python’s Simple Repository
API keeps the package index on its own
path which goes in the PyPI Settings fields below, and the base
URL also needs to cover the /python-upstream/ paths for upstream fallback packages.https://libraries.cgr.dev/.python/simple.python-chainguard-remediated, the same
authentication details, and the URL
https://libraries.cgr.dev/python-remediated/.These settings are required because Chainguard Libraries stores artifacts in
Cloudflare R2. A package file download from libraries.cgr.dev returns a 302
redirect to a pre-signed URL on a different host, and the redirect response itself
is an HTML document. Without these settings, Artifactory may rewrite the
pre-signed URL, forward your credentials across the redirect, or cache the
redirect response in place of the wheel or source distribution. A cached redirect
response fails checksum verification at install time.
If you are manually managing fallback, rather than using the recommended Chainguard Repository built-in fallback approach, configure an additional remote repository for the public PyPI index.
Create a virtual repository to give your build tools a single access point:
PyPI as the Package type.python-all.python-chainguard. If you are using the remediated index, also add python-chainguard-remediated and ensure it is first in the displayed list, so that remediated versions resolve first. Use the icon on the right of the repository name to drag and drop repositories into the desired position.python-public repository and ensure it is last in the list.At this point, you have a virtual repository set up in Artifactory that allows you or others in your organization to access Chainguard Libraries for Python, optionally including remediated versions, with your chosen tools.
After creating the python-chainguard remote repository, validate that Artifactory is successfully proxying through to Chainguard before proceeding. A misconfigured remote repository fails silently; if any remote pointing at the public PyPI index is still present, Artifactory resolves through it instead and the build succeeds with no visible error. This can result in pulling an unprotected package.
Common sources of misconfiguration include invalid or expired credentials, or an incorrect or incomplete repository URL. As noted in the configuration steps, the Artifactory Test connection button is not a reliable indicator; it fails for a correctly configured Chainguard repository, and it may pass for an incorrectly configured one. Use the following steps instead to verify that fetching an artifact through Artifactory produces the same checksum as fetching it directly from libraries.cgr.dev.
urllib3. You can substitute any artifact you know to be available.curl -sSf \
-u "${CHAINGUARD_PYTHON_IDENTITY_ID}:${CHAINGUARD_PYTHON_TOKEN}" \
https://libraries.cgr.dev/python/simple/urllib3/ \
| grep -o 'https://[^"]*\.whl' | head -1libraries.cgr.dev and compute its checksum:curl -sSf -L \
-u "${CHAINGUARD_PYTHON_IDENTITY_ID}:${CHAINGUARD_PYTHON_TOKEN}" \
<url-from-step-1> \
| sha256sumcurl -sSfL \
-u "${ARTIFACTORY_USERNAME}:${ARTIFACTORY_TOKEN}" \
"https://<artifactory-host>/artifactory/<python-remote-repository>/${path-to-wheel}" \
| sha256sumReplace artifactory-host with your Artifactory instance hostname and replace python-remote-repository with your remote repository name. Replace path-to-wheel with the path component of the URL from step 1 (for example: /files/15f7d141c3b76b85/37e321caa85a8f41/urllib3/urllib3-1.26.9-py2.py3-none-any.whl)
The checksums returned by the commands must match.
If the checksum from the Artifactory remote repository differs from the direct fetch, or if the Artifactory fetch fails entirely, review the following before proceeding:
https://libraries.cgr.dev/.chainctl auth pull-token --repository=python and update the Artifactory repository credentials. Expired tokens fail silently.python-chainguard remote cache and locate the affected files. Right-click each artifact, select Delete content, then re-run your install.Do not proceed to virtual repository setup or build configuration until the checksums match.
Refer to the page on build tool configuration for Chainguard Libraries for Python for information on accessing credentials and setting up build tools.
Sonatype Nexus Repository allows for merging multiple remote repositories as a repository group. The below instructions are based on the Nexus documentation for PyPI
The recommended approach is to rely on Chainguard Repository’s upstream
fallback,
configuring a single proxy repository pointed at https://libraries.cgr.dev/python/
rather than adding a separate public PyPI proxy. Refer to Manually managing
fallback if you need to control fallback ordering
yourself.
The following steps create a remote repository for Chainguard Libraries for Python and a repository group that exposes it to your build tools.
First, log in to Sonatype Nexus as a user with administrator privileges and access the Server administration and configuration section within the gear icon in the top navigation bar.
Next, configure a remote repository for Chainguard Libraries for Python repository:
python-chainguard.https://libraries.cgr.dev/python/.If you want to use the separate repository with remediated Python
libraries repeat the
preceding steps with the name python-chainguard-remediated, the same
authentication details, and the URL
https://libraries.cgr.dev/python-remediated/.
If you are manually managing fallback rather than using the Chainguard Repository’s built-in fallback, configure an additional remote repository for the public PyPI.
Finally, create a new repository group and add the repositories:
python-all.python-chainguard-remediated and python-chainguard to the right. Move the python-chainguard-remediated repository to the top of the list.Refer to the page on build tool configuration for Chainguard Libraries for Python for information on accessing credentials and setting up build tools.
.whl.metadata
Builds fail intermittently when Sonatype Nexus is configured as a PyPI proxy in front of libraries.cgr.dev, even though authentication, entitlements, and network connectivity all check out. The failures look like missing packages, but the packages themselves are present and downloadable. The Nexus outbound request logs show 404 responses specifically for URLs ending in .whl.metadata, while the same URL without the .metadata suffix succeeds.
Modern Python installers (pip 23.1+, uv) implement PEP 658 and request a small per-package metadata file by appending .metadata to the wheel’s download URL, ahead of downloading the wheel itself. When Nexus is serving a stale cached index page, it can point clients at a metadata URL format that libraries.cgr.dev no longer honors. Chainguard’s upstream returns 400 for that request, which Nexus in turn surfaces to the client as a 404. The result presents as a missing package, when the underlying issue is a stale cached index.
To fix this, delete and recreate the Chainguard PyPI proxy repository in Nexus. This clears all cached index pages and metadata assets for that repository, forcing Nexus to pull fresh copies on the next request.
Alternatively, you could add a Nexus routing rule to block metadata requests outright. Clients fall back to standard resolution automatically when the metadata request fails cleanly, without surfacing an error:
Block..*\.metadata$.Last updated: 2026-08-21 19:07