Skip to main content
The platform is designed so that the public API, the database and any individual signing node are each insufficient on their own to move funds. Security comes from several independent boundaries, each of which has to be crossed for a transaction to happen.

The boundaries

Threat model, plainly

The wallet’s private key is never stored as a whole. It is generated as separate shares by distributed key generation and used only through an interactive threshold protocol.
  • Compromise of one signing node, one cloud account, one Kubernetes namespace, one node identity or one local share store is not enough to sign.
  • Compromise of the API, or of the control-plane database, is not enough to sign: neither holds key material.
  • A stolen API key is limited to its scopes and bound wallets, and cannot change policy, approve its own requests, rotate secrets or disable controls.
  • An attacker who controls enough nodes to meet the threshold, or obtains enough encrypted shares together with their passphrases, has crossed the custody boundary. The design makes that require several independent failures across different systems and administrative domains, not one successful intrusion.
Threshold cryptography does not remove operational risk; it changes what an attacker has to achieve. The controls around it (policy, approvals, limits, the kill switch and the audit trail) are what make the boundary usable day to day.

Automation is separate from governance

Server-to-server API keys are for the flows an application should run on its own: creating wallets, attaching assets, reading balances and history, requesting withdrawals within policy. Changing the rules is a different trust domain. Policy and approval-group changes, approving or rejecting a request, member and role changes, and freezing withdrawals are done by people in the console under their own session. A static credential cannot quietly become a superuser.

Everything is written down first

Before the platform publishes a key-generation request, it records the wallet operation. Before it publishes a signing request, it records the withdrawal and the signing request. Before it broadcasts, it records the signed transaction and its expected hash. Duplicate requests resolve to the existing operation, a late result cannot revive a failed one, and every state transition and sensitive action is available in the audit trail. An incident can be traced from request ID to wallet, withdrawal, signing request and transaction hash.

Chain truth is reconciled, not assumed

A withdrawal is not final because a transaction was broadcast. It becomes final when the receipt has reached the configured confirmation depth. Balances come from chain-observed state written by the scanner, which handles reorganisations by marking affected deposits failed and rescanning. A stale scanner never silently zeroes a balance.

Emergency stop

A workspace admin can freeze all withdrawals in the workspace from the console, with a reason recorded in the audit trail. While frozen, withdrawal requests are rejected. The check fails closed: if the platform cannot read the freeze state, it blocks the withdrawal.