Hyperlane Agent Keys
Hyperlane agents (validators and relayers) require signing keys to operate. Validators sign message checkpoints, and relayers sign delivery transactions on destination chains. This guide covers key generation for the BitSong testnet, following the official Hyperlane agent key documentation.
Key Types Overview
Each Hyperlane operator needs up to three keys depending on their role:
| Key | Used By | Purpose |
|---|---|---|
| Validator Key | Validator agent | Signs message checkpoints (EVM hex key or AWS KMS) |
| Cosmos Signer Key | Validator agent | Signs BitSong on-chain announcement transactions |
| Relayer Key | Relayer agent | Signs delivery transactions on both BitSong and Base Sepolia |
Choose Your Environment
Two environments are available. Follow only the section that matches your setup — each is self-contained.
| Local (Testnet) | AWS (Production) | |
|---|---|---|
| Validator signing | Hex private key in memory | AWS KMS hardware-backed key |
| Checkpoint storage | Local filesystem | AWS S3 bucket |
| Security | Keys stored in plaintext | Private key never leaves CloudHSM |
| Best for | Testing and development | Mainnet and production |
Prerequisites
Install Foundry to get the cast CLI tool for EVM key operations:
curl -L https://foundry.paradigm.xyz | bash
source ~/.bashrc
foundryup
Verify the installation:
cast --version
# cast Version: 1.5.1-stable
# Commit SHA: b0a9dd9ceda36f63e2326ce530c10e6916f4b8a2
# Build Timestamp: 2025-12-22T11:39:01.425730780Z (1766403541)
# Build Profile: maxper
Local Environment (Testnet)
Hex keys store the private key directly as a 0x-prefixed hexadecimal string. This is the simplest approach and suitable for testnet environments. Checkpoints are stored on the local filesystem.
Generate a Validator Key
Create a new EVM wallet
cast wallet new
This outputs an address and private key pair:
Successfully created new keypair.
Address: 0x32e6...eebC
Private key: 0x2958...78f9
Save both values securely.
Export as environment variables
export VALIDATOR_KEY="0x<your-validator-private-key>"
export VALIDATOR_ADDR=$(cast wallet address --private-key $VALIDATOR_KEY)
echo "Validator EVM address: $VALIDATOR_ADDR"
The VALIDATOR_ADDR is the address you register in the MultisigISM during bridge setup.
Generate a Relayer Key
If you are also running a relayer, generate a separate key for it:
cast wallet new
Export it:
export EVM_RELAYER_KEY="0x<your-relayer-private-key>"
EVM_RELAYER_KEY=$VALIDATOR_KEY), but separate keys provide better security isolation.Cosmos Signer Key
BitSong is a Cosmos-based chain, so the validator agent needs a Cosmos signer key to submit on-chain announcement transactions (announcing its checkpoint storage location to the ValidatorAnnounce module).
The Hyperlane agent requires this key as a hex private key (--chains.bitsong.signer.key). You can create it with bitsongd keys and export the hex value.
Create a dedicated Cosmos signer key
bitsongd keys add hyperlane-signer --keyring-backend test
Note the bitsong1... address from the output — you will fund this account in the next step.
Export the hex private key
COSMOS_SIGNER_KEY=0x$(bitsongd keys export hyperlane-signer --unarmored-hex --unsafe --keyring-backend test 2>&1 | tail -1)
export COSMOS_SIGNER_KEY
Fund the Cosmos signer account
bitsongd tx bank send <your-key-name> $(bitsongd keys show hyperlane-signer -a --keyring-backend test) 10000000utbtsg \
--from <your-key-name> \
--keyring-backend test \
--chain-id crescendo-1 \
--node tcp://localhost:26657 \
--fees 10000utbtsg -y
export COSMOS_SIGNER_KEY=$VALIDATOR_KEY. The derived Cosmos address will still need to be funded.Local Environment Summary
After generating all keys, your environment should have these variables set:
# Validator signing key (hex)
export VALIDATOR_KEY="0x..."
# Derived validator EVM address
export VALIDATOR_ADDR=$(cast wallet address --private-key $VALIDATOR_KEY)
# Cosmos signer key (for BitSong announcement transactions)
export COSMOS_SIGNER_KEY="0x..."
# Relayer key (for message delivery on both chains)
export EVM_RELAYER_KEY="0x..."
.env file for convenience. Make sure the file is never committed to version control:echo ".env" >> .gitignore
AWS Environment (Production)
For production environments, AWS KMS provides hardware-backed key security. The private key never leaves the CloudHSM, and all signing operations happen server-side. Checkpoints are stored in an S3 bucket for reliable, publicly readable access by relayers.
This setup requires three AWS resources: an IAM user (for API access), a KMS key (for signing), and an S3 bucket (for checkpoint storage). See also the official Hyperlane agent key documentation.
Create an IAM User
The IAM user provides API credentials that the Hyperlane agent uses to access KMS and S3.
Open the IAM console
Navigate to the AWS IAM console. In the left sidebar, click Users under the Access management section.
Add a new user
Click the Add users button. Enter a descriptive username:
hyperlane-validator-bitsong
Proceed through the remaining setup steps. You do not need to assign any permissions at this stage — permissions will be granted through the KMS key policy later.
Generate access credentials
After the user is created, open the user details page and select the Security credentials tab. Scroll to the Access keys section and click Create access key.
When prompted for a use case, select Application running outside AWS. Skip the optional description tag and click Create access key.
Save the credentials
You will see two values:
- Access key ID (e.g.
AKIAIOSFODNN7EXAMPLE) - Secret access key (e.g.
wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY)
Export these as environment variables, along with the region where you will create the KMS key:
export AWS_ACCESS_KEY_ID="<your-access-key-id>"
export AWS_SECRET_ACCESS_KEY="<your-secret-access-key>"
export AWS_REGION="<your-aws-region>" # e.g. us-east-1
AWS_REGION variable is required. Without it, all AWS signing operations will fail with Missing Region.Create a KMS Key
The KMS key is the asymmetric signing key used by the validator agent.
Open the KMS console
Navigate to the AWS KMS console. Verify the correct region is selected in the top-right corner — this must match the region you will configure in the validator agent.
In the left sidebar, select Customer managed keys, then click Create key.
Configure the key type
On the key configuration page, set these values:
| Setting | Value |
|---|---|
| Key type | Asymmetric |
| Key usage | Sign and verify |
| Key spec | ECC_SECG_P256K1 |
ECC_SECG_P256K1. This is the secp256k1 elliptic curve used by Ethereum and Hyperlane. Selecting a different key spec will not work.Set the key alias
Enter a descriptive alias for the key:
hyperlane-validator-signer-bitsong
Optionally add a description (e.g. "Hyperlane validator signing key for BitSong testnet") and tags.
Skip key administrators
On the key administrators page, you can skip this step unless you need other IAM users to manage the key.
Grant usage permissions
On the key usage permissions page, select the IAM user you created earlier (hyperlane-validator-bitsong). This grants the user permission to use the key for signing.
Review and create
Review the key policy. The default policy is sufficient. Click Finish to create the key.
Verify the KMS Key Address
After creating both the IAM user and KMS key, verify the derived EVM address:
AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \
AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \
AWS_REGION=$AWS_REGION \
AWS_KMS_KEY_ID=alias/hyperlane-validator-signer-bitsong \
cast wallet address --aws
This prints the EVM address associated with your KMS key. Save this address — it is the validator address you will register in the MultisigISM during bridge setup.
export VALIDATOR_ADDR="0x<kms-derived-address>"
Create an S3 Bucket for Checkpoint Storage
Production validators store checkpoints in an S3 bucket. The validator writes signed checkpoints to S3, and relayers read them to deliver messages. The bucket must be publicly readable by relayers and writable by the validator IAM user.
See also the official AWS Signatures Bucket Setup guide.
Create the bucket
Navigate to AWS S3 in the AWS console and click Create bucket. Use a descriptive name:
hyperlane-validator-signatures-bitsong
Select the same region as your KMS key. Keep ACLs disabled for object ownership.
Configure public access settings
Under Block Public Access settings for this bucket, uncheck Block all public access. Keep the first two ACL-blocking options checked:
- :checked-box: Block public access to buckets and objects granted through new access control lists (ACLs)
- :checked-box: Block public access to buckets and objects granted through any access control lists (ACLs)
- :unchecked-box: Block public access to buckets and objects granted through new public bucket or access point policies
- :unchecked-box: Block public and cross-account access to buckets and objects through any public bucket or access point policies
This allows relayers to read checkpoints via the bucket policy while preventing open ACL access.
Complete the bucket creation with the remaining defaults.
Get your IAM User ARN
Navigate back to IAM in the AWS console. Under IAM resources, click Users, then click on the name of the user you created earlier (e.g. hyperlane-validator-bitsong).
Copy the User ARN from the summary section. It looks like:
arn:aws:iam::791444913613:user/hyperlane-validator-bitsong
Set the bucket policy
Navigate back to S3 in the AWS console. Click on the name of the bucket you just created. Just under the bucket name, click the Permissions tab.
Scroll down to Bucket policy and click Edit. The Bucket ARN is displayed just above the policy editor — copy it.
Enter the following policy, replacing ${BUCKET_ARN} with your bucket ARN and ${USER_ARN} with the IAM user ARN you copied in the previous step:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"${BUCKET_ARN}",
"${BUCKET_ARN}/*"
]
},
{
"Effect": "Allow",
"Principal": {
"AWS": "${USER_ARN}"
},
"Action": [
"s3:DeleteObject",
"s3:PutObject"
],
"Resource": "${BUCKET_ARN}/*"
}
]
}
The first statement grants public read access so any relayer can fetch checkpoints. The second statement grants write access only to your validator IAM user.
Click Save changes.
Cosmos Signer Key (AWS)
Even when using AWS KMS for the validator checkpoint signer, the Cosmos signer key is still a hex private key. The Hyperlane agent's cosmosKey signer type only accepts hex keys — it does not support AWS KMS.
Create the key with bitsongd keys and export the hex value:
Create a dedicated Cosmos signer key
bitsongd keys add hyperlane-signer --keyring-backend test
Note the bitsong1... address from the output — you will fund this account in the next step.
Export the hex private key
COSMOS_SIGNER_KEY=0x$(bitsongd keys export hyperlane-signer --unarmored-hex --unsafe --keyring-backend test 2>&1 | tail -1)
export COSMOS_SIGNER_KEY
Fund the Cosmos signer account
bitsongd tx bank send <your-key-name> $(bitsongd keys show hyperlane-signer -a --keyring-backend test) 10000000utbtsg \
--from <your-key-name> \
--keyring-backend test \
--chain-id crescendo-1 \
--node tcp://localhost:26657 \
--fees 10000utbtsg -y
Create a Relayer KMS Key
The relayer needs its own signing key for Base Sepolia (the EVM destination chain) to pay gas and deliver cross-chain messages. Following the official Hyperlane relayer documentation, create a separate KMS key for the relayer.
Repeat the Create a KMS Key steps above with a different alias:
hyperlane-relayer-bitsong
On the key usage permissions page, select the same IAM user (hyperlane-validator-bitsong).
After creating the key, verify the derived EVM address:
AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \
AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \
AWS_REGION=$AWS_REGION \
AWS_KMS_KEY_ID=alias/hyperlane-relayer-bitsong \
cast wallet address --aws
Using AWS KMS with the Validator Agent
When running the validator with AWS KMS, replace the hex key flags with AWS-specific flags:
# Instead of:
# --validator.type hexKey
# --validator.key $VALIDATOR_KEY
# Use:
--validator.type aws
--validator.region <your-aws-region>
--validator.id alias/hyperlane-validator-signer-bitsong
--chains.bitsong.signer.type aws
--chains.bitsong.signer.region <your-aws-region>
--chains.bitsong.signer.id alias/hyperlane-validator-signer-bitsong
For S3 checkpoint storage, replace localStorage flags:
# Instead of:
# --checkpointSyncer.type localStorage
# --checkpointSyncer.path /checkpoints-bitsong
# Use:
--checkpointSyncer.type s3
--checkpointSyncer.bucket hyperlane-validator-signatures-bitsong
--checkpointSyncer.region <your-aws-region>
--checkpointSyncer.folder bitsong
Make sure the Docker container has access to the AWS credentials via environment variables:
-e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
AWS Environment Summary
After completing all AWS setup, your environment should have these variables set:
# AWS credentials
export AWS_ACCESS_KEY_ID="<your-access-key-id>"
export AWS_SECRET_ACCESS_KEY="<your-secret-access-key>"
export AWS_REGION="<your-aws-region>"
# Derived validator address from KMS
export VALIDATOR_ADDR="0x<kms-derived-address>"
# Cosmos signer key (hex — required even with AWS KMS)
export COSMOS_SIGNER_KEY="0x..."
The relayer uses its own KMS key (alias/hyperlane-relayer-bitsong) — no hex EVM_RELAYER_KEY variable is needed in the AWS environment.
.env file for convenience. Make sure the file is never committed to version control:echo ".env" >> .gitignore
Multi-Validator Setup
If you are coordinating multiple validators:
- Each validator generates their own key pair using the steps above
- Validators share only their EVM addresses (never private keys)
- All validator addresses are collected and used when creating the MultisigISM in the bridge setup
- Each validator runs their own agent with their individual private key