ChainLaunch

Pro Feature

AWS KMS Integration

AWS KMS integration requires ChainLaunch Pro. Learn more.

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

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

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

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:

  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