AWS KMS Integration
This guide covers the AWS Key Management Service (KMS) integration for TrustWeave. The AWS KMS plugin provides production-ready key management with FIPS 140-3 Level 3 compliance and support for all AWS KMS-compatible algorithms.
Overview
The kms/plugins/aws module provides a complete implementation of TrustWeave’s KeyManagementService interface using AWS Key Management Service. This integration enables you to:
- Use AWS KMS for secure key generation and storage with FIPS 140-3 Level 3 validated HSMs
- Leverage AWS KMS’s automatic key rotation capabilities
- Support all AWS KMS-compatible algorithms (Ed25519, secp256k1, P-256/P-384/P-521, RSA)
- Integrate with existing AWS infrastructure and IAM policies
- Meet regulatory compliance requirements with FIPS-validated cryptographic operations
Installation
Add the AWS KMS module to your dependencies:
1
2
3
4
5
dependencies {
implementation("com.trustweave.kms:aws:1.0.0-SNAPSHOT")
implementation("com.trustweave:trustweave-kms:1.0.0-SNAPSHOT")
implementation("com.trustweave:trustweave-common:1.0.0-SNAPSHOT")
}
Configuration
Basic Configuration
The AWS KMS provider can be configured via options map or environment variables:
1
2
3
4
5
6
7
8
9
10
11
import com.trustweave.kms.*
import java.util.ServiceLoader
// Discover AWS provider
val providers = ServiceLoader.load(KeyManagementServiceProvider::class.java)
val awsProvider = providers.find { it.name == "aws" }
// Create KMS with explicit configuration
val kms = awsProvider?.create(mapOf(
"region" to "us-east-1"
))
Authentication
The plugin supports multiple authentication methods:
1. IAM Roles (Recommended for Production)
When running on AWS infrastructure (EC2, ECS, Lambda), use IAM roles:
1
2
3
4
// No credentials needed - uses IAM role automatically
val kms = awsProvider?.create(mapOf(
"region" to "us-east-1"
))
2. Access Keys
For local development or non-AWS environments:
1
2
3
4
5
val kms = awsProvider?.create(mapOf(
"region" to "us-east-1",
"accessKeyId" to "AKIA...",
"secretAccessKey" to "..."
))
3. Environment Variables
The plugin automatically reads from environment variables:
1
2
3
export AWS_REGION=us-east-1
export AWS_ACCESS_KEY_ID=AKIA...
export AWS_SECRET_ACCESS_KEY=...
1
2
3
// Configuration loaded from environment automatically
val config = AwsKmsConfig.fromEnvironment()
val kms = AwsKeyManagementService(config ?: throw IllegalStateException("AWS config not found"))
LocalStack Configuration (Testing)
For local testing with LocalStack:
1
2
3
4
val kms = awsProvider?.create(mapOf(
"region" to "us-east-1",
"endpointOverride" to "http://localhost:4566"
))
Algorithm Support
The AWS KMS plugin supports all AWS KMS-compatible algorithms. AWS KMS uses FIPS 140-3 Level 3 validated hardware security modules (HSMs) as documented in NIST Certificate #4884.
| Algorithm | AWS KMS Key Spec | Signing Algorithm | FIPS 140-3 Status | Notes |
|---|---|---|---|---|
| Ed25519 | ECC_Ed25519 |
ECDSA_SHA_256 |
⚠️ Not in FIPS cert | Supported as of Nov 2025 (may use non-FIPS validated path) |
| secp256k1 | ECC_SECG_P256K1 |
ECDSA_SHA_256 |
✅ Allowed | Blockchain-only use per FIPS certificate |
| P-256 | ECC_NIST_P256 |
ECDSA_SHA_256 |
✅ Approved | FIPS 140-3 Level 3 validated |
| P-384 | ECC_NIST_P384 |
ECDSA_SHA_384 |
✅ Approved | FIPS 140-3 Level 3 validated |
| P-521 | ECC_NIST_P521 |
ECDSA_SHA_512 |
✅ Approved | FIPS 140-3 Level 3 validated |
| RSA-2048 | RSA_2048 |
RSASSA_PKCS1_V1_5_SHA_256 |
✅ Approved | FIPS 140-3 Level 3 validated |
| RSA-3072 | RSA_3072 |
RSASSA_PKCS1_V1_5_SHA_256 |
✅ Approved | FIPS 140-3 Level 3 validated |
| RSA-4096 | RSA_4096 |
RSASSA_PKCS1_V1_5_SHA_256 |
✅ Approved | FIPS 140-3 Level 3 validated |
FIPS 140-3 Compliance
AWS KMS uses FIPS 140-3 Level 3 validated HSMs (Certificate #4884, validated 11/18/2024). The validated module supports:
- ECDSA (FIPS 186-4) on NIST curves (P-256, P-384, P-521) - ✅ Approved
- ECDSA secp256k1 (FIPS 186-4) - ✅ Allowed (blockchain applications only)
- RSA (FIPS 186-4) - ✅ Approved for all key sizes
Important Notes:
- Ed25519 support was added in November 2025 and may not be covered by the current FIPS certificate
- secp256k1 is allowed per FIPS certificate but restricted to blockchain-related applications
- For maximum FIPS compliance, use P-256, P-384, P-521, or RSA algorithms
Checking Algorithm Support
1
2
3
4
5
6
7
8
9
10
val kms = awsProvider?.create(mapOf("region" to "us-east-1"))
// Get all supported algorithms
val supported = kms?.getSupportedAlgorithms()
println("Supported algorithms: ${supported?.joinToString { it.name }}")
// Check specific algorithm
if (kms?.supportsAlgorithm(Algorithm.Ed25519) == true) {
println("Ed25519 is supported")
}
Usage Examples
Generating Keys
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import com.trustweave.kms.*
// Generate Ed25519 key
val key = kms.generateKey(Algorithm.Ed25519)
// Generate key with alias (for easier rotation)
val keyWithAlias = kms.generateKey(
algorithm = Algorithm.Ed25519,
options = mapOf(
"alias" to "alias/issuer-key",
"description" to "Issuer signing key",
"enableAutomaticRotation" to true
)
)
// Generate P-256 key for FIPS compliance
val fipsKey = kms.generateKey(
algorithm = Algorithm.P256,
options = mapOf(
"description" to "FIPS-compliant issuer key"
)
)
Signing Data
1
2
3
4
5
6
7
8
9
10
11
12
// Sign with key ID (KeyId value class)
val signature = kms.sign(KeyId(keyId), data.toByteArray())
// Sign with algorithm override
val signature = kms.sign(
keyId = KeyId(keyId),
data = data.toByteArray(),
algorithm = Algorithm.Ed25519
)
// Sign using alias
val signature = kms.sign(KeyId("alias/issuer-key"), data.toByteArray())
Retrieving Public Keys
1
2
3
4
5
6
7
8
9
10
11
12
// Get public key by key ID (KeyId value class)
val publicKey = kms.getPublicKey(KeyId(keyId))
// Get public key by ARN
val publicKey = kms.getPublicKey(KeyId("arn:aws:kms:us-east-1:123456789012:key/123"))
// Get public key by alias
val publicKey = kms.getPublicKey(KeyId("alias/issuer-key"))
// Access JWK format
val jwk = publicKey.publicKeyJwk
println("Public key JWK: $jwk")
Key Deletion
1
2
// Schedule key deletion (30-day pending window by default)
val deleted = kms.deleteKey(KeyId(keyId))
Key Rotation Strategies
AWS KMS supports two types of key rotation:
1. AWS KMS Automatic Rotation
AWS KMS can automatically rotate customer-managed keys annually:
1
2
3
4
5
6
7
8
9
10
// Enable automatic rotation when creating key
val key = kms.generateKey(
algorithm = Algorithm.Ed25519,
options = mapOf(
"enableAutomaticRotation" to true
)
)
// The same key ID/alias continues to work
// AWS KMS uses newer key material internally
Benefits:
- No code changes required
- Same key ID/alias works across rotations
- Automatic and transparent
Limitations:
- Only for customer-managed keys
- Annual rotation schedule
- Historical key versions maintained by AWS
2. TrustWeave Manual Rotation Pattern
For more control, use TrustWeave’s manual rotation pattern:
1
2
3
4
5
6
7
8
9
10
11
12
13
// Step 1: Generate new key
val newKey = kms.generateKey(
algorithm = Algorithm.Ed25519,
options = mapOf(
"alias" to "alias/issuer-key-v2",
"description" to "Issuer key rotated 2025-01-15"
)
)
// Step 2: Update DID document (see key-rotation.md)
// Step 3: Switch issuance to new key
// Step 4: Maintain old key for historical verification
// Step 5: Eventually delete old key after credentials expire
Benefits:
- Full control over rotation schedule
- Can rotate immediately in response to incidents
- Clear audit trail of key changes
Using Key Aliases for Seamless Rotation
Key aliases make rotation easier:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Create key with alias
val key1 = kms.generateKey(
algorithm = Algorithm.Ed25519,
options = mapOf("alias" to "alias/issuer-key")
)
// Later, create new key and update alias
val key2 = kms.generateKey(
algorithm = Algorithm.Ed25519,
options = mapOf("alias" to "alias/issuer-key-temp")
)
// Update alias to point to new key (requires AWS KMS extension)
// kms.updateKeyAlias("alias/issuer-key", key2.id)
// Old key remains accessible by its ID for historical verification
Error Handling
The plugin maps AWS exceptions to TrustWeave exceptions:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
try {
val key = kms.generateKey(Algorithm.Ed25519)
} catch (e: UnsupportedAlgorithmException) {
println("Algorithm not supported: ${e.message}")
} catch (e: TrustWeaveException) {
when {
e.message?.contains("Access denied") == true -> {
println("Check IAM permissions")
}
e.message?.contains("Key not found") == true -> {
println("Key does not exist")
}
else -> {
println("Error: ${e.message}")
}
}
}
Common Errors
| Error | Cause | Solution |
|---|---|---|
AccessDeniedException |
Insufficient IAM permissions | Grant kms:CreateKey, kms:Sign, kms:GetPublicKey permissions |
NotFoundException |
Key doesn’t exist | Verify key ID/ARN/alias is correct |
InvalidKeyUsageException |
Wrong key usage type | Ensure key is created with SIGN_VERIFY usage |
UnsupportedAlgorithmException |
Algorithm not supported | Check algorithm compatibility table |
IAM Permissions
Your AWS IAM role/user needs the following permissions:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:CreateKey",
"kms:DescribeKey",
"kms:GetPublicKey",
"kms:Sign",
"kms:ScheduleKeyDeletion",
"kms:EnableKeyRotation",
"kms:CreateAlias",
"kms:UpdateAlias"
],
"Resource": "*"
}
]
}
For production, restrict resources to specific key ARNs:
1
2
3
4
5
6
{
"Resource": [
"arn:aws:kms:us-east-1:123456789012:key/*",
"arn:aws:kms:us-east-1:123456789012:alias/*"
]
}
Algorithm Compatibility
See the Algorithm Compatibility Table for detailed comparison of algorithm support across DIDs, VCs, AWS KMS, and Azure Key Vault.
Key Points:
- ✅ AWS KMS supports Ed25519 (as of Nov 2025)
- ✅ All NIST curves (P-256/P-384/P-521) supported
- ✅ secp256k1 supported for blockchain integration
- ✅ RSA keys supported for legacy compatibility
- ❌ BLS12-381 not supported (requires specialized KMS)
Best Practices
- Use IAM Roles: Prefer IAM roles over access keys for production
- Key Aliases: Use aliases for easier key rotation
- Automatic Rotation: Enable automatic rotation for customer-managed keys
- Key Descriptions: Always provide descriptive key descriptions
- Error Handling: Implement proper error handling for AWS exceptions
- Key Lifecycle: Plan key rotation and deletion schedules
- Access Control: Use IAM policies to restrict key access
Testing
Unit Tests
The module includes unit tests that can be run without AWS credentials:
1
./gradlew :kms/plugins/aws:test
Integration Tests with LocalStack
For integration testing, use LocalStack:
1
2
3
4
5
// Configure for LocalStack
val kms = awsProvider?.create(mapOf(
"region" to "us-east-1",
"endpointOverride" to "http://localhost:4566"
))
Start LocalStack:
1
docker run -d -p 4566:4566 localstack/localstack
Related Documentation
- Key Management Guide - Core KMS concepts
- Algorithm Compatibility Table - Algorithm support comparison
- Key Rotation Guide - Key rotation strategies
- Creating Plugins Guide - Custom KMS implementations
FIPS 140-3 Compliance
AWS KMS uses FIPS 140-3 Level 3 validated hardware security modules. For details, see:
- NIST CMVP Certificate #4884 - AWS Key Management Service HSM validation
- Certificate Status: Active (Sunset: 11/17/2026)
- Security Level: Level 3
- Module Type: Hardware (Multi-Chip Stand Alone)
The validated module supports ECDSA (FIPS 186-4) on NIST curves, ECDSA secp256k1 (blockchain use only), and RSA (FIPS 186-4) for all key sizes.
See Also
- AWS KMS Developer Guide
- AWS KMS API Reference
- NIST CMVP Certificate #4884 - FIPS 140-3 validation details