Security·Cryptography

MCP server hardware security module: HSM, CloudHSM, and PKCS#11 key protection

Software-only cryptography stores private keys in memory or on disk — protected by OS access controls and, if you're diligent, an encrypted key store. Hardware Security Modules move key material into tamper-resistant hardware where the private key never leaves the device in plaintext. For MCP servers in regulated industries, HSM-backed key management is often a compliance requirement, not an optional enhancement.

When MCP servers need HSM-level key protection

HSMs are expensive (AWS CloudHSM runs ~$1.60/hour per cluster member, plus $1,000 initialization). The cost is justified when:

Cloud HSM options for MCP deployments

AWS CloudHSM is FIPS 140-2 Level 3 validated. It runs as a dedicated cluster within your VPC. MCP servers access it through the CloudHSM client SDK, which exposes a PKCS#11 interface or JCE/CNG interfaces. Signing a JWT with a CloudHSM-resident RSA or EC key looks like any other PKCS#11 signing operation — the API is standard; only the backing hardware changes.

AWS KMS (with the custom key store option) is a lower-cost alternative that also uses CloudHSM under the hood but adds a key management layer on top. KMS custom key stores are FIPS 140-2 Level 2/3 validated and suitable for most compliance requirements without the operational overhead of managing the CloudHSM cluster directly.

Azure Dedicated HSM is the Azure equivalent, using Thales Luna Network HSMs, also FIPS 140-2 Level 3. Azure Key Vault Managed HSM is the managed variant, analogous to AWS KMS custom key stores.

Google Cloud HSM integrates with Cloud KMS and is FIPS 140-2 Level 3 validated. The Cloud KMS API is the primary interface; no direct PKCS#11 access is required.

PKCS#11 integration in MCP server runtimes

Most MCP servers today run in Node.js or Python. Both ecosystems have PKCS#11 bindings:

In Node.js: the pkcs11js package provides raw PKCS#11 bindings. For JWT signing specifically, you can use the PKCS#11 backend with the node-jose or a custom signing implementation that delegates the private key operation to the HSM slot. The CloudHSM client daemon exposes a PKCS#11 shared library (libcloudhsm_pkcs11.so) that pkcs11js loads.

In Python: the python-pkcs11 package provides a high-level interface. For MCP servers using FastAPI or similar, signing operations use session.sign(key, data, mechanism=pkcs11.Mechanism.ECDSA_SHA256) — the private key object is a reference into the HSM; the key bytes never leave hardware.

HSM-backed TLS for MCP transport

Beyond JWT signing, TLS private keys for the MCP server's own HTTPS endpoint can also be HSM-resident. This is accomplished through PKCS#11 URIs in OpenSSL-based configurations or through engine-based integration (openssl engine pkcs11). With HSM-backed TLS, the TLS handshake's private key operation (decrypting the pre-master secret or signing the key exchange) happens inside the HSM. An attacker who compromises the MCP server process cannot extract the TLS private key because it never exists in process memory.

SkillAudit signals for HSM-relevant configurations

SkillAudit's credential exposure axis flags patterns that indicate software-only key storage: private key material in environment variables, PEM-encoded keys in configuration files, fs.readFileSync calls loading key material at startup. These signals do not prove an HSM is absent, but they strongly suggest software-resident keys. For compliance-sensitive deployments, treat any credential exposure finding as a trigger for HSM evaluation.

Run a SkillAudit scan to see whether your MCP server's credential handling passes the patterns that indicate software-only key storage — the first step before an HSM procurement conversation. Start a free audit →

← Back to blog  ·  Secrets management for MCP servers →