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

# Secret Manager Secrets Should Be Encrypted With CMKs

### More Info:

Ensure that your Amazon Secrets Manager secrets (i.e. database credentials, API keys, OAuth tokens, etc) are encrypted with Amazon KMS Customer Master Keys (CMKs) instead of default encryption keys that Secrets Manager service creates for you, in order to have a more granular control over secret data encryption and decryption process, and meet compliance requirements.

### Risk Level

High

### Address

Security

### Compliance Standards

GDPR, NIST, NISTCSF, PCIDSS

### Remediation

How to ensure secrets manager secrets are encrypted with CMKs

#### Using AWS Console

1. Log in to the AWS Management Console using your AWS account credentials.
2. Navigate to the AWS Secrets Manager service by selecting "Secrets Manager" from the services menu.
3. In the Secrets Manager dashboard, click on "Secrets" in the left navigation pane.
   (In the Cloudanix Console, navigate to "Misconfig" page and look for Affected Assets for "Secret Manager Secrets Should Be Encrypted With CMKs" Policy.)
4. Identify the secrets that are not encrypted with CMKs.
5. Take note of the specific secret identifier(s) that need remediation.
6. Select the checkbox next to the secret(s) you want to remediate.
7. Above the list of secrets, click on the "Edit rotation" button.
8. In the "Configure secret rotation" page, click on the "Edit secret" button.
9. In the "Secret details" section, scroll down to the "Encryption" configuration.
10. Select the option to "Use AWS Key Management Service (KMS) key" for encryption.
11. Choose an appropriate CMK from the dropdown menu or create a new CMK if necessary.
12. Click on the "Save" button to apply the encryption configuration.
13. In the "Configure secret rotation" page, click on the "Next" button.
14. Review and modify the rotation settings as needed and click on the "Next" button.
15. Review the summary of the rotation configuration and click on the "Finish" button.
16. Monitor the rotation process to ensure it is successfully completed for the remediated secrets.
17. Repeat these steps for each secret that is not encrypted with CMKs until all secrets have been remediated.

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        Below are the step‑by‑step remediation instructions using the AWS Management Console so your AWS Secrets Manager secrets are encrypted with **customer‑managed KMS keys (CMKs)** instead of AWS‑managed keys.

        ***

        ## 1. Create (or Identify) a Customer‑Managed KMS Key

        If you don’t already have a CMK for Secrets Manager:

        1. Sign in to the **AWS Management Console** and go to **AWS KMS**
           * Services → **Key Management Service (KMS)**

        2. In the left pane, choose **Customer managed keys**.

        3. Click **Create key**.

        4. Under **Key type**, choose **Symmetric** and **Encryption and decryption**.\
           (This is standard for Secrets Manager.)

        5. Click **Next**.

        6. **Add an alias** (e.g., `alias/secrets-manager-key`).

        7. Configure **Key administrators** (IAM users/roles that can manage the key), then **Next**.

        8. Configure **Key usage permissions**:
           * Add IAM roles/users used by your applications or services that access the secrets.
           * Optionally add the **Secrets Manager** service principal if using resource policies (advanced).

        9. Finish with **Create key**.

        Keep the **Key ID** or **Alias** noted (e.g., `alias/secrets-manager-key`).

        ***

        ## 2. Update Each Secret to Use the CMK

        For each secret currently using the default AWS‑managed key, change it to your CMK:

        1. Go to **AWS Secrets Manager** in the console.
           * Services → **Secrets Manager**

        2. In **Secrets**, click the **secret name** you want to remediate.

        3. On the secret’s details page, choose the **Edit** button.

        4. Scroll down to the **Encryption key** or **KMS key** section.

        5. From the dropdown, select your **customer‑managed CMK**
           * e.g., `alias/secrets-manager-key`.

        6. Review other settings (no change needed for rotation unless desired).

        7. Click **Save**.

        Secrets Manager will re-encrypt the secret with the selected CMK.

        ***

        ## 3. Verify Permissions and Access

        1. Still on the secret details page, use the **Secret value** → **Retrieve secret value** button.
           * If retrieval succeeds for your application role/user, KMS permissions are correct.

        2. If you get an access error:
           * Go back to **KMS → Customer managed keys**.
           * Select your key → **Key policy**.
           * Ensure the application IAM roles/users are allowed `kms:Decrypt` and `kms:GenerateDataKey` on this key.

        ***

        ## 4. (Optional) Enforce Use of CMKs Going Forward

        To avoid regressions:

        1. In your **infrastructure as code** (CloudFormation/Terraform), always specify the `KmsKeyId` for secrets.
        2. In organizational policies (e.g., AWS Config rules, Security Hub controls), flag secrets using AWS‑managed keys instead of CMKs.

        ***

        Repeat step 2 for **all** Secrets Manager secrets flagged by your scanner until each shows your **customer‑managed KMS key** as the encryption key.
      </Accordion>

      <Accordion title="Using CLI">
        Below are minimal, CLI-focused steps to ensure AWS Secrets Manager secrets are encrypted with a customer-managed KMS key (CMK), not the AWS-managed default key.

        ***

        ## 1. Identify Secrets Not Using a CMK

        List all secrets and see which KMS key they use:

        ```bash theme={null}
        aws secretsmanager list-secrets \
          --query 'SecretList[*].[Name,KmsKeyId]' \
          --output table
        ```

        Any secret with `null` or an AWS-managed key (like `aws/secretsmanager`) should be remediated.

        ***

        ## 2. (Optional) Create a Customer-Managed KMS Key (CMK)

        If you don’t already have a CMK:

        ```bash theme={null}
        aws kms create-key \
          --description "CMK for Secrets Manager encryption" \
          --key-usage ENCRYPT_DECRYPT \
          --origin AWS_KMS
        ```

        Capture the `KeyId` from the output, e.g.:

        ```text theme={null}
        "KeyId": "1234abcd-12ab-34cd-56ef-1234567890ab"
        ```

        Optionally, add an alias:

        ```bash theme={null}
        aws kms create-alias \
          --alias-name alias/secretsmanager-cmk \
          --target-key-id 1234abcd-12ab-34cd-56ef-1234567890ab
        ```

        You can use either the `KeyId`, full ARN, or alias ARN (e.g. `arn:aws:kms:region:account-id:alias/secretsmanager-cmk`) in the next step.

        ***

        ## 3. Update Each Secret to Use the CMK

        For a single secret:

        ```bash theme={null}
        aws secretsmanager update-secret \
          --secret-id MySecretNameOrArn \
          --kms-key-id arn:aws:kms:REGION:ACCOUNT_ID:alias/secretsmanager-cmk
        ```

        Or with a direct KeyId:

        ```bash theme={null}
        aws secretsmanager update-secret \
          --secret-id MySecretNameOrArn \
          --kms-key-id 1234abcd-12ab-34cd-56ef-1234567890ab
        ```

        ***

        ## 4. Bulk Remediation (All Secrets Without CMK)

        Example Bash loop to switch all secrets with no `KmsKeyId` to a specific CMK alias:

        ```bash theme={null}
        KMS_KEY_ARN="arn:aws:kms:REGION:ACCOUNT_ID:alias/secretsmanager-cmk"

        for secret in $(aws secretsmanager list-secrets \
          --query "SecretList[?KmsKeyId==null].ARN" \
          --output text); do
          echo "Updating $secret"
          aws secretsmanager update-secret \
            --secret-id "$secret" \
            --kms-key-id "$KMS_KEY_ARN"
        done
        ```

        ***

        ## 5. Verify the Change

        Re-check the KMS key for your secrets:

        ```bash theme={null}
        aws secretsmanager list-secrets \
          --query 'SecretList[*].[Name,KmsKeyId]' \
          --output table
        ```

        Each remediated secret should now show your CMK ARN (or alias ARN) instead of `null` or an AWS-managed key.
      </Accordion>

      <Accordion title="Using Python">
        Below is a concise, step‑by‑step way to ensure AWS Secrets Manager secrets are encrypted with a customer‑managed KMS key (CMK) using Python (boto3).

        ***

        ## 1. Prerequisites

        * Python 3.x
        * `boto3` installed:
          ```bash theme={null}
          pip install boto3
          ```
        * IAM permissions:
          * `kms:CreateKey`, `kms:DescribeKey`, `kms:ListKeys`, `kms:EnableKeyRotation` (if creating/using CMK)
          * `secretsmanager:DescribeSecret`, `secretsmanager:UpdateSecret`, `secretsmanager:ListSecrets`

        ***

        ## 2. Create (or Identify) a Customer-Managed KMS Key

        If you already have a CMK you want to use, note its KeyId or ARN and skip to step 3.

        ### 2.1 Create a CMK with Python

        ```python theme={null}
        import boto3

        kms = boto3.client('kms', region_name='us-east-1')  # adjust region

        response = kms.create_key(
            Description='CMK for Secrets Manager encryption',
            KeyUsage='ENCRYPT_DECRYPT',
            Origin='AWS_KMS'
        )

        cmk_id = response['KeyMetadata']['KeyId']
        print("Created CMK:", cmk_id)

        # (optional) Enable automatic key rotation
        kms.enable_key_rotation(KeyId=cmk_id)
        ```

        Record `cmk_id` or the full ARN (you can use either as `KmsKeyId`).

        ***

        ## 3. Check Existing Secrets for Default AWS-Managed KMS Key

        ```python theme={null}
        import boto3

        secretsmanager = boto3.client('secretsmanager', region_name='us-east-1')

        paginator = secretsmanager.get_paginator('list_secrets')
        for page in paginator.paginate():
            for secret in page['SecretList']:
                name = secret['Name']
                kms_key_id = secret.get('KmsKeyId')
                print(f"Secret: {name}, KmsKeyId: {kms_key_id}")
        ```

        * If `KmsKeyId` is `None`, the secret is using the default AWS-managed key.
        * If it’s set but not your CMK, you’ll want to change it.

        ***

        ## 4. Re-encrypt an Existing Secret with Your CMK

        This changes the KMS key used going forward for all secret versions.

        ```python theme={null}
        import boto3

        region = 'us-east-1'
        cmk_id = 'YOUR_CMK_ID_OR_ARN'   # from step 2
        secret_name = 'YOUR_SECRET_NAME'

        secretsmanager = boto3.client('secretsmanager', region_name=region)

        # (Optional) verify current key
        desc = secretsmanager.describe_secret(SecretId=secret_name)
        print("Current KmsKeyId:", desc.get('KmsKeyId'))

        # Update secret to use CMK
        response = secretsmanager.update_secret(
            SecretId=secret_name,
            KmsKeyId=cmk_id
        )
        print("Updated Secret VersionId:", response['VersionId'])
        ```

        Notes:

        * `update_secret` will cause future encrypt/decrypt operations to use this CMK.
        * Old ciphertext blobs are effectively re‑encrypted when accessed; you do not need to rewrite the secret value.

        ***

        ## 5. Create a New Secret Encrypted with CMK

        ```python theme={null}
        import boto3
        import json

        secretsmanager = boto3.client('secretsmanager', region_name='us-east-1')
        cmk_id = 'YOUR_CMK_ID_OR_ARN'

        secret_name = 'my-app/db-credentials'
        secret_value = {
            "username": "dbuser",
            "password": "dbpass"
        }

        response = secretsmanager.create_secret(
            Name=secret_name,
            KmsKeyId=cmk_id,
            SecretString=json.dumps(secret_value)
        )

        print("Created secret:", response['ARN'])
        ```

        ***

        ## 6. Bulk Remediation: Migrate All Secrets to a CMK

        Example: update every secret currently using the default AWS‑managed key.

        ```python theme={null}
        import boto3

        region = 'us-east-1'
        cmk_id = 'YOUR_CMK_ID_OR_ARN'

        secretsmanager = boto3.client('secretsmanager', region_name=region)

        paginator = secretsmanager.get_paginator('list_secrets')

        for page in paginator.paginate():
            for secret in page['SecretList']:
                secret_id = secret['ARN']
                name = secret['Name']
                kms_key_id = secret.get('KmsKeyId')

                # If no KmsKeyId, it's using AWS-managed default
                if kms_key_id is None:
                    print(f"Updating secret {name} to use CMK {cmk_id}")
                    secretsmanager.update_secret(
                        SecretId=secret_id,
                        KmsKeyId=cmk_id
                    )
        ```

        ***

        ## 7. KMS Key Policy Considerations

        Ensure your CMK key policy allows Secrets Manager and principals that use the secret to use the key:

        Minimal example snippet (KMS key policy statement):

        ```json theme={null}
        {
          "Sid": "AllowSecretsManagerUseOfTheKey",
          "Effect": "Allow",
          "Principal": { "Service": "secretsmanager.amazonaws.com" },
          "Action": [
            "kms:Encrypt",
            "kms:Decrypt",
            "kms:GenerateDataKey",
            "kms:DescribeKey"
          ],
          "Resource": "*"
        }
        ```

        (Also grant your IAM roles/users as needed.)

        ***

        If you tell me how you currently organize your secrets (per app, per environment, etc.), I can adapt the bulk‑remediation script to your naming scheme or tagging strategy.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # Customer-managed KMS key for encrypting Secrets Manager secrets
        resource "aws_kms_key" "secrets_cmk" {
          description             = "CMK for encrypting Secrets Manager secrets"
          enable_key_rotation     = true
          deletion_window_in_days = 30

          # Optional: restrict key usage to Secrets Manager in this account
          policy = data.aws_iam_policy_document.secrets_kms_policy.json
        }

        data "aws_iam_policy_document" "secrets_kms_policy" {
          statement {
            sid     = "AllowAccountUseOfKey"
            effect  = "Allow"
            actions = [
              "kms:Encrypt",
              "kms:Decrypt",
              "kms:ReEncrypt*",
              "kms:GenerateDataKey*",
              "kms:DescribeKey"
            ]

            principals {
              type        = "AWS"
              identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"]
            }

            resources = ["*"]
          }

          statement {
            sid    = "AllowSecretsManagerToUseKey"
            effect = "Allow"
            actions = [
              "kms:Encrypt",
              "kms:Decrypt",
              "kms:ReEncrypt*",
              "kms:GenerateDataKey*",
              "kms:DescribeKey"
            ]

            principals {
              type        = "Service"
              identifiers = ["secretsmanager.amazonaws.com"]
            }

            resources = ["*"]
          }
        }

        data "aws_caller_identity" "current" {}

        # Secrets Manager secret encrypted with the CMK above
        resource "aws_secretsmanager_secret" "example" {
          name        = "SECRET_NAME" # replace with your secret name
          description = "DESCRIPTION_OF_SECRET"

          # Use the customer-managed KMS key instead of the AWS managed default
          kms_key_id = aws_kms_key.secrets_cmk.arn
        }

        # (Optional) secret value
        resource "aws_secretsmanager_secret_version" "example" {
          secret_id     = aws_secretsmanager_secret.example.id
          secret_string = "SECRET_VALUE" # replace with your actual secret value or use sensitive input
        }
        ```

        Changing `kms_key_id` on an existing `aws_secretsmanager_secret` forces replacement of the secret resource in Terraform, which may cause a brief outage if consumers are not updated to the new ARN; plan carefully before applying.

        Verification: `terraform plan` should show creation of `aws_kms_key.secrets_cmk` (if new) and either creation of a new `aws_secretsmanager_secret.example` or an update that replaces it, with `kms_key_id` set to the CMK ARN instead of the default AWS-managed key.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* \[[https://docs.aws.amazon.com/secretsmanager/latest/userguide/security-encryption.html](https://docs.aws.amazon.com/secretsmanager/latest/userguide/security-encryption.html)]
