Skip to main content

Keystores

By default the Edge holds the seed in its own locked memory and derives child keys as it needs them. EDGE_KEYSTORE moves that work somewhere else.

ModeWhere the key material livesTier
mnemonicThe Edge's own mlocked memory. DefaultAll
pkcs11An HSM or a softHSM token, via PKCS#11Ultimate
awskmsAWS KMSUltimate
azurekvAzure Key Vault (Managed HSM)Ultimate

What the default already gives you

Before reaching for an HSM, be clear about what mnemonic mode does:

  • The phrase is read once from a file at mode 0400 and never re-read.
  • It is copied into an mlocked region so it cannot be paged to swap, and the source buffer is zeroed.
  • Child private keys are derived on demand, used to sign, and zeroed. Never persisted.
  • Nothing derived from the phrase is written to the data directory.
  • The container runs as a non-root uid with a read-only root filesystem and ALL capabilities dropped except IPC_LOCK.

The residual exposure is that the seed exists in the process's address space while the process runs. An attacker with the ability to read that memory — a kernel-level compromise of the host, or a core dump collected off-box — gets it.

That is the threat the three managed keystores address, and only that one. If your risk model does not include host memory disclosure, mnemonic mode is not the weak link.

PKCS#11

For an HSM on your own network: Thales Luna, Utimaco, YubiHSM, or softhsm2 for testing.

environment:
EDGE_KEYSTORE: pkcs11
EDGE_PKCS11_LIBRARY: /usr/lib/softhsm/libsofthsm2.so
EDGE_PKCS11_SLOT: "0"
EDGE_PKCS11_PIN_FILE: /run/secrets/hsm_pin
EDGE_PKCS11_LABEL: chainos-master

The PIN goes in a file for the same reason the mnemonic does — see Configuration.

The constraint that decides whether this works for you: the Edge needs the HSM to perform BIP-32 derivation and the signing, on both secp256k1 and Ed25519. Most HSMs sign both curves. Far fewer implement BIP-32 child derivation as a mechanism, and the ones that do not force one of two arrangements:

  • Derivation inside the Edge, signing in the HSM. The child private keys are still in process memory, so this buys you protection of the master seed only. Better than nothing and clearly less than it sounds.
  • One HSM key object per address. Fully protected, and it does not scale — an HSM with a few thousand key slots caps how many customers you can have.

Confirm which of these your device supports before you commit to a design. Ziklag will help you check at onboarding; this is exactly the kind of thing that is discovered late.

AWS KMS

environment:
EDGE_KEYSTORE: awskms
EDGE_AWSKMS_KEY_ID: arn:aws:kms:eu-west-1:123456789012:key/…
AWS_REGION: eu-west-1
# Credentials from the instance role, IRSA or the container credential provider —
# not from static keys in the environment.

The same derivation caveat applies. KMS asymmetric keys sign; they do not derive BIP-32 children. In practice the workable arrangement is a KMS key that encrypts the seed at rest, with the Edge decrypting it at boot into locked memory — which protects the seed on disk and in your backups, and leaves the running process exactly as exposed as mnemonic mode.

Two operational consequences worth planning for:

  • KMS becomes a dependency of Edge start-up. A KMS outage or a revoked grant means the Edge cannot boot. Signing, once booted, does not depend on it in the seed-encryption arrangement — but it does in a sign-per-request arrangement, where a KMS outage stops all withdrawals.
  • Every signature is a billed API call and a network round trip in a sign-per-request arrangement. Budget for the latency as well as the cost.

Azure Key Vault

environment:
EDGE_KEYSTORE: azurekv
EDGE_AZUREKV_VAULT_URL: https://chainos-prod.vault.azure.net/
EDGE_AZUREKV_KEY_NAME: chainos-master
# Managed identity, not a client secret.

Use a Managed HSM vault rather than a software-protected one if the point of the exercise is hardware protection; a standard vault's software keys are protected differently from what an auditor usually means by "HSM". The same derivation caveat applies again.

Choosing

Stay on mnemonic unless one of these is true:

  • Your regulator or your internal policy requires key material in certified hardware, and that requirement is not satisfied by a file at 0400 in a secret manager.
  • Your threat model includes host memory disclosure — a shared or untrusted hypervisor, or a host whose memory you cannot guarantee is not dumped.
  • You already operate an HSM for other purposes, the operational cost is sunk, and it supports BIP-32 derivation.

Do not move to a managed keystore expecting it to solve the backup problem. It does not: whatever holds the master material still has to be backed up, and an HSM's backup procedure is usually harder than a paper mnemonic's, not easier. Read Mnemonic management either way.

Do not move to a managed keystore expecting it to make Ziklag able to help you recover keys. It does not change that at all. Cloud still holds only public keys.

Testing a keystore change

A keystore change must not change a single derived address. Same seed, same paths, same addresses — the keystore is where the arithmetic happens, not what it computes.

# Before: capture what the current Edge derives.
curl -s "$EDGE/addresses?chain=btc&size=5" -H "X-API-Key: $CHAINOS_EDGE_KEY" \
| jq -r '.data.content[] | [.derivationPath, .address] | @tsv' > before.tsv

# Switch the keystore, restart, then compare.
diff before.tsv after.tsv

Any difference means the new keystore is holding different key material, which means it is effectively a mnemonic rotation. Stop and read Identity rotation before going further — Cloud will refuse to derive against the new identity anyway, which is the safety net working as designed.

Do this in sandbox with a sandbox mnemonic first.