HSM PKCS#11 Deployment Health
Scope
The Stella Ops HSM provider is an in-process PKCS#11 provider. Production deployments must use a real PKCS#11 library and token. The in-process simulated HSM is only a local harness and is visible in health metadata as providerMode=simulation, simulation=true, and testOnly=true.
ARM64 Runtime Contract
Pkcs11Interop is managed code. The ARM64 compatibility boundary is the operator-supplied PKCS#11 library configured through LibraryPath, plus any native GOST/OpenSSL/CryptoPro provider it delegates to.
For linux/arm64 production deployments:
- Stella Ops first-party .NET service images are ARM64-ready on Debian/Ubuntu glibc
linux-arm64; only the configured native provider route remains operator-specific. - Use Debian/Ubuntu glibc-based .NET service images. Alpine/musl .NET service images are outside the ARM64 readiness baseline unless a separate audit proves every native NuGet asset and every configured provider library supports musl ARM64.
- The configured PKCS#11 library must be an ARM64/aarch64 ELF built for the same libc family as the service image. An x64-only
.socannot be loaded by an ARM64 .NET process. - Validate the real route before treating it as release evidence: confirm the library architecture (
fileorreadelf -h), resolve dynamic dependencies (lddon the target image), open the slot, verify the token label, and run a sign/verify probe against the declared key id. - If a vendor only supplies amd64 GOST or PKCS#11 binaries, keep the affected signing route on amd64 or expose it through a remote/sidecar provider with explicit route evidence. Do not treat local simulation or generated keys as an ARM64 production substitute.
- For GOST specifically, prefer an open-source OpenSSL GOST or PKCS#11 substitution route when certification rules allow it. Russian vendor GOST providers are not supported for local ARM64 Stella Ops installations unless the provider supplies a compatible Debian/Ubuntu
linux-arm64package. Operators who need that route should contact their GOST provider for ARM64 Linux support and attach the provider’s evidence to the release route.
Fail-Closed Startup Contract
Outside explicit simulation mode, HSM plugin initialization fails before loading the PKCS#11 library unless all deployment selectors are present:
| Setting | Requirement |
|---|---|
LibraryPath | Absolute path to the vendor PKCS#11 library. |
SlotId | Numeric PKCS#11 slot to open. |
TokenLabel | Expected token label in the selected slot. A mismatch fails startup. |
Pin | User PIN supplied through a secret source. Do not store it in source-controlled config. |
KeyIds or operation-specific key IDs | Declared key identifiers allowed for signing, verification, encryption, and decryption. |
Supported key identifier settings are comma, semicolon, or pipe-delimited strings:
Cryptography:
Hsm:
LibraryPath: "/usr/lib/softhsm/libsofthsm2.so"
SlotId: 0
TokenLabel: "StellaOps-Prod"
Pin: "${HSM_PIN}"
KeyIds: "stellaops-signing-2026,stellaops-encryption-2026"
For narrower routing, use SigningKeyIds, VerificationKeyIds, EncryptionKeyIds, and DecryptionKeyIds. The provider rejects any runtime operation whose KeyId is not declared.
Simulation Harness
Simulation must be opted in explicitly:
Cryptography:
Hsm:
AllowSimulation: true
RuntimeEnvironment: "Testing"
KeyIds: "local-hsm-signing,local-hsm-encryption"
AllowSimulation=true is accepted only for Development or Testing runtime environments. The provider resolves the environment from RuntimeEnvironment, then DOTNET_ENVIRONMENT, then ASPNETCORE_ENVIRONMENT, defaulting to Production when none is set. Production startup fails closed even when AllowSimulation=true; the flag cannot turn an HSM route into release evidence.
If no simulation key IDs are configured, the harness creates a local default key. Simulation health details include:
| Detail | Simulation value |
|---|---|
providerMode | simulation |
pkcs11 | false |
simulation | true |
testOnly | true |
library | in-process-simulator |
keyIdPolicy | configured-allow-list when key IDs are set |
Simulation signatures and encryption are not release evidence. They exist only for deterministic local wiring tests and route validation.
PKCS#11 Health Metadata
Real PKCS#11 mode reports:
| Detail | Meaning |
|---|---|
providerMode=pkcs11 | The provider is backed by a PKCS#11 library. |
pkcs11=true | Health probe used a real PKCS#11 client. |
simulation=false | No simulated fallback is active. |
testOnly=false | Health is not reporting the local harness. |
slot | Configured slot ID. |
tokenLabel | Expected token label. |
configuredKeyCount | Number of declared key identifiers. |
Health never exposes the PIN.
SoftHSM And Device Test Hooks
Adjacent integration tests are opt-in and tagged HsmIntegration, so default CI can continue to run offline without native HSM packages. To run them locally with SoftHSM2 or a compatible device:
export STELLAOPS_SOFTHSM_LIB="/usr/lib/softhsm/libsofthsm2.so"
export STELLAOPS_SOFTHSM_SLOT="0"
export STELLAOPS_SOFTHSM_TOKEN_LABEL="StellaOps-Dev"
export STELLAOPS_SOFTHSM_PIN="87654321"
export STELLAOPS_SOFTHSM_KEY_ID="stellaops-hsm-test"
export STELLAOPS_SOFTHSM_MECHANISM="RsaSha256"
dotnet test src/Cryptography/__Tests/StellaOps.Cryptography.Tests/StellaOps.Cryptography.Tests.csproj \
--filter FullyQualifiedName~Pkcs11HsmClientIntegrationTests
If the library, PIN, token label, or key ID variables are absent, the integration tests skip with an explicit reason. The focused setup guide remains docs/operations/softhsm2-test-environment.md.
Operational Notes
- Do not enable
AllowSimulationin production configuration. - Treat a startup failure for missing PKCS#11 settings as a deployment defect, not as a reason to fall back to local keys.
- Token label validation protects against selecting the wrong slot after HSM maintenance or SoftHSM token reinitialization.
- Keep key IDs aligned with signer, attestor, and authority signing profiles so evidence can trace the exact HSM key route.
