Back to all posts
TMKMS setup for XRPL validator Guide
XRPL EVM
XRPL EVM
Guide

TMKMS setup for XRPL validator Guide

June 23, 2025
19 min read

Table of Contents

  1. Introduction

    • Importance of secure key management for validators

    • How it works and practical examples

    • Overview of Tendermint Key Management System

  2. System Requirements for TMKMS Setup

    • Minimum software requirements for setting up TMKMS

  3. TMKMS Setup

    • Step-by-step guide to setting up TMKMS on a server

    • Basic steps to improve security settings when using TMKMS

  4. Alternative Options

Introduction

Importance of secure key management for validators.

Managing private keys is critical for the operation of a validator. These keys are responsible for signing and validating blocks in the network. Therefore, they require a proper level of protection and management.

If attackers gain access to the private keys, it could lead to serious threats, such as network consensus violations, double signing, and more.

Secure storage and handling of keys are not only important to protect against hacking but also to prevent missing signed blocks, double signing, which could result in penalties and other consequences.

A private key stored directly on the validator node is much more vulnerable than one stored separately. For instance, during technical failures of the server, migration of the validator to another server, or careless synchronization without the current priv_validator_state.json file (which contains information about previously signed blocks), the validator may inadvertently perform a double sign of the same block.

In the case of using TMKMS, your private key is separated from the node, significantly reducing the risks. You perform minimal operations with the key, and it remains secure at all times, even during node restoration or synchronization. Additionally, the current signed blocks are stored, ensuring the correct and secure signing of transactions. In the event of a failure, it will be enough to redirect the TCP connection to a backup node, allowing for a quick recovery without compromising security.

How it works and practical examples:

  1. By using TMKMS, when the validator stops working, your private keys remain secure on the TMKMS server. In this case, it is enough to simply redirect the TCP connection from TMKMS to the Backup Validator Node, and the block signing will automatically resume - without losing participation in the consensus and without the risk of being slashed.

Uploaded image

  1. In the event that the TMKMS server stops working, the situation becomes more complicated because you lose access to the current file for signing blocks with your validator. In this case, you need to redirect the requests to a fully synchronized node that has the current state with the network to restore block signing and ensure the continuous operation of the validator.

Uploaded image

For stable architecture operation, it is crucial to adhere to basic security principles: firewall, fail2ban, SSH keys, VPN or sentry-node, monitoring, port access restrictions, and creating users with defined permissions.

Equally important is having supporting infrastructure - RPC, seed nodes, snapshot servers - so that the validator can quickly resume operation after failures. It is also recommended to use reliable server providers and distribute infrastructure across different data centers and countries, which increases resilience to regional failures and contributes to the decentralization of the network.

Automation, for example, through Ansible, reduces the risk of errors and simplifies the management of the entire system.

Overview of Tendermint Key Management System

Tendermint Key Management System (TMKMS) is a solution for securely managing the private keys required for signing blocks in networks running on Tendermint. TMKMS separates key management from the validation process, which significantly enhances the security of validators and reduces the risk of key compromise.

Initially developed by the Cosmos team, it is currently maintained by Iqlusioninc.

Key features:

  • Separation of validator keys onto a separate server or HSM (Hardware Security Module)

  • Remote key storage using HSMs (hardware security modules)

  • Remote signing of transactions through TCP connections

  • Simple switching of validator operation to another server in case of failures

Storage and Signing Support:

  • Soft-sign: This is a software-based signing method where transactions are signed using a standard private key. Compared to the absence of TMKMS, this approach offers the advantage of double protection and storing keys on separate servers, providing additional security.

  • Hardware Security Modules (HSM): Devices such as Ledger Nano S and YubiHSM use hardware-based signing, allowing transactions to be signed without exposing private keys. While this method is more secure, it requires physical access to the server for the use of HSM devices.

In this example, it is configured to use soft-sign on a dedicated server, though there are even more secure options available with hardware security modules (HSM).

Minimum Software Requirements for TMKMS Setup

Operating Systems:

  • Linux (recommended) with x86_64 processor architecture

As an example, we use the following available servers with the following specifications:

  • TMKMS - 2 CPU / 8GB RAM / 100GB Storage

  • Validator Node - 8 Cores, 32GB RAM, 1TB of storage (NVME)

Software Dependencies:

  • Rust (version 1.72 or newer): https://rustup.rs/

  • C compiler: such as gcc or clang

  • pkg-config

  • libusb (version 1.0 or newer) github.com

  • NOTE (x86_64 only): Configure the RUSTFLAGS environment variable:

    export RUSTFLAGS=-Ctarget-feature=+aes,+ssse3

Supported Signing Algorithms:

  • Ed25519: TMKMS supports signing transactions only using Ed25519, which is also used in XRPL.

  • secp256k1: The secp256k1 algorithm is not supported in TMKMS.

TMKMS Setup

Basic Steps to Improve Security Settings When Using TMKMS

  1. Firewall Configuration

The TMKMS server should have a firewall that blocks all ports except for the SSH port. It is recommended to use a non-standard port for SSH, but in this example, we use port 22.

sudo ufw allow 22 ssh
sudo ufw enable

To allow access to the TMKMS ports, the UFW firewall should be configured to allow connections from specific IP addresses to the required port (e.g., port 26658). Here’s how you can do it:

sudo ufw allow from <IP TMKMS> proto tcp to any port 26658  # For the primary TMKMS server
sudo ufw allow from <IP Backup TMKMS> proto tcp to any port 26658  # For the backup TMKMS server

You can additionally configure:

  • Firewall, fail2ban, SSH keys, VPN or sentry-node, monitoring, port access restrictions, and creating users with defined permissions.

Suggested Steps:

  • Create a user with restricted access permissions

  • Fail2ban

  • SSH access via SSH keys

  • Server monitoring, for example, collecting metrics via node_exporter

  • Stunnel / VPN / Sentry node

  • Regularly update the system

  • Logging (e.g., using Loki)

Step-by-Step Guide for TMKMS Setup on the Server

  1. Install Rust

    sudo apt install rustc curl build-essential gcc make
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    source $HOME/.cargo/env
  2. Install TMKMS

    git clone https://github.com/iqlusioninc/tmkms.git 
    cd tmkms
    cargo build --release --features=softsign
    cargo install tmkms --features=softsign
    tmkms version
  3. Move the private key to the TMKMS server.

    Move your priv_validator_key.json to the TMKMS server for validator import, for example, we moved it to $HOME.

  4. Create a directory for the network and initialize TMKMS for it:

    mkdir -p $HOME/tmkms/xrpl-tesnet
    tmkms init $HOME/tmkms/xrpl-testnet

    It will return:

    Generated KMS configuration: /home/user/tmkms/xrpl-testnet/tmkms.toml
    Generated Secret Connection key: /home/user/tmkms/xrpl-testnet/secrets/kms-identity.key
  5. Import the private key into the folder

    tmkms softsign import $HOME/priv_validator_key.json $HOME/tmkms/xrpl-testnet/secrets/xrpl-testnet-validator.key

It will return:

INFO tmkms::commands::softsign::import: Ipmorted Ed25519 private key to /home/user/tmkms/xrpl-testnet/secrets/xrpl-testnet-validator.key

  1. Save and delete the original priv_validator_key.json file.

    Make sure you have a backup of your key before entering the next command.

    Removing the private key

    sudo shred -uvz $HOME/priv_validator_key.json
  2. Edit the configuration file $HOME/tmkms/xrpl-testnet/tmkms.toml

    Depending on your settings, modify the following:

    • chain id: Ensure the chain ID is up to date.

    • Path to state_file: Specifies the state file of your validator, typically located in the directory related to your specific test or network.

    • Path to path: Specifies the signing key used by TMKMS.

    • Path to secret_key: Specifies the secret key used for network connection and authentication.

    • Port 26658: Replace with another port if it has been changed.

    sudo tee $HOME/tmkms/xrpl-testnet/tmkms.toml > /dev/null <<EOF
    # Chain Configuration
    [[chain]]
    id = "xrplevm_1449000-1"
    key_format = { type = "bech32", account_key_prefix = "ethm", consensus_key_prefix = "ethmvalconspub" }
    state_file = "/home/user/tmkms/xrpl-testnet/state/xrpl-testnet-state.json" 
    # Software-based Signer
    [[providers.softsign]]
    chain_ids = ["xrplevm_1449000-1"]
    key_type = "consensus"
    path = "/home/user/tmkms/xrpl-testnet/secrets/xrpl-testnet-validator.key" 
    # Validator Configuration
    [[validator]]
    chain_id = "xrplevm_1449000-1"
    addr = "tcp://<VALIDATOR_IP>:26658" 
    secret_key = "/home/user/tmkms/xrpl-testnet/secrets/kms-identity.key" 
    protocol_version = "v0.34"
    reconnect = true
    EOF
  3. SystemD configuration

    Prepare the necessary commands to use TMKMS as a service
    Create the service file xrpl-testnet.service
    sudo tee /etc/systemd/system/xrpl-testnet.service << EOF
    [Unit]
    Description=xrpl-testnet
    After=network.target
    StartLimitIntervalSec=0
    [Service]
    Type=simple
    Restart=always
    RestartSec=10
    User=$USER
    ExecStart=$(which tmkms) start -c $HOME/tmkms/xrpl-testnet/tmkms.toml
    LimitNOFILE=1024
    [Install]
    WantedBy=multi-user.target
    EOF

Restart systemd, activate the xrpl-testnet.service, start the service and check its status:

Make sure that before the next step, you have specified the correct IP address of the validator server in the configuration file, not the backup nodes, etc., where it is currently running and signing blocks.

Restart Systemd service

sudo systemctl daemon-reload
sudo systemctl enable xrpl-testnet.service
sudo systemctl start xrpl-testnet.service
sudo systemctl status xrpl-testnet.service

You will see the following logs

2025-06-19T22:00:37.270809Z ERROR tmkms::client: [xrpl-testnet-2@tcp://<YOUR_IP>:20658] I/O error: Connection refused (os error 111)
2025-06-19T22:00:38.270988Z  INFO tmkms::connection::tcp: KMS node ID: 041e7bf02849297e2212d2810880e10cbce37bce
2025-06-19T22:00:38.271406Z ERROR tmkms::client: [xrpl-testnet-2@tcp://<YOUR_IP>:20658] I/O error: Connection refused (os error 111)
2025-06-19T22:00:39.271594Z  INFO tmkms::connection::tcp: KMS node ID: 041e7bf02849297e2212d2810880e10cbce37bce
2025-06-19T22:00:39.271989Z ERROR tmkms::client: [xrpl-testnet-2@tcp://<YOUR_IP>:20658] I/O error: Connection refused (os error 111)
2025-06-19T22:00:40.272186Z  INFO tmkms::connection::tcp: KMS node ID: 041e7bf02849297e2422d2810880e10cbce37bce

These logs mean that TMKMS is attempting to connect to your validator at the address IP:PORT:20658. However, your node is currently not configured to accept connections on this port.

If priv_validator_laddr in $HOME/.exprd/config/config.tomlis correctly configured and the port is open, once you configure the node, TMKMS will be able to connect without any additional settings from your side.

Configuring the Validator Node

Currently, we will perform the following setup:

  1. Edit the validator node's configuration file config.toml

    nano $HOME/.exprd/config/config.toml

    Find the following section of the code:

    Uploaded image
  2. Comment out priv_validator_state.file and priv_validator_key.file.

  3. In priv_validator_laddr, enter the following value:

    sudo systemctl restart exprd
  4. Restart the validator node to apply the changes.

    sudo systemctl restart exprd

  5. Check the log journal of the TMKMS service.

    sudo journalctl -u exprd -f -o cat
    You will see logs similar to the following:
    2025-06-19T22:03:08.827961Z  INFO tmkms::keyring: [keyring:softsign] added consensus Ed25519 key: your_valcons
    2025-06-19T22:03:08.828110Z  INFO tmkms::connection::tcp: KMS node ID: 041e7bf02849297e2412d28108a0e10cbce37bce
    2025-06-19T22:03:08.829344Z  INFO tmkms::session: [xrpl-testnet-2@tcp://<YOUR_IP>:26658] connected to validator successfully
    2025-06-19T22:03:08.829353Z  WARN tmkms::session: [xrpl-testnet-2@tcp://<YOUR_IP>:26658]: unverified validator peer ID! (40d737fc9519a8e37653cd47c8db08d96830c12a)
    2025-06-19T22:03:08.830348Z  INFO tmkms::session: [xrpl-testnet-2@tcp://<YOUR_IP>:26658] signed Prevote:7D1E173545 at h/r/s 3384376/0/1 (0 ms)
    2025-06-19T22:03:08.853571Z  INFO tmkms::session: [xrpl-testnet-2@tcp://<YOUR_IP>:26658] signed Precommit:7D1E173545 at h/r/s 3384376/0/2 (0 ms)

Congratulations, your validator is remotely signing transactions from a separate server.

Alternative Options

You can also use Horcrux - a multi-party computation (MPC) signing service.