docs/documentation/platform/pki/code-signing/pkcs11-module.mdx
The Infisical PKCS#11 module implements the PKCS#11 v2.40 standard, allowing tools like jarsigner, openssl, cosign, osslsigncode, apksigner, and gpg to use Infisical signers without code changes.
Download 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 |
Place the binary in a known location, for example /usr/local/lib/:
# Linux
sudo cp libinfisical-pkcs11.so /usr/local/lib/
sudo chmod 755 /usr/local/lib/libinfisical-pkcs11.so
# macOS
sudo cp libinfisical-pkcs11.dylib /usr/local/lib/
sudo chmod 755 /usr/local/lib/libinfisical-pkcs11.dylib
If you prefer to build from source, you need Go 1.24+ and a C compiler:
git clone https://github.com/Infisical/infisical-pkcs-11.git
cd infisical-pkcs-11
make build
The output binary will be in the current directory.
Create a JSON configuration file at /etc/infisical/pkcs11.conf (or any path you prefer):
{
"server_url": "https://app.infisical.com",
"project_id": "<your-project-id>",
"log_level": "info"
}
Then set the authentication credentials via environment variables:
export INFISICAL_UNIVERSAL_AUTH_CLIENT_ID="<your-machine-identity-client-id>"
export INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET="<your-machine-identity-client-secret>"
If using a non-default config path, set:
export INFISICAL_PKCS11_CONFIG=/path/to/your/pkcs11.conf
| Field | Required | Default | Description |
|---|---|---|---|
server_url | Yes | None | Infisical server URL |
project_id | Yes | None | Project ID containing the signers |
auth.method | No | universal-auth | Authentication method |
auth.client_id | No | None | Machine identity client ID (prefer env var) |
auth.client_secret | No | None | Machine identity client secret (prefer env var) |
tls.ca_cert_path | No | None | Custom CA cert for self-hosted instances |
tls.skip_verify | No | false | Skip TLS verification (development only) |
cache.token_ttl_seconds | No | 300 | Auth token cache duration |
cache.cert_ttl_seconds | No | 3600 | Certificate data cache duration |
cache.signer_ttl_seconds | No | 300 | Signer list cache duration |
approval.signing_duration | No | None | Auto-request signing access with this time window (e.g. "8h", "30m", "2d"). Range: 1m to 30d |
approval.signing_count | No | None | Auto-request signing access for this many signing operations |
log_level | No | info | Log level: trace, debug, info, warn, error |
log_file | No | stderr | Path to log file |
| Variable | Description |
|---|---|
INFISICAL_UNIVERSAL_AUTH_CLIENT_ID | Machine identity client ID |
INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET | Machine identity client secret |
INFISICAL_PKCS11_SERVER_URL | Override server_url from config |
INFISICAL_PKCS11_CONFIG | Path to config file (default: /etc/infisical/pkcs11.conf) |
Use pkcs11-tool (from OpenSC) to verify the module is working:
# List available slots (one per signer)
pkcs11-tool --module /usr/local/lib/libinfisical-pkcs11.so --list-slots
The output lists one slot per signer in your project:
Available slots:
Slot 0 (0x0): release-signer
token label : release-signer
token manufacturer : Infisical
...
To list the objects (private key, certificate, public key) in a slot:
pkcs11-tool --module /usr/local/lib/libinfisical-pkcs11.so --slot 0 --list-objects
If a signer has a signing policy attached, the module can automatically create a signing request when a sign operation is denied due to a missing grant. This removes the need to manually create requests via the UI or API before signing.
To enable this, add the approval section to your config file with at least one of the following:
{
"approval": {
"signing_duration": "8h",
"signing_count": 10
}
}
signing_duration: Requests a time-window grant of the specified duration (e.g. "30m", "8h", "2d"). Valid range: 1 minute to 30 days.signing_count: Requests a grant for a fixed number of signing operations.You can set one or both depending on the constraints defined in the signing policy.
<Note> The sign operation will fail until an approver approves the request first. Once approved, retrying the sign operation will succeed. The module logs a message indicating that an approval request was created automatically. </Note>For any issue, start by enabling debug logging in your config file to get detailed output:
{
"log_level": "debug",
"log_file": "/tmp/infisical-pkcs11.log"
}