The Tendermint Key Management System (or TMKMS) should be used by any validator currently or intending to be in the active validator set. This application mitigates the risk of double-signing and provides high-availability to validator keys while keeping these keys on a separate physical host. While TMKMS can be used on the same machine as the validator, it is recommended to be on a separate host.


Let's look at an example - Canto

Create new user (from root)

adduser tmkms
usermod -aG sudo tmkms
su tmkms
cd $HOME

Install RUST

curl --proto '=https' --tlsv1.3 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
#Install GCC
sudo apt update & sudo apt install build-essential curl jq  --yes

Compile and sort TMKMS binaries

cd $HOME
cargo install tmkms --features=softsign
sudo mv $HOME/.cargo/bin/tmkms /usr/local/bin/

Create and Init TKMS working directory

mkdir -p $HOME/tmkms/canto
tmkms init $HOME/tmkms/canto

Import Private key

  • Upload your validator priv_validator_key.json to directory /home/tmkms/priv_validator_key.json

Then check availablity

cat $HOME/priv_validator_key.json

If right output is appeared, follow next step below

tmkms softsign import $HOME/priv_validator_key.json $HOME/tmkms/canto/secrets/canto-consensus.key

Now we can erase copy of original file

sudo shred -uvz $HOME/priv_validator_key.json
  • Swap tmkms.toml to the one below. The only "addr =" field edit need to be done, replace it with your validator node IP + port(26658 default)

rm -rf ~/tmkms/canto/tmkms.toml
tee ~/tmkms/canto/tmkms.toml << EOF
#Tendermint KMS configuration file
id = "canto_7700-1"
key_format = { type = "bech32", account_key_prefix = "cantopub", consensus_key_prefix = "cantovalcons" }
state_file = "$HOME/tmkms/canto/state/canto_7700-1_priv_validator_state.json"
#Software-based Signer Configuration
chain_ids = ["canto_7700-1"]
key_type = "consensus"
path = "$HOME/tmkms/canto/secrets/canto-consensus.key"
#Validator Configuration
chain_id = "canto_7700-1"
addr = "tcp://" #Set here IP and port of the canto node U will be using for signing blocks (port can be custom)   
secret_key = "$HOME/tmkms/canto/secrets/kms-identity.key"
protocol_version = "v0.34"
reconnect = true

Create service file and run TMKMS

sudo tee /etc/systemd/system/tmkmsd-canto.service << EOF
ExecStart=$(which tmkms) start -c $HOME/tmkms/canto/tmkms.toml


sudo systemctl daemon-reload
sudo systemctl enable tmkmsd-canto.service
sudo systemctl restart tmkmsd-canto.service
sudo systemctl status tmkmsd-canto.service
sudo journalctl -fu tmkmsd-canto.service -o cat
  • #ERROR tmkms::client: [canto_7700-1@tcp://] I/O error: Connection refused (os error 111)


  • LAST STEPS. Activate signing from canto node side

  • Find field priv_validator_laddr = "" at dir $HOME/.cantod/config/config.toml and edit to your Validator IP + port

  • Example : priv_validator_laddr = "tcp://" (Line 68 +-)

Make sure your firewall open only for KMS server IP to allow connect to port 26658 (or any custom port u set)
apt install ufw
ufw allow 22
ufw allow 80
ufw allow 443
ufw deny 26658
ufw allow from <ip tmkms server>
ufw enable
ufw status

Restarting the Validator Node

sudo systemctl restart cantod && sudo journalctl -fu cantod -o cat

Make sure that the logs are good

  • delete priv_validator_key.json from the validator node and restart again. Everything should work

Helpful commands

su tmkms && cd


sudo journalctl -fu tmkmsd-canto -o cat


sudo systemctl restart tmkmsd-canto && sudo journalctl -fu tmkmsd-canto -o cat

Last updated