EKS Cluster KMS Encryption for Kubernetes Secrets
Overview
This check verifies that your Amazon EKS clusters use AWS KMS envelope encryption for Kubernetes secrets stored in etcd. When enabled, all secrets (such as passwords, tokens, and API keys) are encrypted at rest using a customer-managed KMS key, adding an extra layer of protection beyond the default encryption.
Risk
Without KMS encryption enabled, Kubernetes secrets in etcd are stored with only basic encryption. If an attacker gains access to:
- The Kubernetes API
- Cluster nodes
- etcd backups or snapshots
They could potentially retrieve plaintext secrets, leading to:
- Credential theft (passwords, tokens, API keys)
- Service impersonation
- Lateral movement within your infrastructure
- Privilege escalation
Remediation Steps
Prerequisites
- Access to the AWS Console with permissions to modify EKS clusters, or
- AWS CLI configured with appropriate credentials
- An existing AWS KMS key (or permission to create one)
Creating a KMS key (if needed)
If you do not already have a KMS key for EKS secrets encryption:
Console:
- Open the AWS KMS console
- Click Create key
- Choose Symmetric key type
- Set an alias like
eks-secrets-key - Define key administrators and usage permissions (ensure your EKS service role can use it)
CLI:
# Create the key
aws kms create-key \
--description "KMS key for EKS secrets encryption" \
--region us-east-1
# Create an alias for easier reference
aws kms create-alias \
--alias-name alias/eks-secrets-key \
--target-key-id <key-id-from-previous-command> \
--region us-east-1
AWS Console Method
- Open the Amazon EKS console at https://console.aws.amazon.com/eks
- Select your cluster from the list
- Go to the Overview tab
- Find the Secrets encryption section
- Click Enable
- Choose your KMS key from the dropdown (or enter the key ARN)
- Click Enable to confirm
The encryption process runs in the background. Your cluster remains available during this operation.
AWS CLI (optional)
Use the associate-encryption-config command to enable KMS encryption on an existing cluster:
aws eks associate-encryption-config \
--cluster-name <your-cluster-name> \
--encryption-config '[{"resources":["secrets"],"provider":{"keyArn":"arn:aws:kms:us-east-1:<account-id>:key/<key-id>"}}]' \
--region us-east-1
Replace:
<your-cluster-name>with your EKS cluster name<account-id>with your AWS account ID<key-id>with your KMS key ID
Check the update status:
aws eks describe-update \
--cluster-name <your-cluster-name> \
--update-id <update-id-from-previous-command> \
--region us-east-1
The status will show InProgress initially, then Successful when complete.
CloudFormation (optional)
When creating a new EKS cluster with CloudFormation, include the EncryptionConfig property:
AWSTemplateFormatVersion: '2010-09-09'
Description: EKS Cluster with KMS encryption for secrets
Parameters:
ClusterName:
Type: String
Default: my-eks-cluster
KMSKeyArn:
Type: String
Description: ARN of the KMS key for secrets encryption
SubnetIds:
Type: List<AWS::EC2::Subnet::Id>
Description: Subnets for the EKS cluster
ClusterRoleArn:
Type: String
Description: ARN of the EKS cluster IAM role
Resources:
EKSCluster:
Type: AWS::EKS::Cluster
Properties:
Name: !Ref ClusterName
RoleArn: !Ref ClusterRoleArn
ResourcesVpcConfig:
SubnetIds: !Ref SubnetIds
EncryptionConfig:
- Resources:
- secrets
Provider:
KeyArn: !Ref KMSKeyArn
Outputs:
ClusterName:
Value: !Ref EKSCluster
ClusterArn:
Value: !GetAtt EKSCluster.Arn
EncryptionKeyArn:
Value: !GetAtt EKSCluster.EncryptionConfigKeyArn
Important: Changing the EncryptionConfig on an existing CloudFormation-managed cluster requires cluster replacement. For existing clusters, use the AWS CLI method instead.
Terraform (optional)
When creating a new EKS cluster with Terraform, include the encryption_config block:
resource "aws_kms_key" "eks_secrets" {
description = "KMS key for EKS secrets encryption"
deletion_window_in_days = 7
enable_key_rotation = true
tags = {
Purpose = "EKS secrets encryption"
}
}
resource "aws_kms_alias" "eks_secrets" {
name = "alias/eks-secrets-key"
target_key_id = aws_kms_key.eks_secrets.key_id
}
resource "aws_eks_cluster" "main" {
name = "my-eks-cluster"
role_arn = aws_iam_role.eks_cluster.arn
vpc_config {
subnet_ids = var.subnet_ids
}
encryption_config {
resources = ["secrets"]
provider {
key_arn = aws_kms_key.eks_secrets.arn
}
}
depends_on = [
aws_iam_role_policy_attachment.eks_cluster_policy
]
}
For existing clusters: Terraform does not support adding encryption to existing clusters in-place. Use the AWS CLI associate-encryption-config command instead, or import the change after applying it manually.
Verification
After enabling encryption, verify the configuration:
- In the EKS Console, select your cluster and check the Secrets encryption section shows your KMS key ARN
- The status should show as enabled/active
CLI verification
aws eks describe-cluster \
--name <your-cluster-name> \
--region us-east-1 \
--query 'cluster.encryptionConfig'
Expected output shows your encryption configuration:
[
{
"resources": ["secrets"],
"provider": {
"keyArn": "arn:aws:kms:us-east-1:<account-id>:key/<key-id>"
}
}
]
If the output is null or empty, encryption is not enabled.
Additional Resources
- AWS EKS Enable KMS Encryption Guide
- AWS Encryption Best Practices for EKS
- AWS KMS Key Management
- Kubernetes Secrets Best Practices
Notes
- Encryption is one-way: Once enabled, you cannot disable secrets encryption on a cluster.
- Existing secrets: After enabling encryption, existing secrets are encrypted on the next write. To encrypt all existing secrets immediately, you can trigger a rewrite by updating each secret.
- KMS key permissions: The EKS cluster service role must have permissions to use the KMS key (
kms:Encrypt,kms:Decrypt,kms:CreateGrant). - Key availability: If the KMS key is deleted or becomes unavailable, you will lose access to encrypted secrets. Use key policies and deletion protection carefully.
- Regional requirement: The KMS key must be in the same AWS region as the EKS cluster.
- Cost: KMS key usage incurs charges. See AWS KMS pricing for details.