ChainLaunch Pro Feature
AWS KMS integration requires ChainLaunch Pro. Learn more.
Use AWS Key Management Service as a key provider for cloud-native, FIPS 140-2 Level 3 validated key storage. Supports all key types including secp256k1 for Besu/Ethereum networks.
Authentication Modes
ChainLaunch supports four ways to authenticate with AWS KMS, from most to least recommended:
| Mode | Use when | Credentials needed |
|---|---|---|
| Instance role / IRSA | ChainLaunch runs on EC2 or EKS | None (automatic) |
| STS AssumeRole | Cross-account or least-privilege | Role ARN only |
| Named profile (SSO) | Local dev with AWS SSO | Profile name |
| Static credentials | Dev/testing with LocalStack | Access key + secret |
Option 1: Instance Role / IRSA (Recommended)
When ChainLaunch runs on EC2 or EKS, the AWS SDK picks up credentials automatically.
Prerequisites
Create an IAM policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:CreateKey",
"kms:CreateAlias",
"kms:DeleteAlias",
"kms:DescribeKey",
"kms:GetPublicKey",
"kms:Sign",
"kms:Verify",
"kms:ListAliases",
"kms:ListKeys",
"kms:TagResource",
"kms:ScheduleKeyDeletion"
],
"Resource": "*"
}
]
}Attach it to your EC2 instance profile or EKS service account.
Via API
curl -X POST http://localhost:8100/api/v1/key-providers \
-H "Content-Type: application/json" \
-d '{
"name": "aws-kms-production",
"type": "AWS_KMS",
"isDefault": true,
"awsKmsConfig": {
"operation": "IMPORT",
"awsRegion": "us-east-1",
"kmsKeyAliasPrefix": "chainlaunch/"
}
}'No credentials needed — the SDK uses the instance role automatically.
Via Terraform
resource "chainlaunch_key_provider" "aws_kms" {
name = "aws-kms-production"
type = "AWS_KMS"
is_default = true
aws_kms_config = {
operation = "IMPORT"
aws_region = "us-east-1"
kms_key_alias_prefix = "chainlaunch/"
}
}Option 2: STS AssumeRole
ChainLaunch assumes a dedicated IAM role. Works with instance role as base credentials or with static credentials from outside AWS.
resource "chainlaunch_key_provider" "aws_kms" {
name = "aws-kms-cross-account"
type = "AWS_KMS"
is_default = false
aws_kms_config = {
operation = "IMPORT"
aws_region = "us-east-1"
assume_role_arn = "arn:aws:iam::123456789012:role/ChainLaunchKMSRole"
external_id = "chainlaunch-unique-id"
kms_key_alias_prefix = "chainlaunch/"
}
}The target role's trust policy must allow the ChainLaunch principal:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:role/ChainLaunchInstanceRole"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "chainlaunch-unique-id"
}
}
}
]
}Named Profile (SSO)
Use a named AWS profile from ~/.aws/config or ~/.aws/credentials — including AWS SSO profiles. ChainLaunch passes the profile to the AWS SDK's shared-config loader, so any credentials resolvable by that profile (static keys, SSO sessions, role chaining) are used automatically. This is ideal for local development against AWS SSO.
This mode is API-only: configure it with the profile field on awsKmsConfig. It is not exposed by the chainlaunch_key_provider Terraform resource, so it cannot be set via HCL.
Via API
curl -X POST http://localhost:8100/api/v1/key-providers \
-H "Content-Type: application/json" \
-d '{
"name": "aws-kms-sso",
"type": "AWS_KMS",
"awsKmsConfig": {
"operation": "IMPORT",
"awsRegion": "us-east-1",
"profile": "my-sso-profile",
"kmsKeyAliasPrefix": "chainlaunch/"
}
}'Ensure the profile is signed in first (for SSO: aws sso login --profile my-sso-profile) so the SDK can resolve valid credentials.
Option 3: Static Credentials (Dev/LocalStack)
For development with LocalStack or when running outside AWS:
resource "chainlaunch_key_provider" "aws_kms_local" {
name = "aws-kms-localstack"
type = "AWS_KMS"
is_default = false
aws_kms_config = {
operation = "IMPORT"
aws_region = "us-east-1"
aws_access_key_id = "test"
aws_secret_access_key = "test"
endpoint_url = "http://localhost:4566"
kms_key_alias_prefix = "chainlaunch/"
}
}Warning
Never use static credentials in production. Use instance roles or STS AssumeRole instead.
Use KMS for an Organization
resource "chainlaunch_fabric_organization" "org1" {
msp_id = "Org1MSP"
description = "Production org with AWS KMS"
provider_id = tonumber(chainlaunch_key_provider.aws_kms.id)
}Use KMS for Besu Validator Keys
AWS KMS supports secp256k1 — required for Besu/Ethereum:
resource "chainlaunch_key" "validator_keys" {
count = 4
name = "besu-validator-${count.index}"
algorithm = "EC"
curve = "secp256k1"
provider_id = tonumber(chainlaunch_key_provider.aws_kms.id)
}
resource "chainlaunch_besu_network" "main" {
name = "production-besu"
chain_id = 1337
consensus = "qbft"
block_period = 5
epoch_length = 30000
request_timeout = 10
initial_validator_key_ids = [
for key in chainlaunch_key.validator_keys : tonumber(key.id)
]
}Supported Key Types
| Algorithm | Curves/Sizes | Supported | Notes |
|---|---|---|---|
| RSA | 2048, 4096 | Yes | |
| EC (ECDSA) | P-256, P-384 | Yes | NIST curves |
| EC (ECDSA) | secp256k1 | Yes | Ethereum/Besu curve |
| Ed25519 | — | No | Not supported by AWS KMS |
Verify Provider Status
curl http://localhost:8100/api/v1/key-providers/{providerId}/awskms/status | jqExpected:
{
"kms_reachable": true,
"has_credentials": true,
"kms_status": "available"
}Key Aliases
ChainLaunch creates KMS key aliases with the configured prefix:
chainlaunch/org1-identity-key
chainlaunch/org1-tls-key
chainlaunch/org1-ca-key
chainlaunch/besu-validator-0
You can view them in the AWS Console under KMS > Customer managed keys, or:
aws kms list-aliases --query 'Aliases[?starts_with(AliasName, `alias/chainlaunch/`)]'Cost Considerations
| Operation | AWS Price | ChainLaunch usage |
|---|---|---|
| KMS key (per month) | $1.00 | 1 per node key |
| API request (per 10K) | $0.03 | Signs, encrypts |
| Asymmetric sign | $0.15/10K | Transaction signing |
For a 4-validator Besu network: ~$4/mo for keys + ~$1-5/mo for API calls.
Multi-Region
For disaster recovery, use KMS multi-region keys:
- Create a multi-region primary key in your main region
- Create replicas in backup regions
- ChainLaunch can use either the primary or replica — same key ID works
Troubleshooting
"kms_reachable: false"
- Check AWS credentials are valid:
aws sts get-caller-identity - Verify the region matches your KMS keys
- For LocalStack: ensure it's running on the configured endpoint
"Access Denied"
- Check the IAM policy has all required KMS actions
- For AssumeRole: verify the trust policy allows the ChainLaunch principal
- Check the external ID matches (if configured)
"KMS key not found"
- Verify the key alias prefix matches
- Check the key is in the correct region
- Ensure the key isn't in "Pending Deletion" state
Next Steps
- HashiCorp Vault Integration for on-premise key management
- Key Management for the complete overview
- Besu Genesis Configuration for Besu-specific key requirements