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

# AWS KMS Customer Master Keys For EFS Encryption

### More Info:

Ensure that your Amazon EFS file systems are encrypted using KMS CMK customer-managed keys instead of AWS managed-keys (default keys used by the EFS service when there are no customer keys defined) in order to have more granular control over your data-at-rest encryption/decryption process.

### Risk Level

High

### Address

Security

### Compliance Standards

GDPR,NIST

### Remediation

How to enable EFS Encryption with Customer Master Keys

#### Using AWS Console

1. Log in to the AWS Management Console using your AWS account credentials.
2. Navigate to the Amazon EFS service by selecting "EFS" from the services menu.
   (In the Cloudanix Console, navigate to "Misconfig" page and look for Affected Assets for "AWS KMS Customer Master Keys For EFS Encryption" Policy.)
3. In the EFS dashboard, select the EFS file system for which you want to enable encryption with CMK.
4. In the file system details page, click on the "Actions" button and select "Modify file system."
5. In the "Modify file system" dialog box, scroll down to the "Encryption" section.
6. Select the option "Use customer managed CMK (AWS Key Management Service)" for encryption.
7. Choose the desired CMK from the "Customer managed CMK" dropdown menu. Make sure the CMK has the appropriate permissions.
8. Optionally, you can enable the "Encrypt data in transit" option to encrypt data in transit as well.
9. Click on the "Save" button to apply the encryption settings to the EFS file system.
10. AWS will start the process of encrypting the data at rest using the specified CMK.
11. Monitor the progress of the encryption process in the EFS dashboard.
12. Once the encryption process is complete, the EFS file system will be encrypted using the customer-managed key.

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        The control name you quoted — **“AWS KMS Customer Master Keys For EFS Encryption”** — applies to **Amazon EFS**, not API Gateway. You *cannot* fix that specific finding in API Gateway; it’s about how your **EFS file systems** are encrypted.

        Below are the concise steps to remediate this in the **AWS Console** by ensuring EFS uses a **customer-managed KMS key (CMK)** instead of the default AWS-managed key.

        > Important: You cannot change the KMS key of an existing EFS file system. You must create a new, encrypted file system with a CMK and migrate data.

        ***

        ## 1. Create a Customer-Managed KMS Key

        1. In the AWS Console, go to **Key Management Service (KMS)**.
        2. In the left pane, choose **Customer managed keys**.
        3. Click **Create key**.
        4. Key type: **Symmetric** → Next.
        5. Set **Alias** (e.g., `alias/efs-cmk-prod`) and optional description → Next.
        6. Choose key administrators and key users (IAM roles/users that EFS and your apps use).
        7. Review and click **Finish**.

        Note the CMK ARN (e.g., `arn:aws:kms:region:account-id:key/key-id`).

        ***

        ## 2. Create a New EFS File System Using the CMK

        1. In the AWS Console, go to **EFS**.
        2. Click **Create file system**.
        3. In the **General** settings page:
           * Set **Name**.
           * Under **Encryption**, ensure **Enable encryption of data at rest** is ON.
           * For **KMS key**, select **Choose from your AWS KMS keys** and pick your new CMK (e.g., `alias/efs-cmk-prod`).
        4. Configure VPC, availability zones, and mount targets as required.
        5. Complete the wizard by clicking **Create**.

        This file system is now encrypted with your customer-managed key.

        ***

        ## 3. Migrate Data From Old EFS (If Applicable)

        If you already had an unencrypted or AWS-managed-key EFS file system:

        1. Mount **both**:
           * Old EFS file system.
           * New CMK-encrypted EFS file system.
        2. Use a copy/sync tool from an EC2 instance (or container) that has both file systems mounted:
           * Basic example:
             ```bash theme={null}
             rsync -aHAX --info=progress2 /mnt/old-efs/ /mnt/new-efs/
             ```
        3. Update all applications / services / mount targets to point to the **new EFS file system**.
        4. After verification, delete the old EFS file system in the **EFS** console.

        ***

        ## 4. (Optional) Restrict the CMK for EFS Use

        In **KMS → Customer managed keys**:

        1. Select your CMK.
        2. Go to the **Key policy** tab.
        3. Ensure that:
           * EFS service (and your IAM roles/users) have `kms:Encrypt`, `kms:Decrypt`, `kms:GenerateDataKey`, etc.
           * Access is limited to the required principals only.
        4. Save policy.

        ***

        If what you actually need is encryption/KMS configuration for **API Gateway** assets (e.g., logs in CloudWatch, KMS for custom domain certs, etc.), specify the exact security finding or resource type and I’ll list the steps for that separately.
      </Accordion>

      <Accordion title="Using CLI">
        AWS API Gateway does not use EFS or KMS directly; EFS is typically attached to Lambda functions that API Gateway invokes. The KMS misconfiguration is on the EFS file system itself, not on API Gateway.

        To remediate “AWS KMS Customer Master Keys For EFS Encryption” with AWS CLI, you must:

        1. create/use a customer-managed KMS key,
        2. create a new EFS encrypted with that CMK,
        3. migrate data,
        4. update any Lambda functions (invoked by API Gateway) to mount the new EFS.

        Below are step‑by‑step CLI instructions.

        ***

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

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

        Capture the KeyId or ARN from the output, e.g.:

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

        Optionally give it an alias:

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

        You can then use `alias/efs-cmk` in EFS commands.

        ***

        ### 2. Identify the existing EFS file system to replace

        List EFS file systems:

        ```bash theme={null}
        aws efs describe-file-systems
        ```

        Find the file system currently used by the Lambda(s) behind your API Gateway. Note its `FileSystemId`, e.g.:

        ```text theme={null}
        "FileSystemId": "fs-0123456789abcdef0"
        ```

        Check its encryption configuration:

        ```bash theme={null}
        aws efs describe-file-systems \
          --file-system-id fs-0123456789abcdef0 \
          --query "FileSystems[0].{Encrypted:Encrypted, KmsKeyId:KmsKeyId}"
        ```

        If it’s encrypted with the default AWS-managed key (or incorrectly configured CMK), you must create a new EFS; encryption settings cannot be changed in place.

        ***

        ### 3. Create a new EFS encrypted with the CMK

        ```bash theme={null}
        aws efs create-file-system \
          --creation-token my-efs-with-cmk \
          --encrypted \
          --kms-key-id alias/efs-cmk \
          --performance-mode generalPurpose \
          --throughput-mode bursting
        ```

        Capture the new `FileSystemId`, e.g. `fs-0abcdef1234567890`.

        Create mount targets in the same subnets/security groups used by the original EFS:

        ```bash theme={null}
        aws efs create-mount-target \
          --file-system-id fs-0abcdef1234567890 \
          --subnet-id subnet-aaaabbbb \
          --security-groups sg-11112222

        aws efs create-mount-target \
          --file-system-id fs-0abcdef1234567890 \
          --subnet-id subnet-ccccdddd \
          --security-groups sg-11112222
        ```

        Wait until the mount targets are `available`:

        ```bash theme={null}
        aws efs describe-mount-targets \
          --file-system-id fs-0abcdef1234567890
        ```

        ***

        ### 4. Copy data from old EFS to the new EFS

        From an EC2 instance in the same VPC (or another host that can mount both EFS file systems):

        1. Install the EFS mount helper if needed.
        2. Mount both file systems:

        ```bash theme={null}
        sudo mkdir -p /mnt/old-efs /mnt/new-efs

        sudo mount -t efs fs-0123456789abcdef0:/ /mnt/old-efs
        sudo mount -t efs fs-0abcdef1234567890:/ /mnt/new-efs
        ```

        3. Copy data:

        ```bash theme={null}
        sudo rsync -avz /mnt/old-efs/ /mnt/new-efs/
        ```

        Validate data integrity as required.

        ***

        ### 5. Update Lambda functions (invoked by API Gateway) to use the new EFS

        List Lambda functions that might be using the old EFS:

        ```bash theme={null}
        aws lambda list-functions
        ```

        For each function, inspect its file system configs:

        ```bash theme={null}
        aws lambda get-function-configuration \
          --function-name MyFunction \
          --query "FileSystemConfigs"
        ```

        If it references `fs-0123456789abcdef0`, update it to the new file system id using the existing (or new) access point that points to the new EFS:

        ```bash theme={null}
        aws lambda update-function-configuration \
          --function-name MyFunction \
          --file-system-configs "FileSystemArn=arn:aws:efs:<region>:<account-id>:access-point/fsap-xxxx,LocalMountPath=/mnt/efs"
        ```

        Repeat for all affected functions.

        API Gateway itself does not need changes; it continues to invoke the same Lambda functions.

        ***

        ### 6. Decommission the old EFS

        After confirming all functions work correctly and all data is migrated:

        1. Unmount from any instances.
        2. Delete the old EFS:

        ```bash theme={null}
        aws efs delete-file-system \
          --file-system-id fs-0123456789abcdef0
        ```

        ***

        ### 7. (Optional) Lock down KMS key policy

        Ensure the CMK’s key policy follows least privilege:

        ```bash theme={null}
        aws kms get-key-policy \
          --key-id alias/efs-cmk \
          --policy-name default > key-policy.json
        ```

        Edit `key-policy.json` to restrict access, then:

        ```bash theme={null}
        aws kms put-key-policy \
          --key-id alias/efs-cmk \
          --policy-name default \
          --policy file://key-policy.json
        ```

        This completes remediation: EFS used (indirectly by API Gateway via Lambda) is now encrypted with a customer-managed KMS CMK, configured via AWS CLI.
      </Accordion>

      <Accordion title="Using Python">
        In AWS, **EFS encryption with KMS CMK is unrelated to API Gateway**. EFS is a filesystem used by EC2/Lambda, not by API Gateway directly.

        Assuming the misconfiguration is:

        > “EFS is not encrypted with a customer-managed KMS key (CMK)”

        Below are **step‑by‑step Python (boto3) instructions** to:

        1. Create or reuse a KMS CMK
        2. Create a new encrypted EFS with that CMK
        3. (Optional but common) Move data from an unencrypted EFS to the new encrypted one

        ***

        ## 1. Prerequisites

        ```bash theme={null}
        pip install boto3
        aws configure  # set credentials and region
        ```

        ```python theme={null}
        import boto3

        region = "us-east-1"  # change to your region

        kms = boto3.client("kms", region_name=region)
        efs = boto3.client("efs", region_name=region)
        ```

        ***

        ## 2. Create (or identify) a KMS Customer Managed Key (CMK)

        If you already have a CMK you want to use, skip to step 3.\
        To create a new CMK:

        ```python theme={null}
        response = kms.create_key(
            Description="CMK for EFS encryption",
            KeyUsage="ENCRYPT_DECRYPT",
            Origin="AWS_KMS"
        )

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

        # Optionally add an alias
        kms.create_alias(
            AliasName="alias/efs-cmk",
            TargetKeyId=cmk_id
        )
        ```

        If you’re using an existing CMK alias:

        ```python theme={null}
        cmk_id = "alias/efs-cmk"  # or full KeyId/ARN
        ```

        Make sure the CMK key policy allows the EFS service and your IAM principals to use it for `Encrypt`, `Decrypt`, `GenerateDataKey*`, etc.

        ***

        ## 3. Create a new **encrypted** EFS using the CMK

        EFS encryption at rest can only be enabled at file system creation time; you **cannot turn it on later** for an existing unencrypted file system.

        ```python theme={null}
        response = efs.create_file_system(
            PerformanceMode="generalPurpose",  # or "maxIO"
            Encrypted=True,
            KmsKeyId=cmk_id,
            Tags=[
                {"Key": "Name", "Value": "my-encrypted-efs"}
            ]
        )

        new_fs_id = response["FileSystemId"]
        print("New encrypted EFS:", new_fs_id)
        ```

        You also need mount targets for subnets:

        ```python theme={null}
        subnet_id = "subnet-xxxxxxxx"
        security_group_id = "sg-xxxxxxxx"

        mt_resp = efs.create_mount_target(
            FileSystemId=new_fs_id,
            SubnetId=subnet_id,
            SecurityGroups=[security_group_id]
        )

        print("Mount target:", mt_resp["MountTargetId"])
        ```

        Repeat `create_mount_target` for each AZ where you need access.

        ***

        ## 4. (Optional) Migrate data from an existing unencrypted EFS

        If you already have an **unencrypted** EFS (`old_fs_id`) you must copy data to the new encrypted one. This is done via EC2 or a container, not directly via API:

        High-level steps:

        1. Create/mount both file systems on an EC2 instance.
           * Mount unencrypted EFS to `/mnt/old_efs`
           * Mount new encrypted EFS to `/mnt/new_efs`
        2. Copy data:

        ```bash theme={null}
        sudo rsync -avz /mnt/old_efs/ /mnt/new_efs/
        ```

        3. Update your applications (or Lambda functions) to mount/use the new encrypted EFS.
        4. After verifying, delete the old file system:

        ```python theme={null}
        old_fs_id = "fs-xxxxxxxx"

        efs.delete_file_system(
            FileSystemId=old_fs_id
        )
        ```

        ***

        ## 5. Clarifying the “API Gateway” part

        API Gateway itself doesn’t use EFS or KMS CMKs for its core operation. Common KMS-related controls for API Gateway are typically about:

        * Encrypting **CloudWatch log groups** with a CMK
        * Encrypting **API cache data** (for REST APIs) with a CMK

        If your misconfiguration is actually about **API Gateway logs or cache encryption with KMS**, tell me which one and I’ll give you the exact Python/boto3 steps for that instead.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # KMS CMK used to encrypt EFS (replace KEY ALIAS/NAME and DESCRIPTION)
        resource "aws_kms_key" "efs_cmk" {
          description             = "KMS CMK for encrypting EFS used by API Gateway workloads"
          deletion_window_in_days = 30
          enable_key_rotation     = true

          tags = {
            Name = "EFS-CMK-FOR_API_GATEWAY"
          }
        }

        # EFS file system encrypted with the CMK above
        resource "aws_efs_file_system" "this" {
          creation_token = "EFS_FOR_API_GATEWAY" # replace with a unique token for your EFS
          encrypted      = true
          kms_key_id     = aws_kms_key.efs_cmk.arn

          tags = {
            Name = "EFS_FOR_API_GATEWAY"
          }
        }
        ```

        Changing `encrypted` from `false` to `true` or changing `kms_key_id` on an existing `aws_efs_file_system` forces replacement of the file system, which deletes data unless you migrate it beforehand.

        Verification: `terraform plan` should show `aws_efs_file_system.this` with `encrypted = true` and `kms_key_id` set to the ARN of `aws_kms_key.efs_cmk`, with either a create (new filesystem) or a `-/+` replacement if you are modifying an existing one.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* \[[https://docs.aws.amazon.com/efs/latest/ug/encryption-at-rest.html](https://docs.aws.amazon.com/efs/latest/ug/encryption-at-rest.html)]
