Skip to main content

Secrets Should Be Encrypted At Rest

More Info:

Advisory: EncryptionConfiguration with a KMS provider should be enabled for Secret resources so etcd does not store secrets in plaintext.

Risk Level

High

Address

Security

Compliance Standards

  • Cloudanix Best Practice

Triage and Remediation

Remediation

Manual Steps
  1. Identify the cluster and region

    • From any machine with AWS CLI access:
      aws eks list-clusters --region us-east-1
      aws eks describe-cluster --region us-east-1 --name YOUR_CLUSTER_NAME \
      --query 'cluster.{name:name,arn:arn,version:version}' --output table
  2. Check if EKS secret envelope encryption is enabled (console)

    • In the AWS Management Console:
      1. Go to Amazon EKSClusters → select YOUR_CLUSTER_NAME.
      2. Open the Configuration tab → Security section.
      3. Look for Secret encryption / Envelope encryption.
        • If a KMS key is listed and status is Enabled, secrets are encrypted at rest.
        • If it shows Not enabled or no KMS key, encryption is not configured.
  3. Check if EKS secret envelope encryption is enabled (CLI/IaC evidence)

    • From any machine with AWS CLI access:
      aws eks describe-cluster --region us-east-1 --name YOUR_CLUSTER_NAME \
      --query 'cluster.encryptionConfig' --output json
    • Interpretation:
      • You should see an entry where resources includes "secrets" and a provider.keyArn is present.
      • If encryptionConfig is empty or missing "secrets", EKS envelope encryption for Secrets is not enabled.
  4. Decide on remediation and KMS key strategy

    • If encryption is not enabled or does not cover secrets, decide:
      • Which customer-managed KMS key to use (or create a new CMK).
        aws kms list-keys --region us-east-1
        aws kms describe-key --region us-east-1 --key-id KMS_KEY_ID \
        --query 'KeyMetadata.{KeyId:KeyId,Arn:Arn,KeyState:KeyState,KeyManager:KeyManager}' --output table
      • Ensure the KMS key policy allows the EKS cluster IAM role to use kms:Encrypt, kms:Decrypt, kms:GenerateDataKey*, and kms:DescribeKey.
  5. Apply or update encryption configuration (IaC / CLI / console)

    • Note: For EKS, envelope encryption for secrets must be specified at cluster creation time or by recreating the cluster; you cannot toggle it in-place on an existing cluster.
    • If encryption is missing and policy permits recreation, create or recreate the cluster with encryption enabled, for example using AWS CLI:
      aws eks create-cluster \
      --region us-east-1 \
      --name YOUR_CLUSTER_NAME \
      --kubernetes-version 1.30 \
      --role-arn arn:aws:iam::ACCOUNT_ID:role/EKSClusterRole \
      --resources-vpc-config subnetIds=subnet-AAAAAAA,subnet-BBBBBBB,securityGroupIds=sg-CCCCCCC \
      --encryption-config '[{"resources":["secrets"],"provider":{"keyArn":"arn:aws:kms:us-east-1:ACCOUNT_ID:key/KMS_KEY_ID"}}]'
    • If using CloudFormation/Terraform, ensure the EKS cluster resource includes an encryptionConfig (or equivalent) block specifying resources = ["secrets"] and a KMS key ARN.
  6. Verify encryption is correctly configured after change

    • From any machine with AWS CLI access:
      aws eks describe-cluster --region us-east-1 --name YOUR_CLUSTER_NAME \
      --query 'cluster.encryptionConfig' --output json
    • Confirm there is at least one entry with "resources": ["secrets"] (or that includes "secrets") and a valid "provider": {"keyArn": "arn:aws:kms:...:key/..."}.
Using kubectl

kubectl cannot configure EKS envelope encryption with KMS, because this setting is applied at the EKS cluster control-plane level via the AWS console, CLI, or IaC, not through Kubernetes API objects. Refer to the Manual Steps section for how to enable EKS secrets encryption with a KMS key.

Automation
#!/usr/bin/env bash
#
# Check EKS secret encryption-at-rest status for multiple clusters.
# Requirements:
# - aws CLI configured with sufficient permissions
# - kubectl configured (only used to show context mapping; not needed for the check)
# Usage examples:
# ./check-eks-secret-encryption.sh
# AWS_PROFILE=prod ./check-eks-secret-encryption.sh
#

set -euo pipefail

# Optional: limit to specific regions by setting REGIONS env var: "us-east-1 us-west-2"
if [[ -n "${REGIONS:-}" ]]; then
REGIONS_LIST=(${REGIONS})
else
REGIONS_LIST=($(aws ec2 describe-regions --query 'Regions[].RegionName' --output text))
fi

echo "PROFILE: ${AWS_PROFILE:-default}"
echo "REGIONS: ${REGIONS_LIST[*]}"
echo

for region in "${REGIONS_LIST[@]}"; do
echo "=== Region: ${region} ==="
clusters=$(aws eks list-clusters --region "$region" --query 'clusters' --output text || true)

if [[ -z "$clusters" ]]; then
echo " (no clusters)"
echo
continue
fi

for cluster in $clusters; do
echo " Cluster: ${cluster}"

desc_json=$(aws eks describe-cluster \
--name "$cluster" \
--region "$region" \
--output json)

# Extract encryption details
enabled=$(echo "$desc_json" | jq -r '.cluster.encryptionConfig != null')
if [[ "$enabled" != "true" ]]; then
echo " EncryptionConfig: NONE <-- PROBLEM: secrets NOT encrypted at rest"
echo
continue
fi

# Show all resources that are encrypted and KMS key info
echo "$desc_json" | jq -r '
.cluster.encryptionConfig[] as $cfg |
" EncryptionConfig:\n" +
" resources: \(.resources | join(", "))\n" +
" provider.kmsKeyArn: \($cfg.provider.keyArn)"'

# Specifically check whether "secrets" are covered
has_secrets=$(echo "$desc_json" | jq -r '
.cluster.encryptionConfig[]
| select(.resources[] | ascii_downcase == "secrets")
| 1' 2>/dev/null || echo "0")

if [[ "$has_secrets" == "1" ]]; then
echo " Status: secrets encryption ENABLED (KMS provider in use)"
else
echo " Status: secrets encryption NOT ENABLED <-- PROBLEM: etcd stores secrets in plaintext"
fi

echo
done
done

Explanation of output indicating a problem:

  • Line: EncryptionConfig: NONE <-- PROBLEM: secrets NOT encrypted at rest

    • The EKS cluster has no encryptionConfig configured at all. etcd is storing all secrets in plaintext.
  • Line: Status: secrets encryption NOT ENABLED <-- PROBLEM: etcd stores secrets in plaintext

    • The cluster has some envelope/KMS encryption configured, but secrets is not listed under resources. Kubernetes Secret objects are not encrypted at rest in etcd and must be addressed via the EKS console/CLI/IaC.