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

# Sagemaker Notebook Instance Should Be Encrypted With KMS Customer Managed Keys

### More Info:

Sagemaker Notebook Instance should be encrypted with KMS Customer Managed Keys

### Risk Level

High

### Address

Security

### Compliance Standards

* APRA CPS 234 (Australia)
* 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)
* ISO 27001
* ISO/IEC 27018
* ISO/IEC 27701
* MAS Technology Risk Management (Singapore)
* MITRE ATT\&CK (Cloud)
* NIST SP 800-171
* NYDFS 23 NYCRR 500
* SOC2
* SWIFT Customer Security Controls Framework
* Sarbanes-Oxley IT General Controls
* UK NCSC Cyber Assessment Framework

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        To remediate this in the AWS Management Console, you’ll usually need to create a new notebook instance that uses a customer-managed KMS key (CMK); the KMS key cannot be changed on an existing instance.

        ### 1. Create or Identify a Customer-Managed KMS Key

        1. Sign in to the AWS Management Console.
        2. Go to **Key Management Service (KMS)**.
        3. In the left pane, choose **Customer managed keys**.
        4. Choose **Create key** (if you don’t already have a CMK you want to use):
           * **Key type**: Symmetric.
           * **Key usage**: Encrypt and decrypt.
           * Configure **Key administrators** and **Key users** (include IAM roles/users used by SageMaker).
           * Finish the wizard and note the **Key ID** or **ARN**.

        Make sure the SageMaker execution role has permissions to use this key (via KMS key policy or IAM).

        ***

        ### 2. Capture Configuration of Existing Notebook (for recreation)

        1. Go to **Amazon SageMaker** in the console.
        2. In the left pane, choose **Notebook instances**.
        3. Click your existing notebook instance.
        4. Note:
           * **Instance type**
           * **VPC / subnets / security groups** (if used)
           * **IAM role**
           * **Lifecycle configuration** (if any)
           * **Volume size**
           * Any other relevant settings.

        If you have important data in the notebook’s EBS volume, back it up (e.g., sync to S3 from the notebook).

        ***

        ### 3. Create a New Notebook Instance Encrypted with CMK

        1. In **SageMaker Console** → **Notebook instances** → click **Create notebook instance**.
        2. Set:
           * **Notebook instance name**: A new name (or plan to rename later).
           * **Notebook instance type**: Same as old (or as desired).
           * **IAM role**: Same role as the old notebook (if appropriate).
           * **VPC**, **subnets**, **security groups**: Match the previous configuration if used.
           * **Volume size in GB**: Same or larger.
        3. Under **Encryption key – optional**:
           * Choose **Enter a KMS key ID or choose from your AWS KMS keys**.
           * Select the **customer-managed KMS key** created/identified in step 1.
        4. Configure **Lifecycle configuration** if needed.
        5. Click **Create notebook instance** and wait for the status to become **InService**.

        ***

        ### 4. Migrate Data (If Needed)

        1. Open the **old** notebook instance and ensure any notebooks/data are copied to S3 (or another storage), if you haven’t already.
        2. Open the **new** KMS-encrypted notebook.
        3. Pull your data back from S3 (or other backup location) into the new instance as required.

        ***

        ### 5. Decommission the Unencrypted Notebook

        1. In **SageMaker Console** → **Notebook instances**.
        2. Select the **old** notebook instance.
        3. Click **Stop** and wait until it is stopped.
        4. Once confirmed that all needed data has been migrated, select the old instance and choose **Delete**.

        Your SageMaker notebook workload is now running on an instance whose EBS volume is encrypted using a customer-managed KMS key.
      </Accordion>

      <Accordion title="Using CLI">
        Below are step‑by‑step AWS CLI instructions to ensure a SageMaker notebook instance is encrypted with a **customer-managed KMS key (CMK)**.

        Important limitation:\
        You **cannot modify** the KMS key of an existing SageMaker notebook instance. You must **create a new notebook instance** with a CMK and migrate any data.

        ***

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

        If you already have a CMK you want to use, skip to step 2.

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

        Get the KeyId or ARN from the output, or list keys:

        ```bash theme={null}
        aws kms list-keys
        ```

        Describe the key to confirm:

        ```bash theme={null}
        aws kms describe-key --key-id <KEY_ID_OR_ARN>
        ```

        You’ll use `<KEY_ARN>` or `<KEY_ID>` in `--kms-key-id` later.

        ***

        ## 2. (Optional but recommended) Update the CMK key policy for SageMaker use

        Give SageMaker (and your users/roles) permission to use the key. Example key policy snippet (you’d merge this into your CMK’s key policy):

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

        Apply via:

        ```bash theme={null}
        aws kms put-key-policy \
          --key-id <KEY_ID_OR_ARN> \
          --policy-name default \
          --policy file://kms-policy.json
        ```

        ***

        ## 3. Stop and delete the existing unencrypted notebook instance

        First, stop it:

        ```bash theme={null}
        aws sagemaker stop-notebook-instance \
          --notebook-instance-name <OLD_NOTEBOOK_NAME>
        ```

        Wait until status is `Stopped`:

        ```bash theme={null}
        aws sagemaker describe-notebook-instance \
          --notebook-instance-name <OLD_NOTEBOOK_NAME> \
          --query 'NotebookInstanceStatus'
        ```

        Then delete:

        ```bash theme={null}
        aws sagemaker delete-notebook-instance \
          --notebook-instance-name <OLD_NOTEBOOK_NAME>
        ```

        > Ensure any notebooks are saved to S3 or source control; the EBS volume will be lost.

        ***

        ## 4. Create a new SageMaker notebook instance encrypted with CMK

        ```bash theme={null}
        aws sagemaker create-notebook-instance \
          --notebook-instance-name <NEW_NOTEBOOK_NAME> \
          --instance-type ml.t3.medium \
          --role-arn arn:aws:iam::<ACCOUNT_ID>:role/<SAGEMAKER_EXECUTION_ROLE> \
          --kms-key-id <KEY_ID_OR_ARN> \
          --volume-size-in-gb 50
        ```

        (Adjust `--instance-type`, `--volume-size-in-gb`, and add any other options you used previously, such as `--security-group-ids`, `--subnet-id`, `--tags`, `--lifecycle-config-name`, etc.)

        Start the notebook:

        ```bash theme={null}
        aws sagemaker start-notebook-instance \
          --notebook-instance-name <NEW_NOTEBOOK_NAME>
        ```

        ***

        ## 5. Verify the notebook is using the CMK

        ```bash theme={null}
        aws sagemaker describe-notebook-instance \
          --notebook-instance-name <NEW_NOTEBOOK_NAME> \
          --query 'KmsKeyId'
        ```

        You should see the CMK ARN/ID you provided.

        ***

        ## 6. Migrate notebooks/data (if needed)

        If you had notebook files in the old instance:

        * If they were in S3: point your new notebook to the same S3 buckets.
        * If they were only on the old EBS volume and you didn’t back them up, they are not recoverable after deletion.\
          For future, use:
          * Git integration (from the notebook UI) or
          * Sync to S3 (e.g., `aws s3 sync` from a terminal in the notebook).

        ***

        These steps ensure the SageMaker notebook instance’s EBS volume is encrypted with your KMS customer-managed key using AWS CLI.
      </Accordion>

      <Accordion title="Using Python">
        Below are practical, step‑by‑step instructions and Python (boto3) snippets to ensure a SageMaker notebook instance is encrypted with a **customer managed KMS key**.

        ### Key points up front

        * The `KmsKeyId` of a SageMaker **notebook instance** cannot be changed in place.
        * To remediate:
          1. Create or identify a **KMS CMK**.
          2. Create a **new** notebook instance with `KmsKeyId` specified.
          3. Migrate any data from the old instance (S3, Git, or manual copy) and then delete the old one.

        ***

        ## 1. Prerequisites

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

        ```python theme={null}
        import boto3

        region = "us-east-1"
        sagemaker = boto3.client("sagemaker", region_name=region)
        kms = boto3.client("kms", region_name=region)
        ```

        ***

        ## 2. Create or identify a customer managed KMS key

        If you already have a CMK, skip to step 3.

        ```python theme={null}
        response = kms.create_key(
            Description="CMK for SageMaker Notebook Encryption",
            KeyUsage="ENCRYPT_DECRYPT",
            Origin="AWS_KMS"
        )
        cmk_id = response["KeyMetadata"]["KeyId"]
        print("Created CMK:", cmk_id)

        # (Optional) give it an alias
        kms.create_alias(
            AliasName="alias/sagemaker-notebook-cmk",
            TargetKeyId=cmk_id
        )
        ```

        You can later refer to this key via either `cmk_id` or `alias/sagemaker-notebook-cmk`.

        ***

        ## 3. Verify existing notebook’s encryption (to identify non‑compliant ones)

        ```python theme={null}
        notebook_name = "your-existing-notebook-name"

        nb_desc = sagemaker.describe_notebook_instance(
            NotebookInstanceName=notebook_name
        )

        print("KmsKeyId:", nb_desc.get("KmsKeyId"))  # None or empty = not using CMK
        ```

        If `KmsKeyId` is missing or using the default AWS managed key (rather than your CMK), it’s non‑compliant.

        ***

        ## 4. Create a new encrypted notebook instance with KMS CMK

        You **must** specify `KmsKeyId` at creation time:

        ```python theme={null}
        kms_key_id = "alias/sagemaker-notebook-cmk"  # or the raw KeyId/ARN

        response = sagemaker.create_notebook_instance(
            NotebookInstanceName="encrypted-notebook-instance",
            InstanceType="ml.t3.medium",
            RoleArn="arn:aws:iam::123456789012:role/SageMakerExecutionRole",
            KmsKeyId=kms_key_id,
            # Optional: other properties
            VolumeSizeInGB=50,
            DirectInternetAccess="Enabled",
            SubnetId="subnet-xxxxxx",         # if using VPC
            SecurityGroupIds=["sg-xxxxxx"],   # if using VPC
            Tags=[
                {"Key": "Name", "Value": "encrypted-notebook-instance"},
                {"Key": "Security", "Value": "KMS-CMK-encrypted"},
            ],
        )

        print("New notebook ARN:", response["NotebookInstanceArn"])
        ```

        Then start it:

        ```python theme={null}
        sagemaker.start_notebook_instance(
            NotebookInstanceName="encrypted-notebook-instance"
        )
        ```

        ***

        ## 5. Migrate content from old notebook to new

        Common approaches (not strictly Python, but required for remediation):

        1. **If work is in S3** (recommended):
           * Configure the old notebook to save notebooks and data to S3.
           * In the new notebook, open from the same S3 location.
        2. **Git-based projects**:
           * Commit/push from the old notebook.
           * Clone/pull in the new notebook.
        3. **Direct copy** (manual):
           * From the old notebook UI, download `.ipynb` and data.
           * Upload to the new notebook.

        If you want to script S3 copy from your local machine (assuming everything is in S3):

        ```python theme={null}
        s3 = boto3.resource("s3")

        source_bucket = "old-notebook-bucket"
        dest_bucket   = "new-notebook-bucket"

        for obj in s3.Bucket(source_bucket).objects.all():
            src = {"Bucket": source_bucket, "Key": obj.key}
            s3.Object(dest_bucket, obj.key).copy_from(CopySource=src)
        ```

        ***

        ## 6. Stop and delete the old, unencrypted notebook

        ```python theme={null}
        old_notebook_name = "your-existing-notebook-name"

        # Stop if running
        sagemaker.stop_notebook_instance(
            NotebookInstanceName=old_notebook_name
        )

        waiter = sagemaker.get_waiter("notebook_instance_stopped")
        waiter.wait(NotebookInstanceName=old_notebook_name)

        # Delete
        sagemaker.delete_notebook_instance(
            NotebookInstanceName=old_notebook_name
        )
        ```

        ***

        ## 7. (Optional) Enforce CMK encryption for all future notebooks

        You can run a simple Python check and auto‑remediate by creating compliant replacements for non‑compliant notebooks:

        ```python theme={null}
        paginator = sagemaker.get_paginator("list_notebook_instances")
        kms_key_required = "alias/sagemaker-notebook-cmk"

        for page in paginator.paginate():
            for nb in page["NotebookInstances"]:
                name = nb["NotebookInstanceName"]
                desc = sagemaker.describe_notebook_instance(NotebookInstanceName=name)
                if not desc.get("KmsKeyId"):
                    print(f"Non-compliant notebook: {name}")
                    # Here you can trigger your own create/migrate/delete workflow
        ```

        ***

        If you share:

        * how your notebooks are currently storing data (S3 path, EBS only, or Git), and
        * whether you need an automated remediation script or a one-time migration,

        I can provide a more specific Python script tailored to your setup.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
