What is a policy?#
Every TrustVault wallet has a policy — a set of rules that determines which keys must sign before a transaction or policy change can be executed. The policy is enforced by the TrustVault HSM and cannot be bypassed.Delegate schedules — govern who can authorise transactions
Recoverer schedules (aka admin schedules) — govern who can change the policy itself (key rotation, recovery). Recoverer keys cannot authorise transactions.
Policy structure#
Policies are composed of schedules, clauses, and keys:Policy
├── delegateSchedules: Schedule[] (OR'd)
└── recovererSchedules: Schedule[] (OR'd)
└── Schedule: Clause[] (AND'd)
└── Clause
├── keys: string[] (public keys)
└── quorumCount: int (min signatures required)
Both delegate and recoverer schedules use the same structure.Clauses are AND'd within a schedule — all clauses must be satisfied.
Schedules are OR'd — any single satisfied schedule activates the policy.Example: 1-of-2 OR CEO approval#
{
"delegateSchedules": [
[
{ "keys": ["04aa...", "04bb..."], "quorumCount": 1 }
],
[
{ "keys": ["04cc..."], "quorumCount": 1 }
]
]
}
Either one of the first two keys signs, OR the CEO key signs.Example: 1-of-2 AND compliance key#
{
"delegateSchedules": [
[
{ "keys": ["04aa...", "04bb..."], "quorumCount": 1 },
{ "keys": ["04cc..."], "quorumCount": 1 }
]
]
}
One of the two ops keys and the compliance key must both sign.Instruction Key#
The Instruction Key is the private key corresponding to a public key in the delegate schedule. It is what you (or the iOS app) use to sign transactions.Keys must be on the secp256r1 (P-256) curve — not secp256k1 (the Bitcoin/Ethereum curve). Public keys are uncompressed hex, 130 characters, prefixed 04.Changing a policy#
Policy changes are approved by the wallet admins (recoverers) only. Delegates cannot approve a policy change. By default (includeBitpandaAdmins: true) Bitpanda Custody admins are included as recoverers, so Bitpanda Custody also signs.There are two types of Policy Change Request: RECOVERY and a special type called ZERO.A ZERO request removes every delegate from a wallet without needing any signatures, so you can lock a wallet down straight away in an emergency.To replace or rotate an Instruction Key:1.
Create a new key pair (on secp256r1)
2.
Call createChangePolicyRequest with the new delegate schedule
3.
Sign the shaSignData with the required recoverer (admin) keys
4.
Wait for Bitpanda Custody to co-sign
Signing a transaction#
When a transaction is created, TrustVault returns unverifiedDigestData:| Field | Description |
|---|
transactionDigest | The raw chain-specific digest (e.g. keccak(rlp(tx)) for Ethereum) |
signData | The digest with the HD wallet path appended in DER format |
shaSignData | SHA-256(signData) — what you sign with your key |
Policy change requests return only signData and shaSignData (there is no transactionDigest).In production, recreate the digests from your original inputs and verify they match unverifiedDigestData before signing. Do not blindly sign shaSignData without verification — use the SDK's built-in verify methods or implement your own. See Create an Ethereum Transaction for details. TCSS destination allowlisting#
The Transaction Co-Signing Service (TCSS) runs after your Instruction Key has signed. If your wallet has an Address Book attached, TCSS will reject any transaction to an address not in the book — regardless of whether the delegate key signed it.Further reading#
Modified at 2026-10-29 12:46:11