> ## 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.

# Ensure Kubernetes Secrets Are Encrypted Using CMKs Managed In AWS KMS

### 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

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Identify the cluster and its region**
           * From any machine with AWS CLI configured, list clusters and their regions:
             ```bash theme={null}
             aws eks list-clusters --region us-east-1
             aws eks list-clusters --region us-west-2
             # repeat for other regions you use
             ```
           * Note the exact `clusterName` and `region` you need to assess.

        2. **Check if envelope encryption with a CMK is enabled for the cluster**
           * On any machine with AWS CLI access, run:
             ```bash theme={null}
             aws eks describe-cluster \
               --name your-cluster-name \
               --region your-region \
               --query 'cluster.encryptionConfig' \
               --output json
             ```
           * If the result is `null` or an empty list `[]`, Kubernetes secrets are **not** encrypted with a CMK.
           * If it returns an array, confirm there is an entry with `resources` containing `"secrets"` and a non-empty `provider.keyArn`.

        3. **Verify the KMS key configuration and ownership**
           * Still on any machine with AWS CLI access, for each `keyArn` reported above, get details:
             ```bash theme={null}
             aws kms describe-key \
               --key-id arn:aws:kms:your-region:your-account-id:key/your-key-id \
               --region your-region
             ```
           * Confirm:
             * `KeyState` is `Enabled`.
             * `KeyManager` is `CUSTOMER` (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.

        4. **Decide compliance status**
           * Cluster is **compliant** with this control if:
             * `encryptionConfig` includes `resources: ["secrets"]` (or includes `secrets`), and
             * `provider.keyArn` refers to an `Enabled` CMK with `KeyManager: CUSTOMER`.
           * Cluster is **non-compliant** if:
             * `encryptionConfig` is missing, or
             * `secrets` is not listed as a resource, or
             * The key is AWS-managed (not customer-managed), or
             * The key is disabled.

        5. **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.

        6. **Document evidence and remediation decision**
           * Save the output of the `describe-cluster` and `describe-key` commands 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.
      </Accordion>

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

      <Accordion title="Automation">
        ```bash theme={null}
        #!/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 (`KeyManager` is `CUSTOMER`), enabled, and usable for `ENCRYPT_DECRYPT`.

        * `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`.

        * `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 (`KeyState` not `Enabled`), or
            * Uses a key not configured for `ENCRYPT_DECRYPT`.
          * This does not satisfy the requirement for a customer-managed CMK.

        * `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.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
