Introduction
AWS KMS centralizes encryption key management and simplifies GDPR and ISO compliance. In this intermediate tutorial, you will create a CMK, encrypt sensitive data, and implement automatic rotation. Each step includes ready-to-use code for Node.js with SDK v3. You will also discover how to integrate KMS into a serverless architecture while respecting the principle of least privilege.
Prerequisites
- AWS account with KMS permissions
- Node.js 20+ and AWS CLI v2
- Basic knowledge of TypeScript and IAM
AWS CLI Configuration
aws configure
aws sts get-caller-identityConfigure your AWS credentials and verify your IAM identity before any KMS operations.
Creating a CMK
aws kms create-key --description "Clé application 2026" --tags TagKey=Environment,TagValue=Production --output jsonCreates a CMK with tags. Note the returned ARN for the following steps.
Installing the AWS SDK
npm init -y
npm install @aws-sdk/client-kmsInstalls the official lightweight and typed KMS client v3, superior to v2.
TypeScript KMS Client
import { KMSClient } from '@aws-sdk/client-kms';
const kmsClient = new KMSClient({
region: 'eu-west-3',
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
});Initializes the KMS client with region and credentials. Always use environment variables.
Encryption Function
import { EncryptCommand } from '@aws-sdk/client-kms';
import { kmsClient } from './kms-client';
export async function encryptData(plaintext: string, keyId: string): Promise<Uint8Array> {
const command = new EncryptCommand({
KeyId: keyId,
Plaintext: Buffer.from(plaintext),
});
const response = await kmsClient.send(command);
return response.CiphertextBlob!;
}Encrypts a string and returns the ciphertext. Handle errors with try/catch in production.
Decryption Function
import { DecryptCommand } from '@aws-sdk/client-kms';
import { kmsClient } from './kms-client';
export async function decryptData(ciphertext: Uint8Array): Promise<string> {
const command = new DecryptCommand({
CiphertextBlob: ciphertext,
});
const response = await kmsClient.send(command);
return Buffer.from(response.Plaintext!).toString();
}Decrypts the ciphertext without specifying the key (KMS deduces it automatically).
Best Practices
- Always use aliases to reference keys
- Enable automatic rotation every 365 days
- Limit IAM permissions to the strict minimum
- Store ciphertext in S3 with SSE-KMS
- Enable CloudTrail to audit KMS calls
Common Mistakes to Avoid
- Forgetting to handle the KeyUnavailableException
- Using AWS-managed keys for sensitive data
- Not enabling rotation on production keys
- Hardcoding the key ID in source code
Further Reading
Discover our advanced AWS security courses: https://learni-group.com/formations