Hushxima
Marketplace

Security

How private keys are stored, where the decryption key lives, and the two moments a key exists in plaintext.

Selling wallets means holding their private keys until you take delivery. This page explains what happens to them in the meantime.

Keys are encrypted at rest

No private key is ever written to the database in plaintext. Each one is encrypted with AES-256-GCM, an authenticated cipher, under a fresh random nonce. Authenticated means tampering with a stored ciphertext makes decryption fail rather than silently return altered bytes.

The encryption key set is versioned. Every ciphertext records which version produced it, so a key can be rotated without touching what is already stored: new writes use the new version, older records keep decrypting under theirs.

What a database dump gives an attacker is a pile of ciphertexts and nothing to open them with.

The decryption key is not in the database, or the image, or the repository

The key material comes from a secrets vault that runs on separate infrastructure, and it is injected into the runtime environment at build time. It is never committed, never written to disk by the application, and never stored alongside the data it protects.

The service itself runs as a container on a container-as-a-service platform, which means the runtime is disposable and holds no durable state of its own.

The point of separating the two is what it costs an attacker. Compromising the container, or walking away with the database, gets you encrypted material. Decrypting it needs the key, and the key lives somewhere else. One breach is not enough.

Two moments in plaintext

A key exists in plaintext for as long as the operation using it, and there are only two operations that need one.

Signing a transaction. Funding a wallet, sweeping a deposit, moving money on chain. The key is decrypted, the transaction is signed, the plaintext is dropped.

Delivering the key to you. Once an order has settled, GET /quote/{id}/keys and GET /wallets/{id}/key decrypt on the way out. Before settlement, neither will do it: the delivery endpoint refuses outright on a quote that is not settled.

Nothing else reads a key. There is no background job that walks the table in plaintext, no cache of decrypted material, no export.

Decrypted keys are held in a wrapper type that zeroes its memory when it goes out of scope and refuses to print itself, so a key cannot end up in a log line or a stack trace by accident. Error reporting runs with personally identifiable information disabled at the SDK level, specifically because this service handles key material.

Memory is flushed daily

On top of the above, the backend is restarted every day. Anything that lingered in process memory goes with it.

This is a deliberate backstop rather than the primary control. The primary controls are the ones above: keys spend as little time decrypted as possible, and the memory holding them is zeroed on release. The restart limits how long a hypothetical failure of either could be worth exploiting.

You can have us forget the keys entirely

If you would rather we did not hold them at all past delivery, key retention can be switched on for your organisation. We then purge the private keys of the wallets you buy a set number of minutes after the sale. After that window the API returns private_key_hex: null with a purged_at timestamp, because there is genuinely nothing left to return.

This is off by default, and it is one-way. Once a key is purged we cannot recover it, and neither can anyone else. Turn it on when your own custody is in place, not before. See Wallets & keys for how it shows up in responses.

What is on your side

Once a key reaches you, it is yours to protect, and nothing above applies any more.

Two things worth getting right. Fetch keys server-side rather than from a browser, so they never touch a device you do not control. And treat your API keys the same way you treat the wallet keys: an organisation key is a bearer credential, it is shown exactly once at creation, and revoking it is immediate if one leaks.

Beyond that, the usual practices for a service that custodies key material apply here: least privilege on who can reach the admin surface, a second factor required for platform staff, an audit trail on sensitive actions, and step-up verification before anything that reveals a key or moves customer funds.

Last updated on

On this page