How to securely store private keys

How to set up Tatum KMS to manage your keys

Private keys and mnemonics are the only things, which unlock your crypto assets and approves the transactions. When you lose access to them, you will never be able to access your assets. Also, when someone else obtains access to your keys, he can steal all your funds. That's something which you must have in mind to run your business successfully.

NEVER give access to your mnemonics or private keys to anyone. Your private keys should NEVER leave your secure perimeter and should not be sent over the Internet, not even via HTTPS connection. Tatum will never ask for your keys or mnemonics, and you should NEVER send them to the Tatum API.

There are public endpoints on Tatum API, which accept or produce sensitive information like private key or mnemonic. These endpoints are present only for test usages and quick prototyping, not for production usage. For production usage, you should leverage one of the three options:

  • Tatum KMS - Key Management System for your private keys. This tool stores the private keys and mnemonics on your server locally, and signs pending transactions periodically pulled from the Tatum API.

  • Tatum Middleware - Local proxy REST API docker image, which runs on your server and accepts every API request. It forwards non-sensitive API calls (create an account, get block) to the Tatum API and resolves sensitive API calls (generate a wallet, send a transaction) locally. Private keys and mnemonics are part of the HTTP API request but never leaves your perimeter.

  • Local libraries for different programming languages - The library takes care of the sensitive operations locally, usually on your local server where the backend of your application runs.

Tatum KMS is the most secure and advanced tool, so Tatum advises to use KMS. In the next sections, you will see how to set up KMS and how the necessary operations on Tatum API look like leveraging KMS.

How does Tatum KMS work

Tatum KMS stores all your mnemonics and private keys in the wallet store. This store is an AEC encrypted file, for which only you know the encryption key.

Every wallet, which is stored inside your KMS, has a unique identifier, called signatureId. This signatureId is used in communication with Tatum API and represents the wallet used by the specific operation.

When you generate and store all the wallets you want to work with, you then enable the daemon mode on the KMS. This daemon mode periodically checks for the pending transactions to sign.

Every pending transaction has a signatureId present. When the pending transaction is matched with the wallet store's specific wallet, it is signed locally and sent to the blockchain. Your wallet data are stored only in memory.

Set up Tatum KMS

Tatum KMS is a command-line tool and provides two modes of operation:

  • daemon mode responsible for periodically pulling pending transactions from Tatum API

  • CLI mode to generate wallets or private keys

Tatum KMS is shipped as a Node.JS binary, and Node.JS 14+ should be installed on your server.

Your local server
Your local server
npm i -g @tatumio/tatum-kms

Generate your wallets

If you want to generate a wallet, which is managed by KMS, there is a generetemanagedwallet command in the CLI mode.

Your local server
Your local server
tatum-kms generatemanagedwallet BTC
Enter password to access wallet store:*****
{
"signatureId": "014073ce-af80-4f9c-8c7c-653ba5880afb",
"xpub": "xpub6FPGLmppWEemTJ56aq6wcSkjeZN4iEw1CBvQzkusgbJpqyoiPPJASLpbduzKrNF54i348moHyoVGkyz1H2TC3iEPLfacjPFEfTENkD6YzzZ"
}

You need to enter the password, which decrypts your wallet store. For the first time, when the store is empty, you have to set up your new password.

The wallet store is encrypted with an AEC cipher and is stored on your local server. The password you provide is used to encrypt the mnemonics and private keys inside. If you lose your password, you will lose access to your mnemonics.

Enable daemon mode

When you generated all your managed wallets, you need to start the KMS in daemon mode.

Your local server
Your local server
tatum-kms daemon --apiKey YOUR_API_KEY --chain=BTC
Enter password to access wallet store:*****

You need to enter the password for unlocking the wallet store. It is asked whenever you start the daemon. If your daemon stops, you need to enter the password again during the start.

Example usage of the API with the Tatum KMS

Create an account or generate a blockchain address

The result of the generatemanagedwallet is the signatureId and the xpub for the wallet. This xpub can be used in the create account operations or for generating deposit addresses.

Create account
Generate deposit address
Create account
curl --location --request POST 'https://api-eu1.tatum.io/v3/ledger/account' \
--header 'x-api-key: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{
"currency": "BTC",
"xpub": "xpub6FPGLmppWEemTJ56aq6wcSkjeZN4iEw1CBvQzkusgbJpqyoiPPJASLpbduzKrNF54i348moHyoVGkyz1H2TC3iEPLfacjPFEfTENkD6YzzZ"
}'
Generate deposit address
curl --request GET \
--url https://api-eu1.tatum.io/v3/bitcoin/address/xpub6FPGLmppWEemTJ56aq6wcSkjeZN4iEw1CBvQzkusgbJpqyoiPPJASLpbduzKrNF54i348moHyoVGkyz1H2TC3iEPLfacjPFEfTENkD6YzzZ/1 \
--header 'x-api-key: YOUR_API_KEY'

Send Bitcoin transaction

You can send the transaction with the same API endpoint as seen in the guide. The only difference is that instead of the private keys, you enter the signatureId of the wallet you want to use.

Request - List of addresses as a source
Response
Request - List of addresses as a source
curl --location --request POST 'https://api-eu1.tatum.io/v3/bitcoin/transaction' \
--header 'x-api-key: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{
"fromAddress": [
{
"address": "mgSXLa5sJHvBpYTKZ62aW9z2YWQNTJ59Zm",
"signatureId": "014073ce-af80-4f9c-8c7c-653ba5880afb"
}
],
"to": [
{
"address": "mgSXLa5sJHvBpYTKZ62aW9z2YWQNTJ59Zm",
"value": 0.000006
},
{
"address": "mgSXLa5sJHvBpYTKZ62aW9z2YWQNTJ59Zm",
"value": 0.000009
}
]
}'
Response
{
"signatureId": "0fe373ce-af80-4f9c-9412-653ba5880afb"
}

Be aware that when in the request is the private key, you need to enter signatureId of the private key from the wallet store. Private keys can be stored using the storemanagedprivatekey command. You can generate a specific private key from the managed stored wallet using getprivatekey command. When there is a mnemonic, you need to enter the signatureId of the mnemonic from the wallet store.

You can see that nowhere in this request was a private key or mnemonic, or other sensitive information.

But be aware that there is a change of behavior of this operation. The transaction is not yet signed and sent to the blockchain. It is waiting in the Tatum to be processed by the KMS.

When KMS detects a new pending transaction, it signs it locally and sends it to the blockchain. It must also mark the transaction as processed, so it will not be sent to the blockchain again.‌

This process is the same for every other send transaction method for every blockchain. The process is a little bit complicated from the start but provides you with the best security available.

Tatum KMS also supports integrations to Azure Key Vault or VGS so that you can store your secrets there. More information can be found on the Tatum KMS GitHub pages, where are all the source codes available.