Kubernetes Secrets Are Encrypted Using CMKs Managed In AWS
More Info:
Enable envelope encryption of Kubernetes secrets using a customer master key (CMK) in AWS KMS so that secrets are encrypted at rest with a customer-managed key.
Risk Level
High
Address
Security
Compliance Standards
- CIS EKS
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
Identify the cluster and its region
- From any machine with AWS CLI configured, list clusters and their regions:
aws eks list-clusters --region us-east-1aws eks list-clusters --region us-west-2# repeat for other regions you use
- Note the exact
clusterNameandregionyou need to assess.
- From any machine with AWS CLI configured, list clusters and their regions:
-
Check if envelope encryption with a CMK is enabled for the cluster
- On any machine with AWS CLI access, run:
aws eks describe-cluster \--name your-cluster-name \--region your-region \--query 'cluster.encryptionConfig' \--output json
- If the result is
nullor an empty list[], Kubernetes secrets are not encrypted with a CMK. - If it returns an array, confirm there is an entry with
resourcescontaining"secrets"and a non-emptyprovider.keyArn.
- On any machine with AWS CLI access, run:
-
Verify the KMS key configuration and ownership
- Still on any machine with AWS CLI access, for each
keyArnreported above, get details:aws kms describe-key \--key-id arn:aws:kms:your-region:your-account-id:key/your-key-id \--region your-region - Confirm:
KeyStateisEnabled.KeyManagerisCUSTOMER(indicates a customer-managed CMK, not AWS-managed).- The key policy allows the EKS cluster IAM role or node IAM role to use the key.
- Still on any machine with AWS CLI access, for each
-
Decide compliance status
- Cluster is compliant with this control if:
encryptionConfigincludesresources: ["secrets"](or includessecrets), andprovider.keyArnrefers to anEnabledCMK withKeyManager: CUSTOMER.
- Cluster is non-compliant if:
encryptionConfigis missing, orsecretsis not listed as a resource, or- The key is AWS-managed (not customer-managed), or
- The key is disabled.
- Cluster is compliant with this control if:
-
Plan remediation for a non-compliant cluster (high-level)
- Because EKS only allows enabling secrets encryption with a CMK at cluster creation time, you cannot turn this on for an existing cluster in-place.
- For non-compliant clusters, plan to:
- Create a new CMK in AWS KMS with appropriate key policy.
- Recreate the EKS cluster with secrets encryption configured to use that CMK.
- Migrate workloads, data, and secrets from the old cluster to the new, then decommission the old cluster.
-
Document evidence and remediation decision
- Save the output of the
describe-clusteranddescribe-keycommands as audit evidence. - Record for each cluster:
- Whether secrets encryption with a customer-managed CMK is enabled.
- Which CMK is used and its status.
- Your remediation plan and target timeline if the cluster is non-compliant.
- Save the output of the
Using kubectl
kubectl cannot configure EKS secrets envelope encryption with AWS KMS CMKs because this setting is part of the managed control-plane configuration at cluster creation time. To remediate this finding, use the AWS console/CLI/IaC as described in the Manual Steps section to create a new cluster with secrets encryption enabled.
Automation
#!/usr/bin/env bash
#
# Report whether EKS clusters have Kubernetes Secrets encrypted with a
# customer-managed AWS KMS key (CMK).
#
# REQUIREMENTS:
# - AWS CLI v2 configured with sufficient permissions
# - jq
#
# SCOPE:
# - This runs from any machine with AWS CLI access.
# - It inspects all EKS clusters in the specified region(s).
set -euo pipefail
REGIONS="${*:-}"
if [ -z "$REGIONS" ]; then
echo "Usage: $0 <region-1> [region-2] ..."
echo "Example: $0 us-east-1 us-west-2"
exit 1
fi
for REGION in $REGIONS; do
echo "=== Region: $REGION ==="
CLUSTERS=$(aws eks list-clusters --region "$REGION" --output json | jq -r '.clusters[]?')
if [ -z "$CLUSTERS" ]; then
echo " No EKS clusters found."
continue
fi
for CLUSTER in $CLUSTERS; do
echo " Cluster: $CLUSTER"
DESC=$(aws eks describe-cluster --region "$REGION" --name "$CLUSTER" --output json)
# Extract encryption config for secrets provider
ENC_CFG=$(echo "$DESC" | jq -c '.cluster.encryptionConfig[]? | select(.resources[]? == "secrets")')
if [ -z "$ENC_CFG" ]; then
echo " status: NON-COMPLIANT - no encryptionConfig for secrets (no KMS envelope encryption)."
continue
fi
# There may be multiple keyArn entries; report them all
KEY_ARNS=$(echo "$ENC_CFG" | jq -r '.provider.keyArn // empty')
if [ -z "$KEY_ARNS" ]; then
echo " status: NON-COMPLIANT - secrets encryptionConfig present but no KMS keyArn found."
continue
fi
# For each key, determine whether it is customer-managed or AWS-managed
while IFS= read -r KEY_ARN; do
if [ -z "$KEY_ARN" ]; then
continue
fi
# Describe the KMS key
KEY_DESC=$(aws kms describe-key --region "$REGION" --key-id "$KEY_ARN" --output json 2>/dev/null || true)
if [ -z "$KEY_DESC" ]; then
echo " status: REVIEW - KMS key $KEY_ARN not describable (check permissions/existence)."
continue
fi
KEY_MANAGER=$(echo "$KEY_DESC" | jq -r '.KeyMetadata.KeyManager')
KEY_STATE=$(echo "$KEY_DESC" | jq -r '.KeyMetadata.KeyState')
KEY_USAGE=$(echo "$KEY_DESC" | jq -r '.KeyMetadata.KeyUsage')
# KeyManager:
# - 'CUSTOMER' => customer-managed CMK (desired)
# - 'AWS' => AWS-managed key (not compliant with CMK requirement)
if [ "$KEY_MANAGER" = "CUSTOMER" ] && [ "$KEY_STATE" = "Enabled" ] && [ "$KEY_USAGE" = "ENCRYPT_DECRYPT" ]; then
echo " status: COMPLIANT - secrets encrypted with CUSTOMER-managed CMK:"
echo " keyArn: $KEY_ARN"
echo " keyState: $KEY_STATE"
echo " keyUsage: $KEY_USAGE"
else
echo " status: NON-COMPLIANT - secrets encryption uses non-CUSTOMER CMK or unusable key:"
echo " keyArn: $KEY_ARN"
echo " keyManager:$KEY_MANAGER (expected: CUSTOMER)"
echo " keyState: $KEY_STATE (expected: Enabled)"
echo " keyUsage: $KEY_USAGE (expected: ENCRYPT_DECRYPT)"
fi
done <<< "$KEY_ARNS"
done
done
Explanation of output to review:
-
status: COMPLIANT- Secrets encryption is enabled for the cluster, and the KMS key used is customer-managed (
KeyManagerisCUSTOMER), enabled, and usable forENCRYPT_DECRYPT.
- Secrets encryption is enabled for the cluster, and the KMS key used is customer-managed (
-
status: NON-COMPLIANT - no encryptionConfig for secrets- The cluster has no envelope encryption configured for Kubernetes Secrets. This violates the control.
-
status: NON-COMPLIANT - secrets encryptionConfig present but no KMS keyArn found- Misconfigured cluster; manually inspect in the AWS console or via
aws eks describe-cluster.
- Misconfigured cluster; manually inspect in the AWS console or via
-
status: NON-COMPLIANT - secrets encryption uses non-CUSTOMER CMK or unusable key- Secrets encryption exists, but:
- Uses an AWS-managed key (
KeyManager: AWS), or - Uses a disabled key (
KeyStatenotEnabled), or - Uses a key not configured for
ENCRYPT_DECRYPT.
- Uses an AWS-managed key (
- This does not satisfy the requirement for a customer-managed CMK.
- Secrets encryption exists, but:
-
status: REVIEW - KMS key ... not describable- The script cannot determine the key details. Check IAM permissions and the key’s region/account, then review manually.
Because this control is marked MANUAL and encryption can only be enabled at cluster creation time, this script is for visibility and review; bringing non-compliant clusters into compliance requires recreating them with Secrets Encryption configured to use a customer-managed KMS key.