.so, .dylib, or .dll) that exposes your Infisical Signers to any tool that supports the PKCS#11 v2.40 standard. Tools like jarsigner, osslsigncode, cosign, apksigner, openssl, and gpg work without modification. They make their usual PKCS#11 calls; the module forwards them to Infisical and returns the signature.
Before installing the module, ensure a Product Admin has created a Signer and added the machine identity (or user) you plan to authenticate as. If the Signer has an approval policy, you’ll also need active access.
Installation
Grab the pre-built binary for your platform from the releases page:| Platform | File |
|---|---|
| Linux x86_64 | libinfisical-pkcs11.so |
| Linux ARM64 | libinfisical-pkcs11.so |
| macOS x86_64 | libinfisical-pkcs11.dylib |
| macOS ARM64 | libinfisical-pkcs11.dylib |
| Windows x86_64 | libinfisical-pkcs11.dll |
Building from source
If you want to build instead of downloading, you need Go 1.24+ and a C compiler:Configuration
The module reads its config from/etc/infisical/pkcs11.conf (override the path with INFISICAL_PKCS11_CONFIG):
Credentials can also live in the config file under
auth.client_id and auth.client_secret, but environment variables are strongly recommended so secrets don’t end up in version control, backups, or shared logs./etc/infisical/pkcs11.conf:
Configuration reference
| Field | Required | Default | Description |
|---|---|---|---|
server_url | Yes | None | Infisical server URL. Must use http:// (local dev) or https://. |
auth.method | No | universal-auth | Authentication method. |
auth.client_id | No | None | Machine identity client ID. Prefer the env var. |
auth.client_secret | No | None | Machine identity client secret. Prefer the env var. |
tls.ca_cert_path | No | None | Custom CA bundle path for self-hosted Infisical with a private CA. |
tls.skip_verify | No | false | Skip TLS verification (development only, never enable in production). |
cache.token_ttl_seconds | No | 300 | How long the auth token is cached. |
cache.cert_ttl_seconds | No | 3600 | How long fetched certificates are cached. |
cache.signer_ttl_seconds | No | 300 | How long the list of Signers is cached. |
approval.signing_duration | No | None | Auto-request signing access with this window when no active access exists. Valid range: 1m to 30d. |
approval.signing_count | No | None | Auto-request signing access for this many signatures when no active access exists. |
log_level | No | info | One of trace, debug, info, warn, error. |
log_file | No | stderr | Optional path to a log file. |
Environment variable reference
| Variable | Description |
|---|---|
INFISICAL_UNIVERSAL_AUTH_CLIENT_ID | Machine identity client ID. Overrides config. |
INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET | Machine identity client secret. Overrides config. |
INFISICAL_PKCS11_SERVER_URL | Override server_url. |
INFISICAL_PKCS11_CONFIG | Path to the config file (default /etc/infisical/pkcs11.conf). |
Environment variables always take precedence over values in the configuration file.
Verify the Module
Usepkcs11-tool (from OpenSC: brew install opensc or apt install opensc) to confirm everything is wired up.
CKR_GENERAL_ERROR and the module logs a “signing requires approval” line. See Automatic Signing Access Requests below to make this seamless.
Automatic Signing Access Requests
When a Signer has a policy attached, sign calls without active access normally fail. The module can automatically open a signing request for you on the first denied call. You just need to add anapproval block to the config:
signing_durationrequests an access window of this duration (30m,8h,2d; range 1m to 30d).signing_countrequests access good for this many signing operations.
maxWindow / maxSignings.
The first sign call still fails until an approver approves the auto-created request. Once approved, retry the sign and it succeeds. The module logs that the request was created so you know what to do.
Example CI workflow
- Pipeline calls
jarsigner(or any PKCS#11 tool) against the Infisical module. - No active access exists, so Infisical returns 403.
- The module sees the
approvalblock and auto-creates a signing request with the configured duration and count. - Pipeline fails on this run.
- A reviewer approves the request in the Infisical UI.
- Pipeline is rerun and the sign call succeeds under the freshly-issued access record.
Troubleshooting
Turn on debug logging in the config first. It’ll usually tell you exactly what went wrong:No slots listed
No slots listed
Almost always one of three things:
- The machine identity is not a member of any Signer in your organization. Have an Admin add it to a Signer (any role works).
- The credentials are wrong. Check the auth token line in the log; if it says
401, regenerate the universal-auth client secret. - The
server_urlpoints at the wrong instance. The module log lineInitialized with universal-auth (auto-authenticated)confirms a successful login.
CKR_GENERAL_ERROR on sign
CKR_GENERAL_ERROR on sign
Almost always means the server rejected the sign. Common reasons (visible in the debug log):
- No active access. The Signer has an approval policy and you don’t yet have access. See Request to sign.
- Access expired or signatures exhausted. Request access again.
- Signer is Disabled. Re-enable it in the UI.
- Certificate expired. Issue a new one or wait for auto-renewal.
CKR_DEVICE_ERROR or connection refused
CKR_DEVICE_ERROR or connection refused
Network or TLS problem. Check
server_url, confirm the host is reachable from the machine, and verify TLS. If you self-host with a private CA, set tls.ca_cert_path to its bundle. As a last resort during local dev, you can set tls.skip_verify: true (never in production).server_url scheme must be http or https
server_url scheme must be http or https
The module rejects any other scheme (
file://, gopher://, etc.) to prevent credentials being sent to unintended targets. Make sure your server_url starts with http:// or https://.The PKCS#11 module sees the slot but says 'signer X has no certificate'
The PKCS#11 module sees the slot but says 'signer X has no certificate'
The Signer is in Pending or Failed status; no certificate has been issued yet. Check the Signer’s status in the UI; for external CAs (AWS Private CA, Azure AD CS), issuance can take minutes. Once the Signer becomes Active, the cert is fetched automatically.
What’s next
Sign JARs
jarsigner with the PKCS#11 module.Sign containers
cosign sign with Infisical.Sign Windows binaries
osslsigncode for .exe / .dll / .msi.Sign APKs
apksigner for Android.Sign with OpenSSL
Raw signing primitives.
Sign with GPG
Use GPG via the PKCS#11 module.