Skip to content
Learni
View all tutorials
Cloud Infrastructure

How to Manage AWS KMS Encryption Keys in 2026

18 minINTERMEDIATE
Lire en français

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

terminal
aws configure
aws sts get-caller-identity

Configure your AWS credentials and verify your IAM identity before any KMS operations.

Creating a CMK

terminal
aws kms create-key --description "Clé application 2026" --tags TagKey=Environment,TagValue=Production --output json

Creates a CMK with tags. Note the returned ARN for the following steps.

Installing the AWS SDK

terminal
npm init -y
npm install @aws-sdk/client-kms

Installs the official lightweight and typed KMS client v3, superior to v2.

TypeScript KMS Client

kms-client.ts
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

encrypt.ts
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

decrypt.ts
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