Security architecture
This page explains key storage locations, key material transfer processes, safeguards for each key operation, and key pair management procedures.
Self-custody wallets ensure a customer's key material is exposed only in two locations: the BVNK vault enclave and the customer's device.
Three principles protect customer keys:
Keys live in a secure enclave
Private keys are generated, stored, and used to sign outgoing payments inside an AWS Nitro Enclave, a type of trusted execution environment (TEE).
Plaintext never reaches the BVNK API or your platform
Key material leaves the enclave only in encrypted form. During export, the enclave encrypts the seed phrase, and only the customer's device can decrypt it.
You retain control
BVNK cannot independently move customer funds. Every transaction requires an authenticated instruction from your platform.
A TEE runs code in an environment isolated from the rest of the system: code and data inside it cannot be read or changed from outside, even by administrators of the host machine. A Nitro Enclave has no persistent storage, no external network access, and no way to sign in to it. It communicates only with its parent instance through a secure local channel. For more information, see the AWS Nitro Enclaves documentation.
Protecting key material
Key protection relies on the following components:
- HD master key: each customer has one HD master key, a BIP39 seed phrase from which all of the customer's self-custody wallet addresses are derived using BIP44 derivation paths. The master key controls the funds in all of these wallets. BVNK provisions it when you create the customer's first self-custody wallet.
- Hardware vault enclave: BVNK stores the master key inside a hardware vault enclave and signs outgoing payments there, so the key is never exposed to sign a transaction. Plaintext key material never leaves the enclave. Exporting the key gives the customer their own copy.
- Data transit key: an RSA key pair that belongs to the vault. You use its public key to encrypt key material before sending it to BVNK. The public key is tenant-wide and long-lived.
- Client-side AES key: a random AES-256 key generated on the customer's device for export and import. Only the customer's device and the vault can read it.
- Credential safeguards: export is available only to API credentials that have an IP allowlist.
How key export works
When a customer exports their seed phrase, their device generates an AES key and sends it to the vault enclave in encrypted form. The enclave uses that key to encrypt the seed phrase, which is returned as ciphertext and decrypted locally on the customer's device. Neither the BVNK API nor your platform receives the plaintext seed phrase or the unwrapped AES key.
Import follows the same path in the opposite direction: the customer's device encrypts the seed phrase, and only the vault enclave can decrypt it.
Each party has access to different levels of key material:
- Customer's device: generates the AES key and decrypts the exported mnemonic. This is the only location outside the vault where key material is in plaintext.
- Your platform: relays the data transit public key and encrypted payloads between the customer's device and BVNK. It cannot decrypt these payloads.
- BVNK API: authenticates your API credential and rejects export requests that do not meet the export safeguards.
- Hardware vault enclave: stores the master key and data transit private key, unwraps your AES key, and encrypts or decrypts the mnemonic.
Envelope encryption
The seed phrase is never transmitted in plaintext. Both export and import use hybrid envelope encryption, implemented in three steps:
-
Fetch the data transit key once via
belonging to the vault. The key is tenant-wide and long-lived, so you can fetch it once and reuse it for every customer and every operation.GET /ledger/v2/data-transit-key. It returns an RSA public key -
Generate a random AES-256 key on the customer's device, then RSA-OAEP
wrap it with the transit public key. The wrapped result is theencryptedSecretyou send on the request. -
AES-GCM encrypt the mnemonic under that same AES key. The result is the
encryptedMnemonic(containing anivGCM nonce anddataciphertext with an authentication tag).
The RSA key does not encrypt the mnemonic directly; it only wraps the AES key. During export, the vault re-encrypts the mnemonic with your AES key and returns the encryptedMnemonic for local decryption. During import, the vault unwraps your AES key and decrypts the mnemonic within the enclave.
Fetch the data transit key
Before you can export or import a key pair, fetch the vault's RSA public key by sending the GET /ledger/v2/data-transit-key request. No parameters are required.
Use the publicKey to RSA-OAEP wrap your AES-256 key. The algorithm field confirms the expected wrapping algorithm.
Operation safeguards
Operations that expose, import, or remove the master key require additional safeguards.
Export and import
Export requires an IP allowlist: the credential must have allowedIps configured. Export from a credential with no IP allowlist is refused.
Each customer has one master key, so import depends on whether the customer already has one:
- No key: the import completes immediately.
- Existing key in any status other than
DELETED: the import request returns an error. To import, delete the existing key first, wait for the 7-day retention window to end and the key to reachDELETED, and then import. Deleting the key terminates its derived wallets, so review the deletion safeguards before you start.
Creating a customer's first self-custody wallet provisions a master key automatically. If the customer wants to use their own mnemonic, import it before you create any wallet for them. Otherwise, the import is blocked until the key BVNK created is deleted.
Deletion
Deletion is a complete removal, not a rotation. It deletes the key from the vault and terminates all derived wallets. Creating a new self-custody wallet later will automatically provision a new key.
Key behaviors:
- Export required first: BVNK will not delete a key unless it has been exported. Export the key, verify mnemonic decryption, and then proceed with deletion.
- Non-zero balances allowed: Unlike custodial wallet termination, self-custody deletion proceeds even if funds remain on chain. These funds remain accessible with the exported seed phrase, but BVNK will no longer track them.
Manage key pairs
Use the following endpoints to manage the key pair's lifecycle.
List
To find the key pair identifier for a customer, send the GET /ledger/v2/key-pairs request with the customerId query parameter.
The response is an array containing at most one entry, as each customer has a single master key. An empty array indicates the customer does not yet have a key, which is the default until the first self-custody wallet is created. If deletion has been requested, the entry also includes scheduledDeletionAt. No key material is returned.
Export
Exporting the key gives the customer independent control of their funds and provides a backup in case of access loss. After decryption, the customer can import the mnemonic into standard wallet software, such as MetaMask or Trust Wallet, to manage or recover funds outside BVNK.
To export the customer's seed phrase, send the POST /ledger/v2/key-pairs/{keyPairId}/actions request with type set to EXPORT. The credential must meet the export safeguards.
{
"type": "EXPORT",
"encryptedSecret": "iN4mZ0k2R1pQ..."
}
encryptedSecret is your AES key, wrapped with RSA-OAEP using the data transit key. The vault re-encrypts the mnemonic with your AES key, ensuring only you can decrypt it.
{
"encryptedMnemonic": {
"iv": "5Kq2Vt8xZ0mA1pRs",
"data": "9dQm2Xk7Lp0aZr4tYv6NcB1e..."
},
"derivedKeys": [
{
"derivationPath": "m/44'/60'/0'/0/0",
"publicKey": "0x04a1b2c3..."
},
{
"derivationPath": "m/44'/195'/0'/0/0",
"publicKey": "0x0498f7e6..."
}
]
}
Decrypt encryptedMnemonic locally with the AES key you wrapped in encryptedSecret to obtain the BIP39 mnemonic. The derivedKeys array lists all derivations registered under the master key, allowing you to reconstruct the same addresses in your wallet software.
Re-exporting is safe, as the seed remains unchanged.
Import
To import an existing mnemonic for a customer, send the POST /ledger/v2/key-pairs request with the customer's encrypted mnemonic. The import succeeds only if the customer has no key, or their previous key is DELETED. See import requirements.
{
"customerId": "d7344ac6-523b-49ef-9662-007433c8d526",
"type": "HD",
"encryptedSecret": "iN4mZ0k2R1pQ...",
"encryptedMnemonic": {
"iv": "5Kq2Vt8xZ0mA1pRs",
"data": "9dQm2Xk7Lp0aZr4tYv6NcB1e..."
}
}
{
"id": "0198e2b4-7c31-7000-8000-2f9c1d4a5b60",
"type": "HD",
"status": "ACTIVE"
}
BVNK derives the standard set of addresses (index 0 for each supported network). Funds on non-standard derivation paths or higher indices will not be detected.
Delete
To delete a customer's key pair, send the POST /ledger/v2/key-pairs/{keyPairId}/actions request with type set to DELETE. Review the deletion safeguards before proceeding.
{
"type": "DELETE"
}
{
"id": "0198e2b4-7c31-7000-8000-2f9c1d4a5b60",
"type": "HD",
"status": "PENDING_DELETION",
"scheduledDeletionAt": "2026-09-16T08:34:30.289967Z"
}
Deletion includes a 7-day retention window. During this period, the key remains in PENDING_DELETION and can be reinstated. After scheduledDeletionAt, the key moves to DELETING while BVNK removes the key from the vault and archives its derived wallets. If an error occurs during this process, BVNK retries automatically until it completes. Once the deletion completes, the key transitions to DELETED and cannot be recovered.
Cancel deletion
To reverse a scheduled deletion while the key is still in PENDING_DELETION, send the POST /ledger/v2/key-pairs/{keyPairId}/actions request with type set to CANCEL_DELETION.
{
"type": "CANCEL_DELETION"
}
{
"id": "0198e2b4-7c31-7000-8000-2f9c1d4a5b60",
"type": "HD",
"status": "ACTIVE"
}
The key returns to ACTIVE status, and all derived wallets continue to operate.
You can cancel a deletion only while the key is in PENDING_DELETION. Once the retention window ends and the key moves to DELETING, the deletion can no longer be cancelled, even if BVNK is still retrying it.
Partner and customer responsibilities
The architecture keeps key material encrypted in transit, but its security also depends on how your platform and customers manage it.
Your platform:
- Generate the AES key on the customer's device: this ensures your platform relays only ciphertext it cannot decrypt.
- Do not store the decrypted mnemonic: never persist the decrypted mnemonic on your backend systems.
- Configure export credentials: set
allowedIpson the credential used for export. - Import before creating wallets: if a customer wants to use their own mnemonic, import it before you create their first self-custody wallet.
- Protect funds before deletion: export the key and verify decryption before deleting it.
Your customers:
- Keep the exported seed phrase secure: anyone with the seed phrase can access funds on all derived addresses.
- Retain the seed phrase after deletion: after key deletion, BVNK no longer tracks funds on its addresses. The exported seed phrase is the only way to access these funds.