PKCS#11 vendors
Per-vendor notes for supported (and unsupported) HSMs.
CertAutoPilot's requirements are CKM_AES_GCM +
CKM_AES_KEY_GEN — any FIPS-approved HSM from the last
decade qualifies. We validate via the capability probe before
committing. See the setup flow
for the generic procedure.
01Support matrix
| HSM | Status | Notes |
|---|---|---|
| SoftHSM2 ≥ 2.4 | ✅ Test-only | Reference implementation for CI/dev. Not for production (software-only). CKM_AES_GCM added in SoftHSM v2.4. |
| AWS CloudHSM | ✅ Production | Set encryption.pkcs11.use_gcm_iv_from_hsm: true — CloudHSM mandates HSM-generated IVs. Requires the CloudHSM client daemon + libcloudhsm_pkcs11.so. |
| Thales Luna Network HSM 7.x | ✅ Production | Standard v2.40 behaviour. Works with host-supplied IVs. Default config. |
| Fortanix DSM | ✅ Community-validated (free SaaS tier ideal for dev/test) | Standard PKCS#11 client. Free Developer tier ships 10 000 transactions / 30-day trial — enough for a full rotation cycle without touching a credit card. See the walkthrough below. |
| Nitrokey HSM 2 | ⚠️ Likely limited | Mechanism list varies by firmware; verify CKM_AES_GCM via pkcs11-tool -M before committing. |
| YubiHSM 2 | ❌ NOT SUPPORTED | Vendor PKCS#11 module supports only CKM_AES_CBC[_PAD], CKM_AES_ECB, and the proprietary CKM_YUBICO_AES_CCM_WRAP. No CKM_AES_GCM. |
| IBM CEX 5/6/7 via opencryptoki | ⚠️ Vendor docs check | Theoretically compatible; not validated by us yet. |
02SoftHSM2 (dev / CI only)
# Install
sudo apt install -y softhsm2 opensc # Debian/Ubuntu
brew install softhsm opensc # macOS
# Initialise a token
softhsm2-util --init-token --free \
--label certautopilot-prod \
--so-pin sopassword --pin password
# One-command install via the bootstrap. Pass the PIN inline or from a
# mode-0600 file — see the standalone install docs for both variants.
curl -fsSL https://raw.githubusercontent.com/CloudNativeWorks/certautopilot-archive/main/get.sh \
| sudo bash -s -- --version=1.4.0 --mongo=local \
--kek-provider=pkcs11 \
--pkcs11-module=/usr/lib/softhsm/libsofthsm2.so \
--pkcs11-token-label=certautopilot-prod \
--pkcs11-pin=password
SoftHSM2 holds the "HSM" in a plain file. It is a legitimate development/testing backend, not a production cryptographic boundary.
03AWS CloudHSM
Prerequisites:
- Provision a CloudHSM cluster in your AWS account (or attach to an existing one).
- Create a crypto user on the cluster (separate from the crypto officer used for admin).
- Install the CloudHSM client daemon on every CertAutoPilot host (Amazon publishes packages for Amazon Linux, RHEL, Ubuntu). The package lands the library at
/opt/cloudhsm/lib/libcloudhsm_pkcs11.soand the daemon's config at/opt/cloudhsm/etc/cloudhsm_client.cfg. - Point the daemon at your cluster — one of the ENI IPs is enough; the daemon discovers peers via the cluster membership API:
This command writes the cluster endpoint intosudo /opt/cloudhsm/bin/configure -a <cluster-eni-ip> sudo systemctl enable --now cloudhsm-clientcloudhsm_client.cfg. The library reads it ondlopen; CertAutoPilot never sees the IP. - Confirm the daemon is running and the cluster is reachable:
sudo /opt/cloudhsm/bin/cloudhsm_mgmt_utilshould list nodes.
Then:
secrets:
encryption:
provider: pkcs11
pkcs11:
modulePath: /opt/cloudhsm/lib/libcloudhsm_pkcs11.so
tokenLabel: <your-cluster-label>
useGcmIvFromHsm: true # CloudHSM mandates HSM-supplied IVs
pinValue: <CU-user:password> # crypto-user creds in user:pass form
The PIN format for CloudHSM is <username>:<password> (crypto-user credentials), not a simple password.
Multi-VM: the same cluster serves every VM.
Run configure -a on each host. Cluster scaling
(adding/removing HSMs) is handled by the daemon
automatically — no CertAutoPilot restart needed for that.
04Thales Luna Network HSM
Prerequisites (must complete before running the bootstrap):
- Download the Luna Client SDK from your Thales customer portal. Install on every CertAutoPilot host — ships
libCryptoki2_64.sounder/usr/safenet/lunaclient/lib/. - Register the client certificate with your HSM partition using
vtlor the LunaSH console per Thales docs:
These commands edit# Add each HSM appliance you want this host to talk to. In an HA # group, add every member; the client library handles failover. sudo /usr/safenet/lunaclient/bin/vtl addServer \ -n hsm01.internal.example.com \ -c /etc/lunaclient/cert/server/CAFile.pem sudo /usr/safenet/lunaclient/bin/vtl addServer \ -n hsm02.internal.example.com \ -c /etc/lunaclient/cert/server/CAFile.pem # Create / assign the HA group the service will bind to. sudo /usr/safenet/lunaclient/bin/vtl haAdmin -group -add \ -label cap-prod -slot 0/etc/Chrystoki.conf. A minimal post-setup snippet of that file looks like:
You never paste IPs into CertAutoPilot'sLunaSA Client = { ReceiveTimeout = 20000; NetClient = 1; ServerName00 = hsm01.internal.example.com; ServerPort00 = 1792; ServerName01 = hsm02.internal.example.com; ServerPort01 = 1792; ClientPrivKeyFile = /etc/lunaclient/cert/client/cap-vm-a.pem; ClientCertFile = /etc/lunaclient/cert/client/cap-vm-a.cert; ServerCAFile = /etc/lunaclient/cert/server/CAFile.pem; } VirtualToken = { VirtualToken00Label = cap-prod; ... }config.yaml. The Luna library readsChrystoki.confondlopenand handles connection pooling, HA failover, and TLS to the appliances. - Verify partition access:
/usr/safenet/lunaclient/bin/vtl verifymust succeed for the CertAutoPilot host before the bootstrap runs — the installer doesn't perform partition bootstrap.
# PIN as a mode-0600 file (recommended); inline via --pkcs11-pin also works.
umask 077 && printf '%s' "$PARTITION_PASSWORD" > /tmp/cap-pin
curl -fsSL https://raw.githubusercontent.com/CloudNativeWorks/certautopilot-archive/main/get.sh \
| sudo bash -s -- --version=1.4.0 --mongo=local \
--kek-provider=pkcs11 \
--pkcs11-module=/usr/safenet/lunaclient/lib/libCryptoki2_64.so \
--pkcs11-token-label=cap-prod \
--pkcs11-pin-file=/tmp/cap-pin
shred -u /tmp/cap-pin
Luna accepts both host-supplied and HSM-supplied IVs; the default (use_gcm_iv_from_hsm: false) is fine. Consult vendor docs for firmware + FIPS-mode requirements.
Multi-VM: run the Luna client install +
vtl addServer + vtl verify sequence
on every VM before the bootstrap. The
Chrystoki.conf file has to be byte-identical
across VMs (same ServerName list, same HA group label) —
most operators push it via their config-management tool.
Each VM gets its own client cert (different ClientPrivKeyFile
/ ClientCertFile paths are fine), but all certs must be
registered with the same HSM partition.
05Fortanix DSM
Fortanix Data Security Manager (DSM) is the easiest way to try a real cloud HSM against CertAutoPilot without procurement. Their SaaS offers a free Developer tier with ~10 000 transactions / 30-day trial — enough to run a full rotation cycle (add V2 → verify → rotate → remove V1) end-to-end. FIPS 140-2 Level 3 backing, standard PKCS#11 v2.40 client, no per-host key distribution needed because the HSM is SaaS.
1. Sign up + create a Group
Go to fortanix.com →
"Start Free" → pick a region close to where CertAutoPilot will
run (EU / Americas / APAC — the region determines the
api_endpoint you'll need in the config below).
Once logged in to the DSM console:
- Groups → ADD GROUP. Name it
certautopilot-kek. A Group is the logical container that owns both your client App and your KEK Security Object.
2. Create an App (the PKCS#11 client identity)
- Apps → ADD APP.
- Name:
certautopilot. - Assigned groups:
certautopilot-kek. - Authentication method: API Key (simplest; DSM also supports PKCS#11 client certificate auth, but API Key is the shortest path to a first rotation).
-
Minimum permissions for CertAutoPilot:
ENCRYPT,DECRYPT,GENERATE. AddWRAPKEY/UNWRAPKEYif you plan to use the same App for non-envelope operations later.
After Save, the App detail page shows an API Key and an App UUID. Copy the API Key — you'll feed it to CertAutoPilot as the PKCS#11 "PIN". Treat it like any other HSM PIN: mode 0600 on disk, never in argv or shell history.
3. Download the PKCS#11 client library
Fortanix Support → PKCS#11 library downloads.
Pick the latest release (as of April 2026, PKCS#11 5.6.2919). Cross-check the
OS Compatibility Matrix linked from the same page
against your CertAutoPilot host (typically Ubuntu 22.04+, Debian 12+, RHEL/Rocky/Alma 9+).
Preferred: the distro package. It puts the library in a standard path and pulls in any required shared libraries.
# Debian / Ubuntu
sudo dpkg -i fortanix-pkcs11-*.deb
# RHEL / Rocky / AlmaLinux
sudo rpm -i fortanix-pkcs11-*.rpm
# If distro package doesn't fit, tarball works too
sudo mkdir -p /opt/fortanix/pkcs11
sudo tar -xzf fortanix-pkcs11-*.tar.gz -C /opt/fortanix/pkcs11/
fortanix_pkcs11.so (v5.x)
Fortanix renamed the library in the 5.x series. Older guides
and vendor-agnostic snippets still reference
libsdkms-pkcs11.so — if you see that path anywhere,
translate it to fortanix_pkcs11.so. The default
install puts it at
/opt/fortanix/pkcs11/fortanix_pkcs11.so.
Find where the .so landed — path depends on how you installed:
dpkg -L fortanix-pkcs11 | grep '\.so$' # Debian/Ubuntu
rpm -ql fortanix-pkcs11 | grep '\.so$' # RHEL/Rocky/Alma
find / -name 'fortanix_pkcs11.so' 2>/dev/null # fallback
4. Write the client config file
Fortanix's 5.x client auto-detects
/etc/fortanix/pkcs11.conf when no explicit path is
given, but CertAutoPilot runs as the non-root certautopilot
service user — which can't read a root-only file under
/etc/fortanix/. Pick any path the service user
can read at runtime; the examples below use
/etc/fortanix/pkcs11.conf (Fortanix default) and
fix permissions post-install. If you prefer
/etc/certautopilot/fortanix-pkcs11.conf (all
CertAutoPilot secrets in one directory), that directory only
exists AFTER this installer's first run — so either pre-create
it yourself or use the Fortanix default path for now and move
the file after install.
The installer creates the certautopilot user+group
during user::ensure, which runs before the PKCS#11
preflight check. If you're laying down the config before the
very first install, create the group yourself once so the
chown below succeeds:
getent group certautopilot >/dev/null || sudo groupadd --system certautopilot
Now write the config (INI-like, not YAML):
sudo mkdir -p /etc/fortanix
sudo tee /etc/fortanix/pkcs11.conf >/dev/null <<EOF
# One of: https://eu.smartkey.io, https://amer.smartkey.io, https://apac.smartkey.io
# Match the region you picked at signup (DSM console's top bar shows it).
api_endpoint = "https://eu.smartkey.io"
# Raw API Key from DSM console → Apps → certautopilot → API Keys tab.
# Fortanix API keys are 164 characters; a short value means a truncated copy-paste.
api_key = "<PASTE APP API KEY>"
EOF
# The service user must be able to read the config at runtime — mode 0640
# + group=certautopilot keeps it invisible to everyone else while the
# service process (group member) can open it. Parent dir needs group +x
# so path traversal works.
sudo chown root:certautopilot /etc/fortanix/pkcs11.conf
sudo chmod 0640 /etc/fortanix/pkcs11.conf
sudo chgrp certautopilot /etc/fortanix
sudo chmod 0750 /etc/fortanix
root:root 0600
If the config stays at the default
root:root 0600 that a bare tee or
text-editor save leaves behind, the service user hits
could not open file /etc/fortanix/pkcs11.conf: PermissionDenied
at every startup. The Fortanix library falls back to its
built-in defaults (no endpoint, no API key) and
C_Login returns CKR_ARGUMENTS_BAD —
the error is obscure, the root cause is purely file
permissions. The chown/chmod lines
at the end of the block above are not optional: the parent
dir needs group=certautopilot 0750 and the file
needs root:certautopilot 0640. The installer's
pkcs11 preflight will fail fast with an exact remediation if
you skip them, but fixing it up front saves a round trip.
The Fortanix library reads the config path from the
file:// URI that CertAutoPilot stores as its
PKCS#11 PIN (see the install step below). Because the URI is
explicit, the library never consults its built-in default
path or FORTANIX_PKCS11_CONFIG_PATH — so if you
already have a Fortanix client consuming the default path
you can put CertAutoPilot's config elsewhere and leave the
existing one alone. Any path the certautopilot
service user can read works.
5. Probe with pkcs11-tool before installing CertAutoPilot
Confirm auth + library work before committing to an install:
# Install the pkcs11-tool if missing
sudo apt install -y opensc # Debian/Ubuntu
# or:
sudo dnf install -y opensc # RHEL/Rocky/Alma
# Info / token list — prints 32 slots, all exposing the same token
# (label: "Fortanix Token"). The slot count is a client-library quirk;
# one token is what actually exists.
pkcs11-tool --module /opt/fortanix/pkcs11/fortanix_pkcs11.so -I
pkcs11-tool --module /opt/fortanix/pkcs11/fortanix_pkcs11.so -L
# Login + list objects.
# The --pin value is a URI telling the Fortanix library to read the real
# API key from the config file (handled by the library, not pkcs11-tool).
# An empty object list is expected on a fresh group — what matters is
# that login succeeds with no CKR_PIN_INCORRECT error.
pkcs11-tool --module /opt/fortanix/pkcs11/fortanix_pkcs11.so \
--login --pin 'file:///etc/fortanix/pkcs11.conf' -O
file:// instead of the raw API key?
Fortanix's 5.x library officially supports four PIN formats in
its C_Login handler: raw 164-character key,
env:VAR, file:///path, and
password:... (vendor docs).
Fortanix itself recommends the config-file approach "for
applications with character limits on the PIN parameter" —
relevant because the 164-character raw key routinely trips
shell PATH limits, CI secret-UI truncation, and
copy-paste-with-trailing-newline bugs. The
file:// URI sidesteps all of that: the key lives
in one mode-0600 file, and the URI you pass around (as
CertAutoPilot's PKCS#11 PIN) is itself non-secret.
Troubleshooting:
- CKR_PIN_INCORRECT with a raw API key → almost always a copy-paste whitespace or truncation. Verify
echo -n "$KEY" | wc -cprints 164. Switch to thefile://URI above to sidestep the issue entirely. - 0 slots with tokens available → config file not found or not readable. Make sure the path your
file://PIN URI points at (e.g.,/etc/fortanix/pkcs11.conf) exists and is readable by the user runningpkcs11-tool/ the CertAutoPilot service. - could not open file … PermissionDenied at
C_Login, followed byCKR_ARGUMENTS_BAD→ the service user (certautopilot) can't read the Fortanix config. Expected fix: file mode0640, ownershiproot:certautopilot; parent dir mode0750with groupcertautopilot. The Fortanix library's fallback "using default configuration" line in the same log confirms this is the permission case — the library couldn't parse your real config and defaulted to empty values, so the API key was never sent. - ECONNREFUSED / DNS error → wrong
api_endpointregion. EU account hitting the amer endpoint (or vice versa) fails here before auth is even attempted. - Authentication failed (401 in trace logs) → API Key was generated in a different region, or the App's auth method isn't "API Key" (check DSM → Apps → your app → Authentication tab), or the App is disabled.
- cannot dlopen / module not found →
.sopath wrong. Run thefindcommand above and use the exact path. - Want verbose logs? Set
FORTANIX_PKCS11_LOG_FILE=/tmp/fortanix_pkcs11.logandFORTANIX_PKCS11_LOG_LEVEL=tracein the environment that runs CertAutoPilot (for systemd: drop them into/etc/certautopilot/secrets.env; for ad-hoccertautopilot kekcommands,exportthem before invoking). The 5.x client does not honour an[log]section or top-levellog_file/log_levelkeys inside the client config — only these two env vars. The trace file records every HTTP request the library sends to DSM, which is the most direct signal when the DSM console audit log is empty. - DSM Audit Log (console → Audit Log) → most authoritative signal. Every failed auth attempt that reaches DSM is logged with a reason. If it's empty, the problem is client-side (wrong endpoint, config not loaded); if it's populated, the problem is credential-side.
6. Install CertAutoPilot with the Fortanix PKCS#11 provider
Pass the file:// URI directly as the PKCS#11 PIN:
it isn't itself a secret (it just points at the file that
holds the real API key, which you already protected with
0640 root:certautopilot in step 4), so argv
visibility of the URI during install is fine. The installer
stamps the URI into /etc/certautopilot/secrets.env
as CERTAUTOPILOT_ENCRYPTION_PKCS11_PIN; systemd
loads that into the service process at every start, and the
Fortanix library resolves the URI back to the real API key
inside C_Login.
# Bootstrap. Two Fortanix-specific flags to note:
# --pkcs11-token-label — default label is 'Fortanix Token' (with a
# space); the quotes are required.
# --pkcs11-pin — file:// URI pointing at your Fortanix
# client config. Use --pkcs11-pin-file only when the PIN itself
# is the 164-char raw API key (see alternative below).
curl -fsSL https://raw.githubusercontent.com/CloudNativeWorks/certautopilot-archive/main/get.sh \
| sudo bash -s -- --version=1.4.4 --mongo=local \
--kek-provider=pkcs11 \
--pkcs11-module=/opt/fortanix/pkcs11/fortanix_pkcs11.so \
--pkcs11-token-label="Fortanix Token" \
--pkcs11-pin='file:///etc/fortanix/pkcs11.conf'
Alternative: raw API key (no Fortanix config
file indirection). Here the 164-character key IS the secret,
so it must never appear in argv — use
--pkcs11-pin-file with a mode-0600 file:
umask 077
printf '%s' '<164-char API key from DSM>' > /tmp/cap-pin
chmod 0600 /tmp/cap-pin
curl -fsSL https://raw.githubusercontent.com/CloudNativeWorks/certautopilot-archive/main/get.sh \
| sudo bash -s -- --version=1.4.4 --mongo=local \
--kek-provider=pkcs11 \
--pkcs11-module=/opt/fortanix/pkcs11/fortanix_pkcs11.so \
--pkcs11-token-label="Fortanix Token" \
--pkcs11-pin-file=/tmp/cap-pin
shred -u /tmp/cap-pin
The raw-key path puts the 164-char secret in
/etc/certautopilot/secrets.env (mode 0600); the
URI path keeps it in /etc/fortanix/pkcs11.conf
so rotating the API key is a one-file edit rather than a
secrets.env edit plus service restart. Either path works;
pick whichever matches your secret-rotation story.
During the install, kek pkcs11-init --version=1
issues a CKM_AES_KEY_GEN against Fortanix — you'll
see a new AES Security Object appear in the DSM
console under Groups → certautopilot-kek →
Security Objects, labelled certautopilot-kek-v1.
That is your KEK.
7. Rotation cycle on Fortanix
Same shape as any other PKCS#11 provider (the runbook applies unchanged):
# Create V2 inside the HSM + kek_versions metadata
sudo certautopilot kek pkcs11-init --version=2
# Restart so the provider loads V2 alongside V1
sudo systemctl restart certautopilot
# Verify — every live node must have V2 loaded (current need not match)
sudo certautopilot kek verify --target=2
# Rotate — rewrap every envelope with V2 explicitly
sudo certautopilot kek rotate --from-version=1 --to-version=2
sudo certautopilot kek status # poll to completion
# Wait ~30s for heartbeat auto-reload to flip fleet current → V2
# (optional forced restart: systemctl restart certautopilot)
# Retire V1 — refuses if any live node still has V1 as current
sudo certautopilot kek remove --version=1
Fortanix-specific gotchas
- Token label is literally "Fortanix Token" (with a space). The DSM client exposes 32 PKCS#11 slots and every one of them carries the same fixed token label
Fortanix Token. Pass it quoted on the install command:--pkcs11-token-label="Fortanix Token". Dropping the space (Fortanix) is the most common bootstrap failure and producescould not find PKCS#11 tokenfromkek pkcs11-init. Always cross-check withpkcs11-tool -L. - Client config file must be readable by the
certautopilotservice user. A bareteeleaves the fileroot:root 0600;kek pkcs11-initruns as root and masks this, but the systemd-hardened service fails at every start withcould not open file … PermissionDeniedfollowed byCKR_ARGUMENTS_BADatC_Login. The file needsroot:certautopilot 0640and its parent dir needsroot:certautopilot 0750— see step 4. The installer's pkcs11 preflight fails fast with the exact chown/chmod if this trips. - API Key = PKCS#11 PIN. DSM doesn't have a separate "User PIN" concept for API-Key-authed Apps. If the key leaks, rotate it via DSM console → Apps → your app → "Rotate API Key", then update
/etc/certautopilot/secrets.envand restart. - Transaction budget. Free tier caps total operations (wrap + unwrap + generate). A full rotation of a lab cluster is 2–3 ops per envelope-encrypted record (unwrap old + wrap new + occasional key ops). For 500 records budget ~2 000 transactions — well within the free tier.
- Audit log. DSM console → Audit Log shows every PKCS#11 call CertAutoPilot makes. Useful for confirming rotation activity and for the sort of compliance evidence a real HSM deployment would need.
- Fortanix accepts host-supplied GCM IVs — but only at 12 bytes (NIST 96-bit). Any other length fails with
CKR_ARGUMENTS_BADatC_Encrypt(reproducible againsteu.smartkey.io). CertAutoPilot pinsGCMIVLength=12at everycrypto11.Configconstruction site for exactly this reason — you do not need to configure anything, but do not override the pin. - Leave
use_gcm_iv_from_hsmat its default (false). Thetruepath is broken on Fortanix:crypto11asksmiekg/pkcs11to build aCK_GCM_PARAMSwithpIv=NULL, butmiekgleavesulIvBitsunset in that path, and Fortanix responds withCKR_MECHANISM_PARAM_INVALIDatC_EncryptInit. Only AWS CloudHSM requirestrue; every other HSM (including Fortanix) wants host-supplied IVs. - Fortanix advertises
CKM_AES_KEY_WRAP_KWP(0x2107) andCKM_AES_KEY_WRAP(0x2104) but both reject every parameter combination we tried. Rawmiekg/pkcs11probes with NULL mechanism params and the 8-byte default ICV all returnedCKR_MECHANISM_PARAM_INVALID. Algorithm migration from AES-GCM to AES-KWP (tempting as a way to eliminate IV-length concerns) is a dead end on Fortanix; the KEK wrap stays on AES-GCM. - Trial → production. Moving from the Developer tier to a paid Fortanix subscription doesn't change anything CertAutoPilot cares about — same client library, same endpoint pattern, same PKCS#11 semantics. The keys you created during trial persist into the upgraded account.
06Nitrokey HSM 2
Nitrokey's PKCS#11 mechanism list depends on firmware version. Probe first:
pkcs11-tool --module /usr/lib/opensc-pkcs11.so -M | grep -i gcm
If CKM_AES_GCM is absent, upgrade firmware. Some older versions only expose CKM_AES_CBC — unsupported by CertAutoPilot.
07YubiHSM 2 — NOT SUPPORTED
YubiHSM's PKCS#11 module supports only CKM_AES_CBC[_PAD],
CKM_AES_ECB, and the vendor-proprietary
CKM_YUBICO_AES_CCM_WRAP. No CKM_AES_GCM,
so envelope wrap/unwrap cannot be implemented without using the
CCM wrap path — which we don't do today. A Phase 3 effort may
add YubiHSM-specific CCM wrap on request.
08IBM CEX via opencryptoki
IBM's Crypto Express cards expose PKCS#11 through the
opencryptoki layer. Theoretically they support CKM_AES_GCM,
but we haven't validated end-to-end. Run --probe-only
first; report success/failure so we can update this matrix.
09What to watch for in any HSM
- Session exhaustion. Many HSMs cap at ~1024 concurrent sessions. CertAutoPilot's default session pool is 1024; tune
encryption.pkcs11.max_sessionsif yours is tighter. - Sensitive + non-extractable attributes. The probe checks that generated keys come back with
CKA_SENSITIVE=trueandCKA_EXTRACTABLE=false. Some HSMs default differently — ensure your key policy enforces these. - IV handling. Set
use_gcm_iv_from_hsm: truefor CloudHSM. Leave false for SoftHSM2, Luna, Fortanix, and everything else. - Firmware upgrades. Before applying a firmware update, run
--probe-onlyin a non-production cluster to check for mechanism regressions.