> ## 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 Should Be Encrypted By Default

### More Info:

Ensure that your Amazon Secrets Manager secrets (i.e. database credentials, API keys, OAuth tokens, etc) are encrypted at rest using AWS KMS, as AWS Secrets Manager automatically encrypts every secret value using envelope encryption with a KMS key by default, in order to guarantee that sensitive data is protected at the storage level and meets baseline compliance requirements for data-at-rest encryption.

### Risk Level

High

### Address

Security

### Compliance Standards

* APRA CPS 234 (Australia)
* AWS Startup Security Baseline
* BSI C5 (Germany)
* Brazil LGPD
* CCPA / CPRA (California)
* CIS Critical Security Controls v8
* CMMC 2.0
* CSA Cloud Controls Matrix v4
* DPDPA
* Digital Operational Resilience Act (EU)
* Essential 8
* HIPAA
* ISO 27001
* ISO/IEC 27017
* ISO/IEC 27018
* ISO/IEC 27701
* KSA PDPL
* MAS Technology Risk Management (Singapore)
* MITRE ATT\&CK (Cloud)
* NIS2 Directive
* NIST CSF
* NIST SP 800-171
* NYDFS 23 NYCRR 500
* PCI
* SWIFT Customer Security Controls Framework
* Sarbanes-Oxley IT General Controls
* Securities and Exchange Board of India (SEBI) - Cloud Security Adoption Framework
* UK NCSC Cyber Assessment Framework

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        In AWS, Secrets Manager secrets are always encrypted; remediation usually means **ensuring they use a customer-managed AWS KMS key** instead of the default AWS-managed key.

        Below are step‑by‑step instructions using the AWS Console.

        ***

        ## 1. Create (or identify) a customer-managed KMS key

        1. Sign in to the **AWS Management Console**.
        2. Go to **AWS Key Management Service (KMS)**:
           * In the search bar, type **KMS** and select **Key Management Service**.
        3. In the left navigation pane, choose **Customer managed keys**.
        4. Click **Create key**.
        5. Key type: select **Symmetric** and **Encrypt and decrypt**.
        6. Click **Next**.
        7. Add an **Alias** (e.g., `alias/secretsmanager-default`).
        8. Configure **Key administrators** and **Key users**:
           * Ensure the IAM roles/users and the **Secrets Manager service role** (if you use one) that will access the secrets are added as **Key users**.
        9. Complete the wizard by clicking **Finish**.

        Note the **Key ID** or **Alias**; you’ll need it when assigning to secrets.

        ***

        ## 2. Update existing secrets to use the KMS CMK

        You must do this per secret.

        1. Go to **AWS Secrets Manager** in the console.
        2. On the **Secrets** page, click the secret you want to remediate.
        3. On the secret’s details page, click **Edit**.
        4. In the **Encryption key** section:
           * Change from the default (e.g., `aws/secretsmanager`) to your **customer-managed KMS key** (e.g., `alias/secretsmanager-default`).
        5. Scroll down and click **Save**.

        Repeat for all existing secrets that should use the customer-managed KMS key.

        ***

        ## 3. Ensure new secrets are encrypted with the CMK by default (process-wise)

        There is no global “default CMK” switch for Secrets Manager; you enforce it by process or IaC. Using the console:

        1. When you **create a new secret** in Secrets Manager:
           * On the **Store a new secret** page, in the **Encryption key** dropdown, select your **customer-managed KMS key**.
        2. Complete the secret creation as usual.

        To make this “by default” in practice:

        * Update internal runbooks so all admins select the CMK.
        * If you use CloudFormation/Terraform, set `KmsKeyId` to your CMK in those templates so all programmatically created secrets use that key automatically.

        ***

        This remediation ensures all Secrets Manager secrets are encrypted with a **customer-managed AWS KMS key**, satisfying controls that require non-default or customer-managed encryption.
      </Accordion>

      <Accordion title="Using CLI">
        In AWS Secrets Manager, all secrets are always encrypted, but by default they use the AWS managed key `aws/secretsmanager`. To meet a “Secret Manager should be encrypted by default (with KMS CMK)” requirement, you typically must:

        1. Create or identify a customer-managed KMS key.
        2. Ensure all new secrets are created with that key.
        3. Re‑encrypt existing secrets to use that key.

        Below are the AWS CLI steps.

        ***

        ### 1. Create a customer-managed KMS key (if you don’t already have one)

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

        Note the `"KeyId"` from the output (for example: `arn:aws:kms:us-east-1:111122223333:key/abcd-...`).

        Optionally give it an alias:

        ```bash theme={null}
        aws kms create-alias \
          --alias-name alias/secretsmanager-default \
          --target-key-id <YOUR_KEY_ID_OR_ARN>
        ```

        ***

        ### 2. Use the CMK when creating new secrets

        When creating a secret, specify `--kms-key-id` (either the key ARN or alias):

        ```bash theme={null}
        aws secretsmanager create-secret \
          --name my/secure/secret \
          --secret-string 'SuperSecretValue' \
          --kms-key-id alias/secretsmanager-default
        ```

        This ensures the secret is encrypted by your CMK rather than `aws/secretsmanager`.

        If you’re using automation (CloudFormation, Terraform, pipelines, etc.), update those definitions to always pass the CMK.

        ***

        ### 3. Re-encrypt existing secrets with the CMK

        List your secrets:

        ```bash theme={null}
        aws secretsmanager list-secrets --output json
        ```

        For each secret that is not using your CMK, update it:

        ```bash theme={null}
        aws secretsmanager update-secret \
          --secret-id <SECRET_ID_OR_ARN> \
          --kms-key-id alias/secretsmanager-default
        ```

        You can script it, for example (bash):

        ```bash theme={null}
        KMS_KEY_ID="alias/secretsmanager-default"

        aws secretsmanager list-secrets --output json \
          | jq -r '.SecretList[].ARN' \
          | while read SECRET_ARN; do
              aws secretsmanager describe-secret --secret-id "$SECRET_ARN" --output json \
              | jq -r '.KmsKeyId' | grep -q "$KMS_KEY_ID"
              if [ $? -ne 0 ]; then
                echo "Updating $SECRET_ARN to use $KMS_KEY_ID"
                aws secretsmanager update-secret \
                  --secret-id "$SECRET_ARN" \
                  --kms-key-id "$KMS_KEY_ID"
              fi
            done
        ```

        (Requires `jq`.)

        ***

        ### 4. Ensure IAM permissions and key policy allow usage

        Make sure principals that manage/use secrets can use the CMK:

        Example key policy snippet (attach/update via `put-key-policy` or console):

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

        And allow your admins/automation roles to use the CMK as well.

        ***

        These steps ensure Secrets Manager secrets are encrypted by a customer-managed KMS key by default and remediate the “Secret Manager should be encrypted by default (AWS KMS)” finding.
      </Accordion>

      <Accordion title="Using Python">
        In AWS Secrets Manager, every secret is encrypted with KMS, but many checks require that you use a **customer-managed KMS key (CMK)** instead of the default `aws/secretsmanager` key.\
        Remediation with Python (boto3) is:

        1. **Prerequisites**
           * Python 3.x
           * `boto3` installed:
             ```bash theme={null}
             pip install boto3
             ```
           * IAM permissions:
             * `secretsmanager:ListSecrets`, `secretsmanager:DescribeSecret`, `secretsmanager:UpdateSecret`
             * `kms:DescribeKey`, `kms:CreateKey`, `kms:ListAliases`

        ***

        ### Step 1: Choose or create a KMS key

        Either use an existing CMK or create one. Example to create a CMK and alias via Python:

        ```python theme={null}
        import boto3

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

        # Create a new KMS CMK
        response = kms.create_key(
            Description='CMK for encrypting Secrets Manager secrets',
            KeyUsage='ENCRYPT_DECRYPT',
            Origin='AWS_KMS'
        )
        key_id = response['KeyMetadata']['KeyId']
        print("Created KMS Key:", key_id)

        # Optional: create a friendly alias
        kms.create_alias(
            AliasName='alias/secretsmanager-default-kms',
            TargetKeyId=key_id
        )
        print("Created alias: alias/secretsmanager-default-kms")
        ```

        You can then reference the key as either `key_id` or `arn` or the alias `alias/secretsmanager-default-kms`.

        ***

        ### Step 2: Find secrets not using your CMK

        This script:

        * Lists all secrets
        * Checks if their `KmsKeyId` is set and whether it matches your target CMK
        * Prints the ones that need remediation

        ```python theme={null}
        import boto3

        region = 'us-east-1'
        target_kms_key_id = 'alias/secretsmanager-default-kms'  # or full KeyId/ARN of your CMK

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

        paginator = secrets_client.get_paginator('list_secrets')

        secrets_to_update = []

        for page in paginator.paginate():
            for secret in page.get('SecretList', []):
                arn = secret['ARN']
                name = secret['Name']
                kms_key_id = secret.get('KmsKeyId')  # None = default aws/secretsmanager

                if kms_key_id != target_kms_key_id:
                    print(f"Secret {name} ({arn}) is not using target KMS key.")
                    secrets_to_update.append(arn)

        print("Total secrets to update:", len(secrets_to_update))
        ```

        ***

        ### Step 3: Re-encrypt each secret with the desired CMK

        Use `UpdateSecret` with `KmsKeyId`. This causes Secrets Manager to re-encrypt the secret value with the new KMS key.

        ```python theme={null}
        for secret_arn in secrets_to_update:
            try:
                print(f"Updating secret {secret_arn} to use KMS key {target_kms_key_id}")
                secrets_client.update_secret(
                    SecretId=secret_arn,
                    KmsKeyId=target_kms_key_id
                )
            except Exception as e:
                print(f"Failed to update {secret_arn}: {e}")
        ```

        This remediates existing secrets by ensuring they are encrypted with your customer-managed KMS key.

        ***

        ### Step 4: Create new secrets always using your CMK (default behavior in code)

        When creating new secrets in Python, always specify `KmsKeyId`:

        ```python theme={null}
        response = secrets_client.create_secret(
            Name='my-secure-secret',
            Description='Secret that uses CMK by default',
            SecretString='{"username":"admin","password":"P@ssw0rd"}',
            KmsKeyId=target_kms_key_id  # enforce CMK on creation
        )
        print("Created secret:", response['ARN'])
        ```

        To make this “default” in your environment:

        * Ensure all IaC/templates and application code that call Secrets Manager **always** pass `KmsKeyId=<your CMK>`.
        * Optionally enforce via code review, CI checks, or policy tools (e.g., CloudFormation Guard, Terraform rules).
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        resource "aws_kms_key" "SECRETS_KMS_KEY" {
          description         = "KMS CMK for encrypting Secrets Manager secrets"
          enable_key_rotation = true
          # Optionally scope key policy to principals that should manage/use this key
          # policy = DATA.aws_iam_policy_document.SE CRETS_KMS_POLICY.json
        }

        resource "aws_secretsmanager_secret" "SECRET_RESOURCE_NAME" {
          name        = "SECRET_NAME" # replace with your secret name
          description = "DESCRIPTION_OF_SECRET"

          # Ensure the secret is encrypted with AWS KMS (customer-managed key)
          kms_key_id = aws_kms_key.SECRETS_KMS_KEY.arn
        }
        ```

        Changing `kms_key_id` on an existing `aws_secretsmanager_secret` is an in-place update and should not force replacement of the secret or cause downtime.

        Verification: `terraform plan` should show an in-place update (`~`) on the existing `aws_secretsmanager_secret.SECRET_RESOURCE_NAME` resource, with `kms_key_id` changing from `null` or the previous key ARN to the ARN of `aws_kms_key.SECRETS_KMS_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)
