docs/documentation/platform/pki/code-signing/guides/pkcs11-gpg.mdx
In the following steps, we explore how to use GnuPG with the Infisical PKCS#11 module via gnupg-pkcs11-scd. This enables signing git commits and tags, RPM/DEB packages, and any other artifact that uses GPG signatures, all backed by keys stored securely in Infisical.
Sign permission on the signergnupg-pkcs11-scd (the PKCS#11 smart card daemon bridge)Create ~/.gnupg/gnupg-pkcs11-scd.conf:
providers infisical
provider-infisical-library /usr/local/lib/libinfisical-pkcs11.so
Configure GnuPG to use the PKCS#11 smart card daemon. Edit ~/.gnupg/gpg-agent.conf:
scdaemon-program /usr/bin/gnupg-pkcs11-scd
Restart the GPG agent to apply the changes:
gpgconf --kill gpg-agent
List the available keys from the PKCS#11 token:
gpg --card-status
The output shows your signer's key information. To use the key for signing, you need to learn the key grip and create a GPG key stub:
# List key grips from the PKCS#11 token
gpg-connect-agent "SCD LEARN" /bye
Look for lines starting with KEY-FRIEDNLY or KEYPAIRINFO. These show the available keys and their key grips (40-character hex strings). Note the key grip for the signer you want to use.
Then generate a key stub:
You can generate the key stub interactively:
gpg --expert --full-gen-key
# Select option: (13) Existing key
# Enter the key grip from the previous step
Or use batch mode for CI/CD environments:
cat > /tmp/gpg-keygen.txt <<EOF
Key-Type: RSA
Key-Length: 3072
Key-Grip: <KEY-GRIP-FROM-PREVIOUS-STEP>
Name-Real: Release Signing
Name-Email: [email protected]
Expire-Date: 0
%no-protection
%commit
EOF
gpg --batch --gen-key /tmp/gpg-keygen.txt
Note the key ID from the output (shown as a 40-character hex string). You'll use it for signing.
Configure git to use your GPG key:
# Set the signing key
git config --global user.signingkey <KEY-ID>
# Enable commit signing by default
git config --global commit.gpgsign true
# Enable tag signing by default
git config --global tag.gpgsign true
Now every commit and tag will be signed automatically:
# Signed commit
git commit -m "feat: add new feature"
# Signed tag
git tag -s v1.0.0 -m "Release v1.0.0"
# Verify a commit signature
git log --show-signature -1
# Verify a tag signature
git tag -v v1.0.0
Use GPG to create detached signatures for any file:
# Create a detached signature
gpg --detach-sign --armor -u <KEY-ID> release-v1.0.0.tar.gz
# Verify
gpg --verify release-v1.0.0.tar.gz.asc release-v1.0.0.tar.gz
For CI pipelines, configure the GPG agent in non-interactive mode. You need to create the key stub on each run since GNUPGHOME is ephemeral:
export INFISICAL_UNIVERSAL_AUTH_CLIENT_ID="${INFISICAL_CLIENT_ID}"
export INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET="${INFISICAL_CLIENT_SECRET}"
export INFISICAL_PKCS11_CONFIG="/path/to/pkcs11.conf"
# Set up ephemeral GPG home directory
export GNUPGHOME=$(mktemp -d)
cp /path/to/gnupg-pkcs11-scd.conf "$GNUPGHOME/"
cp /path/to/gpg-agent.conf "$GNUPGHOME/"
# Discover available keys from the PKCS#11 token
gpg-connect-agent "SCD LEARN" /bye
# Create a key stub pointing to the PKCS#11 key
# Replace KEY-GRIP with the grip from the SCD LEARN output (KEYPAIRINFO line)
cat > /tmp/gpg-keygen.txt <<EOF
Key-Type: RSA
Key-Length: 3072
Key-Grip: <KEY-GRIP>
Name-Real: CI Signing
Name-Email: [email protected]
Expire-Date: 0
%no-protection
%commit
EOF
gpg --batch --gen-key /tmp/gpg-keygen.txt
# Sign the artifact using the generated key
gpg --detach-sign --armor artifact.tar.gz
For any issue, enable debug logging in your config file ("log_level": "debug", "log_file": "/tmp/infisical-pkcs11.log") to get detailed output.