> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 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

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Identify the cluster and region**
           * From any machine with AWS CLI access:
             ```bash theme={null}
             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 EKS** → **Clusters** → 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:
             ```bash theme={null}
             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).
               ```bash theme={null}
               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:
             ```bash theme={null}
             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:
             ```bash theme={null}
             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/..."}`.
      </Accordion>

      <Accordion title="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.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/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.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
