PyHSM is a production-ready software Key Management Service (KMS) that securely stores encryption keys, signs data, manages key lifecycles, and keeps an auditable record of every operation so your applications are safer by design.
Stop embedding encryption keys in your code.
Stop building your own key management from scratch.
Give your applications a secure vault for their most valuable secrets.
sudo apt install pipx -y && pipx install vectorguard-pyhsm
If those secrets are compromised, attackers can impersonate users, steal money, or decrypt sensitive information.
Most teams store these secrets in environment variables, config files, or worse — hardcoded in source code. One breach exposes everything.
PyHSM gives those secrets a secure home — encrypted at rest, access-controlled, audited, and lifecycle-managed.
See how teams use PyHSM to protect what matters most.
Protect the encryption keys securing customer accounts, transaction signatures, and payment data.
Safeguard patient data, digital identities, and comply with HIPAA encryption requirements.
Sign blockchain transactions without ever exposing private keys to application code or disk.
Securely store API credentials, webhook secrets, and per-tenant encryption keys at scale.
Protect model credentials, inference API secrets, and sensitive customer data used in pipelines.
Manage device certificates and signing keys across distributed deployments without cloud dependency.
cryptography Library?Python's cryptography library gives you primitives. PyHSM gives you a complete key management system.
| Capability | cryptography library |
PyHSM |
|---|---|---|
| Encrypt / Decrypt | Yes (you manage keys yourself) | Yes (keys managed for you) |
| Key storage & encryption at rest | Not included | Double-encrypted keystore (AES-GCM + AES-KWP) |
| Key rotation | Build it yourself | Built-in with version tracking |
| Access control & caller identity | Not included | Caller ACLs, rate limits, operation caps |
| Audit logging | Not included | HMAC-chained tamper-evident log |
| Key lifecycle policies | Not included | Expiration, archival, destruction |
| Process isolation | Not included | Separate OS process for key material |
| Memory zeroization | Not included | Deterministic byte-by-byte clearing |
| Shamir secret sharing | Not included | M-of-N key reconstruction |
The cryptography library is a toolbox. PyHSM is the locksmith. PyHSM knows how to use the tools securely, manages the keys, tracks who accessed what, and ensures nothing is left exposed.
A complete key management system, not a wrapper around a single crypto library.
AES-256-GCM with hybrid nonce strategy (Python) and nonce-misuse-resistant AES-256-GCM-SIV (TypeScript). Argon2id key derivation following OWASP recommendations.
Split master keys into shares with configurable thresholds. No single point of compromise. M-of-N unlock ceremony for production deployments. Per-share HMAC-SHA256 integrity (256-bit, index-bound) prevents corrupted or adversarially crafted shares from being accepted during reconstruction.
Tamper-evident audit trail with cryptographic chaining. Every operation is recorded and verifiable. Rotation-seal entries (rotationSeal/rotationOpen) extend integrity across file boundaries — deletion of any rotated log file is detectable via verify_across_rotations(). CEF/LEEF/JSON SIEM export.
Full feature parity across Python and TypeScript. Use whichever fits your stack. 274 tests (180 Python + 94 TypeScript), 80% coverage enforced in CI.
Built-in key expiration, operation limits, caller ACLs, and automatic rotation via rotate_every_days policy. Keys rotate lazily on next use when due.
Known-Answer Tests (KATs) covering all 10 active cryptographic primitives run automatically against published NIST and RFC test vectors. Crypto modules are verified before any key operation is accepted.
Built-in FileBackend (atomic writes) and MemoryBackend (testing/ephemeral). Implement the StorageBackend interface to plug in any database, S3 bucket, or cloud store.
Create encrypted point-in-time backups of your keystore with create_backup(). Verify integrity at any time with verify_backup() — HMAC check without loading into the live store.
Export operational metrics in Prometheus text format or OpenTelemetry OTLP JSON. First-class observability without extra agents.
PyHSM's 3 biggest competitors — and why teams choose PyHSM instead.
Amazon's fully managed cloud key management service. Deep AWS integration, FIPS-certified hardware — but every key and every API call costs money, and your keys live on Amazon's infrastructure.
Google's managed key management service. Similar story to AWS KMS — excellent if you're already on GCP, but you're locked into Google's infrastructure and pricing model.
IBM-owned secrets management platform with a Transit secrets engine for cryptography-as-a-service. Powerful, but requires Consul for HA, a dedicated ops team, and ~$1,140/month on HCP.
| Feature | PyHSM | AWS KMS | Google Cloud KMS | HashiCorp Vault |
|---|---|---|---|---|
| Pricing model | AGPL-3.0 free · Commercial license from $149/mo (Startup) · $349/mo (Growth) · $749/mo (Scale) | $1/key/month + $0.03/10K API calls | $0.06/key/month + $0.03/10K operations | ~$1.58/cluster/hour (HCP managed) or self-hosted infra cost |
| Vendor lock-in | ✅ None — runs anywhere | ❌ AWS-only | ❌ GCP-only | ⚠️ HCL policy language, Consul dependency for HA |
| Data sovereignty | ✅ Full — you own and control the keystore | ❌ Keys stored on AWS infrastructure | ❌ Keys stored on Google infrastructure | ⚠️ Depends on deployment model |
| secp256k1 (Ethereum/Bitcoin) | ✅ Native, built-in | ✅ Supported (SECG P-256k1) | ✅ Supported | ❌ Not in Transit — requires a custom third-party plugin |
| Ed25519 (Solana/Cosmos) | ✅ Native, built-in | ✅ Supported (added Nov 2025) | ⚠️ Limited support | ❌ Not in Transit natively |
| Shamir M-of-N secret sharing | ✅ Built-in, HMAC-hardened | ❌ Not available | ❌ Not available | ⚠️ Shamir-based unseal only (not a user-facing API) |
| Tamper-evident audit log | ✅ HMAC-chained, spans rotation boundaries, SIEM export | ⚠️ AWS CloudTrail (separate service, additional cost) | ⚠️ Cloud Audit Logs (separate service) | ✅ Audit log available |
| Per-key ACLs + rate limiting | ✅ Built-in per key | ⚠️ IAM policies (complex, coarse-grained) | ⚠️ IAM policies (complex, coarse-grained) | ✅ Vault policies |
| Argon2id KDF (memory-hard) | ✅ Required, OWASP-recommended | ❌ Not applicable (managed service) | ❌ Not applicable | ❌ Not applicable |
| Process isolation (IPC) | ✅ Unix socket IPC server, mutual HMAC auth | ✅ By design (managed service) | ✅ By design (managed service) | ✅ By design (separate server) |
| Python + TypeScript SDKs | ✅ Both included, feature parity | ✅ AWS SDK (multi-language) | ✅ Google SDK (multi-language) | ✅ Multi-language clients |
| JWK import/export | ✅ Full RFC 7517 (all key types) | ⚠️ Import only (limited) | ⚠️ Import only (limited) | ✅ Supported |
| Automatic key rotation | ✅ rotate_every_days policy, lazy | ✅ Automatic rotation available | ✅ Automatic rotation available | ✅ Supported |
| Prometheus + OTLP metrics | ✅ Built-in | ❌ Requires CloudWatch | ❌ Requires Cloud Monitoring | ✅ Built-in |
| FIPS 140-2/3 certified | ❌ FIPS-approved algorithms, not certified | ✅ FIPS 140-2 validated HSMs | ✅ FIPS 140-2 validated HSMs | ⚠️ Depends on deployment |
| Compliance docs included | ✅ SOC 2, PCI-DSS, HIPAA, NIST, ISO 27001, GDPR | ✅ AWS handles its own compliance | ✅ Google handles its own compliance | ⚠️ Partial — org must document |
| No cluster/infra to manage | ✅ pip install, 5 lines of code | ✅ Fully managed | ✅ Fully managed | ❌ Requires Consul for HA, dedicated ops |
| Network latency per operation | ✅ Sub-millisecond (local) | ❌ 5–50ms per API call | ❌ 5–50ms per API call | ⚠️ Local if self-hosted, ~20ms if HCP |
| Open source | ✅ AGPL-3.0 | ❌ Proprietary | ❌ Proprietary | ✅ MPL 2.0 (OSS core) |
AWS KMS at 50 keys with 1M API calls/month costs ~$53/month. Google KMS is similar. Vault HCP runs ~$1,140/month before client fees. PyHSM's annual commercial license is a flat fee — no per-operation billing, ever.
HashiCorp Vault's Transit engine does not support secp256k1 natively — you have to find, audit, and maintain a third-party plugin. PyHSM has it built in with zero additional setup.
Vault requires Consul for high availability, a dedicated operator, and an HCL policy language to learn. PyHSM is pip install vectorguard-pyhsm and five lines of Python. No cluster, no sidecar, no ops team required.
With AWS KMS and Google Cloud KMS, your keys live on someone else's infrastructure. With PyHSM, the keystore is a file you control, encrypted with a key only you hold. No cloud provider can be compelled to hand your keys to a third party.
Where PyHSM doesn't win: If you need a FIPS 140-2 certified module for a U.S. federal contract or PCI Level 1 SAQ D, AWS KMS or a hardware HSM is the correct answer. PyHSM's COMPLIANCE.md is explicit about this — it's not a gap to hide, it's a scope boundary.
PyHSM is free and open source under AGPL-3.0. Commercial licenses unlock proprietary use. Production Support gives you direct access to the engineering team.
Required if you embed PyHSM in a proprietary product, run it behind a SaaS API, or need a written agreement for procurement. Not needed for open-source, internal, or evaluation use.
1 production deployment · up to 5 keys
Up to 5 deployments · unlimited keys
Unlimited deployments · unlimited keys
For teams that want ongoing expert guidance and a direct line to the creator — deployment help, security reviews, architecture reviews, and incident troubleshooting.
Priority access to the engineering team for teams running PyHSM in production.
Clone the repo or pip install vectorguard-pyhsm. Open source under AGPL-3.0 — use it freely in open-source projects. Commercial or proprietary use requires a commercial license.
Full documentation, test suite, README.md, and OPERATIONS.md cover every security decision. Read the source. Audit it. It's your code now.
When you need implementation guidance or code review, get Priority Support.
Deploy with confidence knowing the creator of PyHSM is available to review, advise, and help when things get complex.
A complete walkthrough showing how PyHSM encrypts a private key, splits the master password with Shamir secret sharing, and recovers it using the default Anvil private key.
0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80. This is the default Anvil (Foundry) test private key. Never use test keys in production.
First, we create a keystore and generate an AES-256 encryption key inside it. Then we encrypt the Anvil private key using that key. The master password protects the entire keystore. Without it, the encrypted data is useless.
vectorguard-pyhsm --store demo-keystore.enc generate vault-key --type aes-256
# → Generated aes-256 key: vault-key
vectorguard-pyhsm --store demo-keystore.enc encrypt vault-key \
-d "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
# → 0200000001f383ad67000000009a3d48dfa78fe787...(ciphertext)
The private key is now encrypted inside the keystore. The ciphertext output is the AES-256-GCM encrypted form of the key; it's completely useless without the master password. Even if an attacker steals the keystore file, they cannot recover the private key.
Now we eliminate the single point of failure. Instead of one person holding the master password, we split it into 5 shares using Shamir's Secret Sharing. Any 3 shares can reconstruct the password, but 2 or fewer reveal zero information. This is mathematically proven, not just computationally hard.
# Each ASCII character becomes its 2-digit hex code:
# 'd' = 64, 'e' = 65, 'm' = 6d, 'o' = 6f, '-' = 2d, 'm' = 6d, 'a' = 61, ...
#
# Full breakdown of "demo-master-password":
# d=64 e=65 m=6d o=6f -=2d m=6d a=61 s=73
# t=74 e=65 r=72 -=2d p=70 a=61 s=73 s=73
# w=77 o=6f r=72 d=64
#
# You can verify this with Python:
python3 -c "print('demo-master-password'.encode().hex())"
# → 64656d6f2d6d61737465722d70617373776f7264
The split command operates on hex-encoded byte strings. The hex value 64656d6f2d6d61737465722d70617373776f7264 is simply the ASCII encoding of "demo-master-password" represented in hexadecimal. Each character maps to its hex byte value (e.g., 'd' → 64, 'e' → 65, 'm' → 6d). This is not encryption or hashing; it's a direct, reversible encoding that the Shamir split algorithm requires as input.
vectorguard-pyhsm split -k 3 -n 5 -s "64656d6f2d6d61737465722d70617373776f7264"
# → Share 1: {"index": 1, "data": "d18a992fabfb5eb8e53689284a0f69f734d3312b", "share_hmac": "...", "hmac_salt": "...", "reconstruction_hmac": "..."}
# → Share 2: {"index": 2, "data": "0985e4adb3d6b7e7c3e9a8fba6d4a5958b7628ae", "share_hmac": "...", "hmac_salt": "...", "reconstruction_hmac": "..."}
# → Share 3: {"index": 3, "data": "bc6a10ed3540882c52ba53fe9cbabf11c8ca6be1", "share_hmac": "...", "hmac_salt": "...", "reconstruction_hmac": "..."}
# → Share 4: {"index": 4, "data": "ce2a97e3180640240fce01c779af615d67ae9ba0", "share_hmac": "...", "hmac_salt": "...", "reconstruction_hmac": "..."}
# → Share 5: {"index": 5, "data": "7bc563a39e907fef9e9dfac243c17bd92412d8ef", "share_hmac": "...", "hmac_salt": "...", "reconstruction_hmac": "..."}
Distribute one share to each of 5 custodians. No single custodian (or even any 2) can reconstruct the password. Each share should be stored in a separate location — different password managers, different physical safes, or different geographic regions depending on your threat model.
When you need to decrypt (sign a transaction, recover the key, rotate credentials, etc.), you gather any 3 of the 5 custodians. Each provides their share, and the master password is reconstructed.
vectorguard-pyhsm reconstruct \
--share '{"index": 1, "data": "d18a992fabfb5eb8e53689284a0f69f734d3312b", "share_hmac": "...", "hmac_salt": "...", "reconstruction_hmac": "..."}' \
--share '{"index": 3, "data": "bc6a10ed3540882c52ba53fe9cbabf11c8ca6be1", "share_hmac": "...", "hmac_salt": "...", "reconstruction_hmac": "..."}' \
--share '{"index": 5, "data": "7bc563a39e907fef9e9dfac243c17bd92412d8ef", "share_hmac": "...", "hmac_salt": "...", "reconstruction_hmac": "..."}'
# → 64656d6f2d6d61737465722d70617373776f7264 (hex of "demo-master-password")
Notice we used shares 1, 3, and 5 (any combination of 3 works). The reconstruction outputs the hex-encoded master password which is then used to unlock the keystore.
With the reconstructed master password, unlock the keystore and decrypt the original private key.
vectorguard-pyhsm --store demo-keystore.enc decrypt vault-key \
-d "0200000001f383ad67...(ciphertext)" \
-p "demo-master-password"
# → 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
The original private key is recovered exactly as it was. The audit log records every operation with HMAC-chained tamper detection; so you have a permanent, verifiable record of who decrypted what and when.
The private key is never stored in plaintext anywhere
The master password doesn't exist as a single secret (it's split across 5 people)
Any 2 or fewer shares reveal zero information (information-theoretic, not computational)
Every encrypt/decrypt operation is permanently recorded in the audit log
If someone tampers with the keystore file, PyHSM detects it and refuses to open
AGPL-3.0 licensed. Read every line. Security-conscious developers trust what they can verify. Commercial use in proprietary products requires a commercial license — contact us.
You own the code, the keys, and the deployment. No cloud dependency, no per-operation fees.
AES-256-GCM / AES-256-GCM-SIV, Argon2id, HKDF, HMAC-SHA256. No custom cryptography — only proven standards. Startup Known-Answer Tests cover all 10 active primitives. 274 tests (180 Python + 94 TypeScript), 80%+ coverage enforced in CI.
HMAC-chained audit logs spanning rotation boundaries, caller ID tracking, cross-rotation verify_across_rotations(), and SIEM export provide evidence for SOC 2, PCI-DSS, HIPAA, NIST SP 800-57, ISO 27001, and GDPR auditors. See COMPLIANCE.md for the full framework coverage matrix.
Key material is deterministically zeroized byte-by-byte after every operation. Sensitive buffers never linger in heap memory waiting for garbage collection — a requirement auditors look for and most libraries skip entirely.
Run PyHSM as a separate OS process communicating over a Unix socket with mutual HMAC authentication. Your application code never holds raw key material in its own memory space — the attack surface shrinks to the IPC boundary.
Architecture, security, and design questions about PyHSM.
v2.0.0 is a major release. Existing keystores are readable — PyHSM migrates the KDF automatically on the next write. The code changes are minimal but required:
pip install --upgrade vectorguard-pyhsmPyHSM("path", "pw") to PyHSM(storage_path="path", master_password="pw").decrypt() always returns bytes. If you pass the result to a string API, add .decode("utf-8").get_audit_log() returns an AuditLog object. Replace any direct list access with .export_jsonl().allow_export defaults to False. Add "allow_export": True to key policies where JWK export is needed.generate --type is now required. The implicit aes-256 default has been removed.PyHSM.create() in production. The sync constructor is retained for testing but emits a deprecation warning.See the full migration guide in the documentation for a detailed breakdown.
v2.3.1 (released October 29, 2026) is a security hardening release with no breaking changes. It ships four targeted fixes and 10 new regression tests:
RateLimiter.allow(), usage(), and reset() now all acquire a threading lock before touching shared state. Previously, two concurrent threads could both pass the rate-limit check before either recorded the operation, admitting up to 2× the configured limit under burst load. The fix makes every check-then-record atomic.audit.verify(), audit.verify_across_rotations(), and the legacy Shamir 4-byte checksum path have been replaced with hmac.compare_digest(). Plain != on HMAC-derived strings is a timing oracle — an adversary can guess values byte-by-byte by measuring response latency.import_key_jwk() now rejects RSA keys below 2048 bits with a clear error citing NIST SP 800-131A Rev. 2. Only 2048 and 4096 bits are accepted. Previously, any RSA key size (including 512 and 1024 bits) would be silently stored and used.Total test count is now 274 tests (180 Python + 94 TypeScript).
v2.3.0 shipped two changes:
October 28 — License change: MIT → AGPL-3.0. The license was updated from MIT to the GNU Affero General Public License v3.0 (AGPL-3.0). There are no code changes in this stage — the version bump exists solely to mark the license transition clearly in the package history.
October 29 — Offline JWT license enforcement and runtime notices. The following features were added:
PyHSM() instantiation emits an INFO-level log entry stating the AGPL-3.0 terms and commercial licensing contact. The CLI prints a one-line banner to stderr on every subcommand.LicenseError before any key operation is permitted.license CLI subcommand that shows the active tier, licensee, expiry, and limits.get_license_info() API method returning a LicenseInfo dataclass.license_verified or agpl_mode event is written to the HMAC-chained audit log at every session open.What the AGPL change means for you:
COMMERCIAL_LICENSE.md in the repository or contact pavon@vectorguardlabs.com.Users who had v2.2.5 already installed in their infrastructure prior to October 28, 2026 are unaffected by this change.
v2.2.0 was a targeted security-hardening release. v2.2.5 reflects the current stable version with all hardening in place. There are no breaking changes from v2.1.0 except that --ipc-secret is now required for the IPC server.
Security fixes in v2.2.0 (all present in v2.2.5):
--ipc-secret (or PYHSM_IPC_SECRET) must be set. The server refuses to start without it. Any client connecting to the HSM process must present a valid HMAC-SHA256 token on every request; unauthenticated connections are rejected before any operation is processed.checksum field remain backward-compatible.rotationSeal/rotationOpen entries cryptographically stitch the HMAC chain across file boundaries. The new verify_across_rotations() method verifies the full chain across all retained rotated files — deletion of any rotated file is detectable.Migration from v2.1.0: The only change required is supplying --ipc-secret to the IPC server. Generate it once with openssl rand -hex 32, store it securely (ideally on a tmpfs mount, chmod 600), and pass it at startup. Existing Shamir shares continue to work — new splits automatically use the stronger HMAC scheme.
Vault solves a different problem at a different scale. It's a secrets management platform — it manages database credentials, API tokens, PKI certificates, and dynamic secrets across an organization. It requires Consul for HA, needs dedicated operators, and the Enterprise license for features like HSM auto-unseal costs six figures.
PyHSM is a focused key management library. You pip install it, import it in your code, and you have key generation, signing, encryption, and audit logging in five lines. There's no cluster to manage, no Consul dependency, no operator UI to secure, no HCL policy language to learn.
Use Vault if: You need org-wide secrets management with 50 services and dynamic credential rotation.
Use PyHSM if: You need to encrypt data or sign transactions from your application with proper key lifecycle management — without the operational overhead.
Additional distinction: Vault's Transit engine doesn't support secp256k1. If you're signing Ethereum or Bitcoin transactions, Vault can't do it natively. PyHSM can.
Short answer: PyHSM doesn't claim the key is impossible to extract. It makes extraction as difficult as possible within software constraints, and makes all access auditable.
The layers of defense:
bytearray (Python) or Buffer (Node.js) and deterministically zeroized byte-by-byte after each operation. It never sits in a string pool waiting for garbage collection.hsm.sign() and get a signature back. hsm.decrypt() returns the plaintext as bytes — the private key itself is unwrapped internally, used, and zeroized.export_jwk() exists for interoperability, but it's a deliberate call that gets logged in the audit trail. Keys require "allow_export": True in their policy — this is False by default.What PyHSM cannot prevent: A root-level attacker with memory debugging tools attached to the running HSM process during the microseconds of signing. That's what hardware HSMs solve with a physical trust boundary.
Key rotation generates a new key version and archives the old one. Old ciphertexts remain decryptable because the version number is embedded in the ciphertext format.
Mechanically:
os.urandom(32))archived: trueencrypt() calls use the new versiondecrypt() reads the version prefix from the ciphertext header and selects the matching key version automaticallyThis means you can rotate keys without re-encrypting your entire database. Old data decrypts with the old version, new data uses the new version.
Automatic rotation: Set "rotate_every_days": 90 in the key policy and PyHSM rotates the key automatically on the next encrypt() call after the interval expires — no cron jobs or external schedulers needed.
Rotation is currently supported for AES keys. Asymmetric keys (EC, RSA, Ed25519) don't rotate in-place — you generate a new key ID and transition callers.
Each audit entry contains an HMAC that chains to the previous entry — similar to a blockchain of log records.
To tamper with entry N, an attacker would need to recompute the HMAC for entries N, N+1, N+2, ... all the way to the end. And to compute any HMAC, they need the audit HMAC key — which is derived from the master password via HKDF.
Verification walks the chain and checks every HMAC against its predecessor. If any entry was modified, inserted, or deleted, the chain breaks and verification reports the exact sequence number where corruption occurred.
Cross-rotation chain integrity (v2.2.0+): When the log rotates, a rotationSeal entry is written to the closing file containing the chain's final HMAC. The new file starts with a rotationOpen entry recording that seal. verify_across_rotations() stitches all retained rotated files oldest-to-newest, so deletion of any rotated file is detectable — an attacker cannot erase evidence without breaking the provable chain.
The log is append-only — entries are never modified or deleted during normal operation. Every operation (including denied ones) is recorded with timestamp, operation type, key ID, caller ID, and success/failure status.
PyHSM provides the following guarantees:
PYHSM_ALLOW_PBKDF2_FALLBACK=1 for migrationrotationSeal/rotationOpen + verify_across_rotations()) — tamper-evident across all retained filesWhat is explicitly NOT guaranteed: Protection against kernel-level access, CPU side-channel attacks, physical access to hardware, or compromised underlying crypto libraries.
PyHSM defends against five classes of threat actors:
In-scope: Filesystem theft, application compromise, unauthorized key usage, silent key abuse, insider threats with partial access, keystore tampering, audit log manipulation.
Out-of-scope (acknowledged): Root attacker with debugger during signing, CPU side-channels, physical hardware access, compromised OS kernel.
It depends on your constraints. Neither is universally better.
Use AWS KMS if: You're in a regulated environment requiring FIPS certification, you're already all-in on AWS, you don't need secp256k1/Ed25519, and you're fine with per-operation costs and network latency.
Use PyHSM if: You need secp256k1/Ed25519 signing (blockchain), you want to avoid per-operation costs at scale, you require data sovereignty, you want zero vendor lock-in, or your latency budget can't tolerate network round-trips for every operation.
Key differences: AWS KMS costs $1/key/month + $0.03/10K API calls and adds 5–50ms latency per operation. PyHSM is free for open-source use (AGPL-3.0), runs locally with sub-millisecond crypto latency, supports secp256k1 and Ed25519 (which KMS doesn't), and has no vendor lock-in — you can export keys in standard JWK format (allow_export: true in the key policy).
They're not mutually exclusive: Some teams use AWS KMS for general infrastructure encryption and PyHSM specifically for blockchain transaction signing where AWS has no native support.
Process isolation is the highest security configuration PyHSM offers within software constraints. It separates key material into a dedicated OS process that communicates with your application over a Unix domain socket (IPC).
Why it matters: Without isolation, an attacker who achieves Remote Code Execution (RCE) in your application can read anything in that process's memory — including any key material that happens to be unwrapped at that moment. With process isolation, the keys live in a separate address space. The attacker would need a kernel exploit to cross that boundary.
How it works:
/run/pyhsm/pyhsm.sock).Authentication: As of v2.2.0, IPC mutual authentication is mandatory — the server refuses to start without a configured --ipc-secret (or PYHSM_IPC_SECRET environment variable). The client authenticates each request using an HMAC-SHA256 over the message payload. Unauthenticated connections are rejected before any operation is processed.
Performance (v2.2.0+): The previous global lock has been replaced with per-key locking. Read-only operations hold no lock at all. A 30-second per-connection timeout drops stalled clients rather than blocking other operations.
Trade-offs: Process isolation adds IPC latency (typically <1ms on localhost) and operational complexity (two processes to manage instead of one). For most deployments, this is negligible compared to the security gain.
In production, you don't want a single person (or a single .env file) holding the master password that unlocks all keys. PyHSM implements Shamir's Secret Sharing over GF(256) to split the master password into N shares where any K shares can reconstruct it — but K-1 or fewer reveal zero information about the secret.
Typical setup (3-of-5):
Security properties:
PYHSM_SHARES as a comma-separated list of JSON objects — each provided by a different secrets manager or operator.When to use Shamir: Any deployment where the master password represents a single point of failure — production systems, multi-team environments, regulatory contexts requiring separation of duties, or anywhere you need to survive the "hit by a bus" scenario.
This is by design — it's a security property of Shamir Secret Sharing, not a bug.
Why the shares differ each time: Shamir Secret Sharing works by generating a random polynomial of degree K-1 (where K is your threshold). The secret is the constant term (the y-intercept), but the other coefficients are randomly chosen each time you run split.
For a 3-of-5 split, PyHSM generates a random degree-2 polynomial:
f(x) = secret + a1*x + a2*x² (over GF(256))
secret is fixed (your master password bytes)a1 and a2 are randomly generated each timeThe shares are points on this polynomial: Share 1 = f(1), Share 2 = f(2), etc. Different random coefficients produce a different polynomial, which produces different shares — but the same y-intercept (your secret).
Why reconstruction still works: Any 3 points on a degree-2 polynomial uniquely determine that polynomial, and therefore uniquely determine f(0) — the secret. Your shares and someone else's shares are from different polynomials that pass through the same point at x=0.
Visual intuition:
f(x) = secret + 7x + 3x² → shares A, B, C, D, Eg(x) = secret + 2x + 9x² → shares V, W, X, Y, ZBoth f(0) = g(0) = secret. But f(1) ≠ g(1), f(2) ≠ g(2), etc.
Why this matters for security: This randomness is critical. If the same secret always produced the same shares, an attacker who saw shares from two different split ceremonies could cross-reference them. The random coefficients ensure that every split is independent — even if you split the same secret 1,000 times, the shares are completely different each time and reveal nothing about each other.
Yes — blockchain signing is one of PyHSM's primary use cases and a key differentiator from cloud KMS solutions like AWS KMS or Google Cloud KMS, which don't support secp256k1 or Ed25519.
Supported blockchain ecosystems:
How it works in practice:
hsm.sign("eth-wallet", tx_hash).(r, s, v) and broadcasts.Security advantages over raw key files:
.env file — it's double-encrypted and requires the master password (or M-of-N Shamir shares) to unlock.max_operations policies prevent unlimited signing even if the application is compromised.Production considerations: Latency is ~103ms per sign operation (dominated by keystore persistence). For high-frequency use cases, consider the TypeScript layer's deferred persistence mode. For cold wallets or treasury keys, combine with Shamir 3-of-5 so no single operator can unlock the signing key.
Ready to secure your key management? Let's talk about which plan fits your team.
We respond to all inquiries within 1 business day.