MPC secret storage
Split a secret's DEK across parties so no single holder can reconstruct it.
MPC splits each secret's DEK into shares so one compromised holder cannot decrypt. It layers on top of the standard HSM envelope encryption and is set per vault. The custody mode is immutable once set.
- 2of2_client_custody: XOR split between the server HSM and you; you hold a client_share
- 2of3_multi_hsm: Shamir 2-of-3 across GCP, AWS, and Azure; no client share
- 2of3_client_custody: Shamir 2-of-3 with two HSMs plus your client share
For client-custody modes, store the client_share safely. Lose it on a 2of2_client_custody vault and the secret cannot be recovered, because the server holds only its single share.
Create a dedicated vault for MPC testing; custody mode cannot be changed after it is set.
Requires a Pro or higher plan. Custody mode is also immutable once set on a vault, so create a throwaway vault to experiment with rather than deciding on a real one.
- 1
Export your API key and vault ID. Use your vault UUID from
1claw vault listor Foundations.bashexport ONECLAW_API_KEY="1ck_your_key_here" export VAULT_ID="your-vault-uuid" - 2
Exchange your API key for a bearer token.
bashexport TOKEN=$(curl -s -X POST https://api.1claw.co/v1/auth/api-key-token \ -H "Content-Type: application/json" \ -d "{\"api_key\":\"$ONECLAW_API_KEY\"}" | jq -r .access_token) - 3
Enable MPC with XOR client custody. This choice is permanent for the vault.
bashcurl -s -X POST https://api.1claw.co/v1/vaults/$VAULT_ID/mpc \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"custody_mode":"2of2_client_custody"}' - 4
Write a secret. The PUT response includes a base64 client_share you must keep. Capture it from the response.
bashRESPONSE=$(curl -s -X PUT https://api.1claw.co/v1/vaults/$VAULT_ID/secrets/api-keys/stripe \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"value":"sk_live_abc123","type":"api_key"}') CLIENT_SHARE=$(echo "$RESPONSE" | jq -r .client_share) echo "Save this client_share permanently: $CLIENT_SHARE" - 5
Read it back by sending your share in X-Client-Share. Without the header the read fails.
bashcurl -s https://api.1claw.co/v1/vaults/$VAULT_ID/secrets/api-keys/stripe \ -H "Authorization: Bearer $TOKEN" \ -H "X-Client-Share: $CLIENT_SHARE"
The vault now returns a client_share on write and requires it on read, so 1Claw alone cannot reconstruct the DEK.
Where this goes wrong in practice. Threshold schemes are mathematically sound and operationally demanding, and the gap between those two is where incidents live.
- Custody mode is immutable, and it is chosen early. The decision is made during a spike, by whoever is setting up the vault, usually before anyone has thought about who will hold a share in a year.
- The client share has no owner. A share held by "the team" is held by nobody. It needs a named custodian, a documented location, and a successor.
- The X-Client-Share header is forgotten in one path. Client-custody modes require it on every read, and the service that was written last, or by a different team, is the one that discovers this in production.
- Availability is confused with security. 2-of-3 tolerates losing one share; 2-of-2 tolerates nothing. Teams pick 2-of-2 for its stronger trust property and discover the availability cost during an incident.
Before enabling a client-custody mode, write down who holds the share, where, and who takes over if they leave. If that is hard to answer, choose multi-HSM instead: a weaker trust assumption you can operate beats a stronger one you cannot.
Decide
You are choosing a custody mode for a vault holding the signing material behind a treasury that moves large sums. The team is small and operationally inexperienced, and there is no formal key-escrow process.
Which mode fits, and why?
Check your understanding
3 questionsWhich mode returns a client_share and needs X-Client-Share on reads?
Can a vault's MPC custody mode be changed after it is set?
Where are the shares stored in 2of3_multi_hsm?