A PKCS#11 remote proxy written in Rust. Applications load the shim library in place of a local PKCS#11 module. The shim forwards calls over gRPC to a daemon connected to the token or HSM, preserving the backend's results within the documented support limits.
app ──dlopen──▶ libpkcs11_proxy_ng_shim.so ──gRPC/TLS──▶ pkcs11-proxy-ng (daemon) ──FFI──▶ backend .so (HSM/token)
Current source version:
v<!-- SYNC-VERSION -->0.3.1<!-- /SYNC-VERSION -->.Latest published release: v0.3.1 (2026-10-27; release notes). It carries over v0.3.0 a release-process change only — no environment approvals and no provider-qualification evidence on the release path (see the notes). The provider-matrix qualification planned for this version did not land; support claims are unchanged from v0.3.0. See GitHub Releases for published versions, the support matrix for supported environments, and release documentation for qualification status.
Use one logical client in one trusted security domain per daemon/provider
instance. Do not share it with mutually untrusted clients. Restart the daemon
and provider before switching independent clients or domains.
[proxy] max_contexts = 1 limits admission; it does not establish isolation.
Multi-client isolation is planned for a later version
(v0.4 scope).
Installed from a release bundle? On Linux and macOS follow
INSTALL.md in the extracted archive instead of the
source-checkout steps below. The Windows ZIP carries no
INSTALL.md: start from its proxy.toml.template plus the
Run-Pkcs11ProxyNg.ps1 supervisor, following Windows daemon
operations.
This local example uses SoftHSM2 and OpenSC's pkcs11-tool.
# 1. Install prerequisites on Debian/Ubuntu.
# Install Rust through rustup first; see doc/development.md.
sudo apt install -y build-essential pkg-config protobuf-compiler \
softhsm2 opensc gnutls-bin
# 2. Initialise a test token. Use these PINs only for local development.
softhsm2-util --init-token --slot 0 --label dev \
--so-pin 1234 --pin 1234
# 3. Build.
cargo build --workspace --release --locked
# 4. Start the daemon with the dev config (loopback, no TLS).
RUST_LOG=pkcs11_proxy_ng=info LOG_FORMAT=plain \
./target/release/pkcs11-proxy-ng examples/configs/dev/proxy.toml &
# 5. List slots through the proxy.
PKCS11_PROXY_ENDPOINT=http://127.0.0.1:7512 \
pkcs11-tool --module ./target/release/libpkcs11_proxy_ng_shim.so \
--list-slotsFor anything beyond local dev, start from a template in
examples/configs/ (dev / staging / prod) rather than
hand-rolling a config.
The selected v0.2 native ownership contract
is implemented: mechanism roots and nested
output cells live in persistent native allocations (Miri-checked under both
borrow models), one provider chain per process is enforced by the
constructor domain with lifecycle-honest retirement, wire widths are
checked with rejection proven on i686 hardware, slot waiting is
CKF_DONT_BLOCK-only with shared native event flags, and the Linux
whole-process lifetime stop (exit_group(70)) fires on the admitted
targets. What remains is candidate-bound qualification — session
operation slots, subprocess/topology coverage, and the provider parity
round — not the enforcement itself. The v0.2.0 tail stretch
(implemented 2026-09-17) evidences Windows x64/MSVC daemon + shim in both interoperation
directions on real Windows Server 2022
(artifacts/v020-tail-windows-2026-09-16/ legs A/B/C at the workspace root),
the 32-bit/mixed width claim (four Linux legs plus the NSS-i386 second
provider, scripts/run-cross-width-*-live-test.sh in nightly), the per-PR
Tier 0f windows-client-llp64 --all-targets gate, and the deterministic
Windows ZIP bundle (scripts/release-windows.sh, SHA256SUMS-windows).
This is not a v0.2 parity/support receipt.
Public v0.1.0 support
- Linux
x86_64 - Remote daemon over TCP + mTLS (baseline public transport), and Unix-domain socket + peer-credential auth for same-host deployments
- Backends validated with direct-vs-proxied parity: SoftHSM2, NSS softokn, Kryoptic
- The released daemon, client, CLI, and shim architecture and TOML config model
Explicitly not claimed for this beta
- General production-readiness / operational guarantees
- Windows GNU, 32-bit Windows (PE32), and macOS/ARM/big-endian runtime claims
- Plain TCP without mTLS as a public-supported mode (undecided)
- Backends beyond the validated matrix (others may work but are unvalidated)
The public v0.1.0 beta claim — "the proxy does not materially change observed PKCS#11
behavior for the validated providers" — is backed by repeatable direct-vs-proxied
checking, not by assertion. See the full
beta support matrix and the
parity methodology.
The v0.2.x releases carry the opt-in gateway authorization,
resilience, and audit increments (see the v0.2.0
notes). v0.3.0 adds the
stabilization increments on top — the audit-remediation campaign plus
passive CLI diagnostics, the generated support-matrix table, release
attestation/recovery tooling, and experimental platform legs. v0.3.1
changes only the release process on top of that (see the
v0.3.1 notes for scope and limits);
the planned matrix qualification did not land, so support claims are
unchanged from v0.3.0.
doc/development.md— native tools, optional mise setup, MSRV, and local validation commandsdoc/error-reference.md— everyCK_RVthe proxy can return, with cause + operator action + application actiondoc/runbooks/operating-pkcs11-proxy-ng.md— deploy, configure, roll out, troubleshoot; daemon and shim env varsdoc/provider-support-tables.md/doc/oasis-profile-coverage.md— provider and PKCS#11 spec coveragedoc/release/— beta support matrix, mTLS setup, parity validation methodology, and the0.xrelease checklist. Scope rule for every direct-vs-proxied mismatch: proxy bugs get fixed here, provider-conformance issues go upstream — never normalized by the proxy (parity triage)scripts/README.md— CI, release, and manual tools
The PRD, ADRs, architecture overview, audits, and follow-up notes are maintained
in the separate pkcs11-proxy-ng-ws planning workspace. This repository builds,
tests, and packages releases independently.
See configuration examples for local, mTLS, and
Unix-socket setups. The staging and prod example names describe settings;
the current source remains a single-client testing candidate.
Build and stage the Linux release artifacts without a PKCS#11 provider:
scripts/release-dry-run.shThis validates packaging only; provider parity and publication readiness are separate release gates.
The dry run checks packaging, not provider parity or publication readiness. The
complete freeze, receipt, tag, and publication procedure is in the
0.x release checklist.
It stages these files:
| Artifact | Purpose |
|---|---|
target/release/pkcs11-proxy-ng |
gRPC proxy daemon |
target/release/pkcs11-proxy-ng-cli |
administrative and smoke-test CLI |
target/release/libpkcs11_proxy_ng_shim.so |
loadable PKCS#11 shim library |
Use --prefix /tmp/pkcs11-proxy-ng-install to keep the staged layout, or
--skip-build to check existing target/release artifacts. See the
development guide for provider tests.
Eight crates publish at one synchronized version with exact =X.Y.Z
internal requirements (mirrored from the workspace version — see
scripts/sync-versions.sh). Four are user-facing entry points;
the rest resolve automatically as dependencies. Version 0.3.1 is
published; the current checkout tracks post-v0.3.1 work.
cargo install pkcs11-proxy-ng --locked # daemon
cargo install pkcs11-proxy-ng-cli --locked # CLIAdd pkcs11-proxy-ng-client = "=X.Y.Z" as a dependency for the Rust
client library (substitute the latest
release).
The pkcs11-proxy-ng-shim crate builds the loadable
PKCS#11 module — take it from a GitHub release bundle or OS package,
never cargo install it as a library.
The current checkout is not release-qualified. The full maintainer procedure — prerequisites, staging, recovery, evidence retention, and docs.rs follow-up — is in the crates.io publication guide.
Read AGENTS.md before contributing.
Licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
See licensing and source provenance for the mock table's provenance limits and the distribution notice boundary. Third-party source material is not relicensed by the project's Apache-2.0 OR MIT choice.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.