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:

Fail-Closed Startup Contract

Outside explicit simulation mode, HSM plugin initialization fails before loading the PKCS#11 library unless all deployment selectors are present:

SettingRequirement
LibraryPathAbsolute path to the vendor PKCS#11 library.
SlotIdNumeric PKCS#11 slot to open.
TokenLabelExpected token label in the selected slot. A mismatch fails startup.
PinUser PIN supplied through a secret source. Do not store it in source-controlled config.
KeyIds or operation-specific key IDsDeclared 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:

DetailSimulation value
providerModesimulation
pkcs11false
simulationtrue
testOnlytrue
libraryin-process-simulator
keyIdPolicyconfigured-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:

DetailMeaning
providerMode=pkcs11The provider is backed by a PKCS#11 library.
pkcs11=trueHealth probe used a real PKCS#11 client.
simulation=falseNo simulated fallback is active.
testOnly=falseHealth is not reporting the local harness.
slotConfigured slot ID.
tokenLabelExpected token label.
configuredKeyCountNumber 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