Skip to main content

AWS KMS Integration (Pro)

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:

ModeUse whenCredentials needed
Instance role / IRSAChainLaunch runs on EC2 or EKSNone (automatic)
STS AssumeRoleCross-account or least-privilegeRole ARN only
Named profile (SSO)Local dev with AWS SSOProfile name
Static credentialsDev/testing with LocalStackAccess key + secret

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"
}
}
}
]
}

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

AlgorithmCurves/SizesSupportedNotes
RSA2048, 4096Yes
EC (ECDSA)P-256, P-384YesNIST curves
EC (ECDSA)secp256k1YesEthereum/Besu curve
Ed25519NoNot supported by AWS KMS

Verify Provider Status

curl http://localhost:8100/api/v1/key-providers/{providerId}/awskms/status | jq

Expected:

{
"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

OperationAWS PriceChainLaunch usage
KMS key (per month)$1.001 per node key
API request (per 10K)$0.03Signs, encrypts
Asymmetric sign$0.15/10KTransaction 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:

  1. Create a multi-region primary key in your main region
  2. Create replicas in backup regions
  3. 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