uv-pkcs11
An unofficial fork of uv — the extremely fast Python package and project manager — with PKCS#11 client-certificate (mTLS) support, so uv can authenticate to package indexes with keys held in PKCS#11 providers that never expose the private key.
The fork never logs in to a token, so it works with providers whose
certificate and key are usable without a PIN: software HSMs, network HSMs
unlocked out of band, and p11-kit-proxied providers configured for loginless
use. Ordinary PIN-protected smart cards and tokens that require C_Login
before private-key use are not supported. The PKCS#11 support itself is
new (beta): tested end to end against SoftHSM, with limited real-world
provider mileage so far.
This project is not affiliated with or endorsed by Astral. The fork lives at github.com/dtrodrigues/uv-pkcs11; for everything except the PKCS#11 additions, see the upstream documentation.
Usage
Client-certificate behavior is controlled entirely by SSL_CLIENT_CERT:
-
A
pkcs11:URI (an RFC 7512 subset) selects a PKCS#11 identity:$ export SSL_CLIENT_CERT='pkcs11:?module-path=/path/to/pkcs11-module.so' $ uv pip install --index-url https://my-mtls-index.example.com/simple/ some-package
The path attributes
token,serial,id(percent-encodedCKA_ID), andobject(certificate label) narrow the match when tokens hold more than one identity, for examplepkcs11:id=%01orpkcs11:token=MyToken;type=certis accepted, other attributes are rejected. Themodule-pathquery attribute must be an absolute path, and the named module is native code loaded into the process — only point it at a module you trust. Without amodule-pathquery attribute, the p11-kit proxy (p11-kit-proxy.so;p11-kit-proxy.dylibon macOS) is loaded, picking up any module registered with p11-kit. Exactly one identity must match, otherwise uv reports an error naming the candidates. -
A file path is a PEM client certificate and key, exactly as in upstream uv.
-
Unset means no client certificate — stock uv behavior. PKCS#11 is never activated implicitly.
Notes:
- No PIN is presented and no login is performed: the certificate/key pair
must be visible in a public session (providers unlocked out of band work
as-is; PIN-protected devices requiring login will not).
pin-value/pin-sourceURI attributes are rejected. - RSA only (PKCS#1 v1.5 and PSS with SHA-256/384/512); the identity applies
only to verified HTTPS connections, never to hosts marked
--allow-insecure-host. - Only the leaf certificate is sent; intermediates must be known to the server.
Known limitations (kept simple on purpose; both surface as TLS handshake failures rather than discovery-time errors):
- Pairing trusts the provider's
CKA_IDconvention: the certificate's public key is not compared against the private key, so a stale or mispaired certificate sharing the key'sCKA_IDis selected and fails when the server verifies the handshake signature. Re-provision the token so certificate and key match. - Signature schemes are offered based on
C_GetMechanismListalone: per-mechanismCKF_SIGNflags and key-size ranges fromC_GetMechanismInfoare not checked, so a token that lists an RSA mechanism it cannot use with the selected key (for example a key outside the mechanism's supported size range) fails inC_Signduring the handshake.
Installation
$ pip install uv-pkcs11
Wheels are built for Linux (x86_64 and aarch64) and macOS (Apple Silicon);
other platforms build from the sdist. The distribution installs the uv and
uvx commands and therefore must not be installed alongside the official
uv distribution in the same environment — install one or the other.
Versioning
Wheel versions mirror the upstream uv release the fork is built from (e.g.
0.12.9); .postN marks a fork-side re-release of the same upstream base.
uv self update support is intentionally not built in — it would replace
this fork with official uv binaries.
Release files for uv-pkcs11 0.12.9
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| uv_pkcs11-0.12.9.tar.gz | 7.2 MB | Details |
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| uv_pkcs11-0.12.9-py3-none-manylinux_2_28_aarch64.whl | Python 3 | none | Linux glibc 2.28+ ARM64 | Details |
| uv_pkcs11-0.12.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64 | Details |
| uv_pkcs11-0.12.9-py3-none-macosx_11_0_arm64.whl | Python 3 | none | macOS 11.0+ ARM64 | Details |
Total release size: 74.4 MB
Release files / uv_pkcs11-0.12.9.tar.gz
| Download URL | uv_pkcs11-0.12.9.tar.gz |
|---|---|
| Size | 7.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3a74f4bb65cb0c46da578947575f1b974406ad85251c99566d9ae605ce48d2b6
|
|
BLAKE2b-256 checksum How to use checksums |
e858e45d9f56733691fddbeb62a1b3cab9b96b308681297ed57fea72bc5737d9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / uv_pkcs11-0.12.9-py3-none-manylinux_2_28_aarch64.whl
| Download URL | uv_pkcs11-0.12.9-py3-none-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 23.1 MB |
| Tags | Linux glibc 2.28+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
a99d52eb8b052414d0b3124828e35c495141eef95736f7579a7a8424eff17cd4
|
|
BLAKE2b-256 checksum How to use checksums |
aaccc1b4f111c76b99fa8514927fed13fc97c9890d23396c902b615913bec8ca
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / uv_pkcs11-0.12.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | uv_pkcs11-0.12.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 24.0 MB |
| Tags | Linux glibc 2.17+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
b9e1139cb0367d6adc1bb9bfbd39a5af7f5047e0f93694ab75b6a6712b17f2d1
|
|
BLAKE2b-256 checksum How to use checksums |
abb21a07267c5ec1cb4284e67300f94b057a7f4dc2dba5f6b4f2717c6b55fae7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / uv_pkcs11-0.12.9-py3-none-macosx_11_0_arm64.whl
| Download URL | uv_pkcs11-0.12.9-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 20.2 MB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
91c036a67bdc950ee233692ef273e3ab9d223b2cd19e706ea2ed3670cc1d9138
|
|
BLAKE2b-256 checksum How to use checksums |
89a3f82eb11609fe82f88a80343dfad6c2cbb41497ea7eab690857f11ba6434b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|