aws-sdk-java-v2-kms
Install this skill
npx skills add giuseppe-trisciuoglio/developer-kitWorks across Claude Code, Cursor, Codex, Copilot & Antigravity
The aws-sdk-java-v2-kms skill provides a structured framework for interacting with AWS Key Management Service using the version 2 Java SDK. It offers programmatic control over cryptographic assets by enabling developers to manage symmetric and asymmetric keys, handle key lifecycle states, and perform direct encryption or decryption operations. The skill emphasizes the implementation of envelope encryption patterns, where a master key protects a temporary data key used for local data processing, reducing latency and service calls. It bridges the gap between raw AWS API requests and Java development workflows, offering patterns for Spring Boot environments and robust client configuration options including custom retry policies and region-specific management. This tool is intended for developers maintaining security-sensitive Java applications requiring integration with AWS infrastructure for data protection and secure credential management.
When to Use This Skill
- •Protecting sensitive application logs or database fields using KMS-backed envelope encryption
- •Automating the lifecycle of encryption keys across different deployment environments
- •Integrating digital signature verification into microservices for data integrity
- •Implementing regulatory-compliant key rotation and administrative control within a Java backend
How to Invoke This Skill
Example prompts that trigger this skill in Claude Code, Cursor, or Antigravity:
- “how do I encrypt data using AWS KMS in Java 2.x
- “implementing envelope encryption with AWS SDK for Java
- “create and manage KMS keys programmatically in Java
- “using KmsAsyncClient for non-blocking encryption
- “configure AWS KMS client with custom retry policy in Java
Pro Tips
- 💡Always follow the principle of least privilege when defining KMS key policies, ensuring only necessary entities have access to cryptographic operations.
- 💡Utilize envelope encryption for large datasets by generating data keys from KMS and encrypting data locally, reducing KMS API costs and latency while maintaining central key management.
- 💡Implement robust error handling and retry mechanisms for KMS API calls, especially when dealing with key availability or throttling limits.
What this skill does
- •Programmatic management of KMS key states, including enabling, disabling, and describing metadata
- •Direct execution of cryptographic operations for small to medium-sized payloads
- •Generation of unique data encryption keys for local envelope encryption
- •Support for both synchronous and asynchronous non-blocking client request patterns
- •Configuration of custom retry policies and secure credential provider chains
When not to use it
- ✕Performing bulk file encryption for terabyte-scale data where local hardware acceleration is superior
- ✕Managing high-frequency, low-latency encryption that exceeds KMS request quotas
Example workflow
- Initialize the KmsClient using DefaultCredentialsProvider for secure authentication
- Request a new data key from KMS to establish an encryption master key session
- Encrypt the target application data locally using the generated data key's plaintext
- Wipe the plaintext data key from memory immediately after the local encryption operation
- Store the ciphertext of the data key alongside the encrypted application data
Prerequisites
- –AWS account with active IAM credentials
- –KMS key alias or ARN already configured in the AWS console
- –Java 8 or higher development environment
Pitfalls & limitations
- !Failure to zero-out or clear the plaintext data key from memory after use creates a potential security exposure
- !Exceeding KMS per-second request limits can cause runtime throttling in high-throughput applications
- !Misconfiguring AWS regions leads to connectivity failures if the key is not local to the client instance
FAQ
How it compares
Compared to generic HTTP wrappers, this skill offers type-safe Request/Response objects and built-in handling of AWS authentication headers and retry logic, preventing manual serialization errors.
📄 Full skill instructions — original source: giuseppe-trisciuoglio/developer-kit
## Overview
This skill provides comprehensive patterns for AWS Key Management Service (KMS) using AWS SDK for Java 2.x. Focus on implementing secure encryption solutions with proper key management, envelope encryption, and Spring Boot integration patterns.
## When to Use
Use this skill when:
- Creating and managing symmetric encryption keys for data protection
- Implementing client-side encryption and envelope encryption patterns
- Generating data keys for local data encryption with KMS-managed keys
- Setting up digital signatures and verification with asymmetric keys
- Integrating encryption capabilities into Spring Boot applications
- Implementing secure key lifecycle management
- Setting up key rotation policies and access controls
## Dependencies
### Maven
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>kms</artifactId>
</dependency>### Gradle
implementation 'software.amazon.awssdk:kms:2.x.x'## Client Setup
### Basic Synchronous Client
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.kms.KmsClient;
KmsClient kmsClient = KmsClient.builder()
.region(Region.US_EAST_1)
.build();### Basic Asynchronous Client
import software.amazon.awssdk.services.kms.KmsAsyncClient;
KmsAsyncClient kmsAsyncClient = KmsAsyncClient.builder()
.region(Region.US_EAST_1)
.build();### Advanced Client Configuration
KmsClient kmsClient = KmsClient.builder()
.region(Region.of(System.getenv("AWS_REGION")))
.credentialsProvider(DefaultCredentialsProvider.create())
.overrideConfiguration(c -> c.retryPolicy(RetryPolicy.builder()
.numRetries(3)
.build()))
.build();## Basic Key Management
### Create Encryption Key
public String createEncryptionKey(KmsClient kmsClient, String description) {
CreateKeyRequest request = CreateKeyRequest.builder()
.description(description)
.keyUsage(KeyUsageType.ENCRYPT_DECRYPT)
.build();
CreateKeyResponse response = kmsClient.createKey(request);
return response.keyMetadata().keyId();
}### Describe Key
public KeyMetadata getKeyMetadata(KmsClient kmsClient, String keyId) {
DescribeKeyRequest request = DescribeKeyRequest.builder()
.keyId(keyId)
.build();
return kmsClient.describeKey(request).keyMetadata();
}### Enable/Disable Key
public void toggleKeyState(KmsClient kmsClient, String keyId, boolean enable) {
if (enable) {
kmsClient.enableKey(EnableKeyRequest.builder().keyId(keyId).build());
} else {
kmsClient.disableKey(DisableKeyRequest.builder().keyId(keyId).build());
}
}## Basic Encryption and Decryption
### Encrypt Data
public String encryptData(KmsClient kmsClient, String keyId, String plaintext) {
SdkBytes plaintextBytes = SdkBytes.fromString(plaintext, StandardCharsets.UTF_8);
EncryptRequest request = EncryptRequest.builder()
.keyId(keyId)
.plaintext(plaintextBytes)
.build();
EncryptResponse response = kmsClient.encrypt(request);
return Base64.getEncoder().encodeToString(
response.ciphertextBlob().asByteArray());
}### Decrypt Data
public String decryptData(KmsClient kmsClient, String ciphertextBase64) {
byte[] ciphertext = Base64.getDecoder().decode(ciphertextBase64);
SdkBytes ciphertextBytes = SdkBytes.fromByteArray(ciphertext);
DecryptRequest request = DecryptRequest.builder()
.ciphertextBlob(ciphertextBytes)
.build();
DecryptResponse response = kmsClient.decrypt(request);
return response.plaintext().asString(StandardCharsets.UTF_8);
}## Envelope Encryption Pattern
### Generate and Use Data Key
public DataKeyResult encryptWithEnvelope(KmsClient kmsClient, String masterKeyId, byte[] data) {
// Generate data key
GenerateDataKeyRequest keyRequest = GenerateDataKeyRequest.builder()
.keyId(masterKeyId)
.keySpec(DataKeySpec.AES_256)
.build();
GenerateDataKeyResponse keyResponse = kmsClient.generateDataKey(keyRequest);
// Encrypt data with data key
byte[] encryptedData = encryptWithAES(data,
keyResponse.plaintext().asByteArray());
// Clear plaintext key from memory
Arrays.fill(keyResponse.plaintext().asByteArray(), (byte) 0);
return new DataKeyResult(
encryptedData,
keyResponse.ciphertextBlob().asByteArray());
}
public byte[] decryptWithEnvelope(KmsClient kmsClient,
DataKeyResult encryptedEnvelope) {
// Decrypt data key
DecryptRequest keyDecryptRequest = DecryptRequest.builder()
.ciphertextBlob(SdkBytes.fromByteArray(
encryptedEnvelope.encryptedKey()))
.build();
DecryptResponse keyDecryptResponse = kmsClient.decrypt(keyDecryptRequest);
// Decrypt data with decrypted key
byte[] decryptedData = decryptWithAES(
encryptedEnvelope.encryptedData(),
keyDecryptResponse.plaintext().asByteArray());
// Clear plaintext key from memory
Arrays.fill(keyDecryptResponse.plaintext().asByteArray(), (byte) 0);
return decryptedData;
}## Digital Signatures
### Create Signing Key and Sign Data
public String createAndSignData(KmsClient kmsClient, String description, String message) {
// Create signing key
CreateKeyRequest keyRequest = CreateKeyRequest.builder()
.description(description)
.keySpec(KeySpec.RSA_2048)
.keyUsage(KeyUsageType.SIGN_VERIFY)
.build();
CreateKeyResponse keyResponse = kmsClient.createKey(keyRequest);
String keyId = keyResponse.keyMetadata().keyId();
// Sign data
SignRequest signRequest = SignRequest.builder()
.keyId(keyId)
.message(SdkBytes.fromString(message, StandardCharsets.UTF_8))
.signingAlgorithm(SigningAlgorithmSpec.RSASSA_PSS_SHA_256)
.build();
SignResponse signResponse = kmsClient.sign(signRequest);
return Base64.getEncoder().encodeToString(
signResponse.signature().asByteArray());
}### Verify Signature
public boolean verifySignature(KmsClient kmsClient,
String keyId,
String message,
String signatureBase64) {
byte[] signature = Base64.getDecoder().decode(signatureBase64);
VerifyRequest verifyRequest = VerifyRequest.builder()
.keyId(keyId)
.message(SdkBytes.fromString(message, StandardCharsets.UTF_8))
.signature(SdkBytes.fromByteArray(signature))
.signingAlgorithm(SigningAlgorithmSpec.RSASSA_PSS_SHA_256)
.build();
VerifyResponse verifyResponse = kmsClient.verify(verifyRequest);
return verifyResponse.signatureValid();
}## Spring Boot Integration
### Configuration Class
@Configuration
public class KmsConfiguration {
@Bean
public KmsClient kmsClient() {
return KmsClient.builder()
.region(Region.US_EAST_1)
.build();
}
@Bean
public KmsAsyncClient kmsAsyncClient() {
return KmsAsyncClient.builder()
.region(Region.US_EAST_1)
.build();
}
}### Encryption Service
@Service
@RequiredArgsConstructor
public class KmsEncryptionService {
private final KmsClient kmsClient;
@Value("${kms.encryption-key-id}")
private String keyId;
public String encrypt(String plaintext) {
try {
EncryptRequest request = EncryptRequest.builder()
.keyId(keyId)
.plaintext(SdkBytes.fromString(plaintext, StandardCharsets.UTF_8))
.build();
EncryptResponse response = kmsClient.encrypt(request);
return Base64.getEncoder().encodeToString(
response.ciphertextBlob().asByteArray());
} catch (KmsException e) {
throw new RuntimeException("Encryption failed", e);
}
}
public String decrypt(String ciphertextBase64) {
try {
byte[] ciphertext = Base64.getDecoder().decode(ciphertextBase64);
DecryptRequest request = DecryptRequest.builder()
.ciphertextBlob(SdkBytes.fromByteArray(ciphertext))
.build();
DecryptResponse response = kmsClient.decrypt(request);
return response.plaintext().asString(StandardCharsets.UTF_8);
} catch (KmsException e) {
throw new RuntimeException("Decryption failed", e);
}
}
}## Examples
### Basic Encryption Example
public class BasicEncryptionExample {
public static void main(String[] args) {
KmsClient kmsClient = KmsClient.builder()
.region(Region.US_EAST_1)
.build();
// Create key
String keyId = createEncryptionKey(kmsClient, "Example encryption key");
System.out.println("Created key: " + keyId);
// Encrypt and decrypt
String plaintext = "Hello, World!";
String encrypted = encryptData(kmsClient, keyId, plaintext);
String decrypted = decryptData(kmsClient, encrypted);
System.out.println("Original: " + plaintext);
System.out.println("Decrypted: " + decrypted);
}
}### Envelope Encryption Example
public class EnvelopeEncryptionExample {
public static void main(String[] args) {
KmsClient kmsClient = KmsClient.builder()
.region(Region.US_EAST_1)
.build();
String masterKeyId = "alias/your-master-key";
String largeData = "This is a large amount of data that needs encryption...";
byte[] data = largeData.getBytes(StandardCharsets.UTF_8);
// Encrypt using envelope pattern
DataKeyResult encryptedEnvelope = encryptWithEnvelope(
kmsClient, masterKeyId, data);
// Decrypt
byte[] decryptedData = decryptWithEnvelope(
kmsClient, encryptedEnvelope);
String result = new String(decryptedData, StandardCharsets.UTF_8);
System.out.println("Decrypted: " + result);
}
}## Best Practices
### Security
- **Always use envelope encryption for large data** - Encrypt data locally and only encrypt the data key with KMS
- **Use encryption context** - Add contextual information to track and audit usage
- **Never log sensitive data** - Avoid logging plaintext or encryption keys
- **Implement proper key lifecycle** - Enable automatic rotation and set deletion policies
- **Use separate keys for different purposes** - Don't reuse keys across multiple applications
### Performance
- **Cache encrypted data keys** - Reduce KMS API calls by caching data keys
- **Use async operations** - Leverage async clients for non-blocking I/O
- **Reuse client instances** - Don't create new clients for each operation
- **Implement connection pooling** - Configure proper connection pooling settings
### Error Handling
- **Implement retry logic** - Handle throttling exceptions with exponential backoff
- **Check key states** - Verify key is enabled before performing operations
- **Use circuit breakers** - Prevent cascading failures during KMS outages
- **Log errors comprehensively** - Include KMS error codes and context
## References
For detailed implementation patterns, advanced techniques, and comprehensive examples:
- @references/technical-guide.md - Complete technical implementation patterns
- @references/spring-boot-integration.md - Spring Boot integration patterns
- @references/testing.md - Testing strategies and examples
- @references/best-practices.md - Security and operational best practices
## Related Skills
- @aws-sdk-java-v2-core - Core AWS SDK patterns and configuration
- @aws-sdk-java-v2-dynamodb - DynamoDB integration patterns
- @aws-sdk-java-v2-secrets-manager - Secrets management patterns
- @spring-boot-dependency-injection - Spring dependency injection patterns
## External References
- [AWS KMS Developer Guide](https://docs.aws.amazon.com/kms/latest/developerguide/)
- [AWS SDK for Java 2.x Documentation](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/home.html)
- [KMS Best Practices](https://docs.aws.amazon.com/kms/latest/developerguide/best-practices.html)
How to Use This Skill Unit
Option A: Project-Specific (Recommended)
- Click "Download" above
- In your project, create the directory:
.agent/skills/aws-sdk-java-v2-kms/ - Save the file as
SKILL.md - The agent will automatically discover the skill based on its description.
Option B: Global Installation (All Agents)
Save the file to these locations to make it available across all projects:
- Claude Code:
~/.claude/skills/giuseppe-trisciuoglio/developer-kit/aws-sdk-java-v2-kms/SKILL.md - Cursor:
~/.cursor/skills/giuseppe-trisciuoglio/developer-kit/aws-sdk-java-v2-kms/SKILL.md - Antigravity:
~/.gemini/antigravity/skills/giuseppe-trisciuoglio/developer-kit/aws-sdk-java-v2-kms/SKILL.md
🚀 Install with CLI:npx skills add giuseppe-trisciuoglio/developer-kit