> ## 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 Not Have Direct Internet Access

### More Info:

SageMaker Notebook Instance should not have direct internet access

### Risk Level

Medium

### 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 remove direct internet access from a SageMaker Notebook Instance via the AWS Console, you must:

        1. **Ensure the notebook runs inside a VPC without direct internet access**
        2. **Use VPC endpoints so it can still reach required AWS services (S3, SageMaker, etc.)**

        Below are concise step‑by‑step instructions.

        ***

        ## 1. Prepare a Private VPC Environment (if you don’t already have one)

        You need:

        * A VPC
        * Private subnets (no route to an Internet Gateway)
        * Optional: NAT Gateway (if you still want outbound internet for package installs; if you want *no* internet at all, skip NAT)

        ### 1.1 Check or Create VPC and Subnets

        1. Go to **VPC Console** → **Your VPCs**.
        2. Use an existing VPC or click **Create VPC**.
        3. In **Subnets**, make sure you have at least one subnet that:
           * Does **not** have a route to an **Internet Gateway**.
           * Optionally has a route to a **NAT Gateway** (if limited outbound internet is acceptable).
           * Has DNS support/hostnames enabled at the VPC level (for endpoints).

        To confirm subnet is private:

        1. Go to **Route Tables**, find the route table associated with that subnet.
        2. Ensure there is **no route** like `0.0.0.0/0` → `igw-xxxx`.
           * If present, remove/edit this route for the private subnet or create a separate private route table.

        ***

        ## 2. Create VPC Endpoints for Required AWS Services

        To let the notebook access AWS services without internet:

        1. Go to **VPC Console** → **Endpoints** → **Create endpoint**.

        ### 2.1 S3 Gateway Endpoint

        1. **Service category**: AWS services
        2. **Service name**: `com.amazonaws.<region>.s3` (type: Gateway)
        3. **VPC**: select your VPC.
        4. **Route tables**: select the route tables used by your private subnets.
        5. **Policy**: use **Full access** (or a custom restrictive one).
        6. Click **Create endpoint**.

        ### 2.2 Interface Endpoints (PrivateLink)

        Repeat **Create endpoint** for each:

        * `com.amazonaws.<region>.sagemaker.api`
        * `com.amazonaws.<region>.sagemaker.runtime`
        * `com.amazonaws.<region>.sagemaker.notebook`
        * `com.amazonaws.<region>.sts`
        * Optionally:
          * `com.amazonaws.<region>.logs` (CloudWatch Logs)
          * `com.amazonaws.<region>.monitoring` (CloudWatch Metrics)
          * `com.amazonaws.<region>.ecr.api` and `ecr.dkr` (if using custom images)

        For each:

        1. **Service category**: AWS services.
        2. **Service name**: pick the specific interface service.
        3. **VPC**: select your VPC.
        4. **Subnets**: select the private subnets where notebooks will run.
        5. **Security group**: choose or create an SG that allows:
           * Inbound from notebook instance SG on TCP 443.
           * Outbound to anywhere or at least to the VPC.
        6. Click **Create endpoint**.

        ***

        ## 3. Configure Security Groups

        1. Go to **VPC Console** → **Security groups**.
        2. For the notebook’s security group:
           * **Outbound**: allow HTTPS (TCP 443) to the VPC CIDR or `0.0.0.0/0` (traffic stays inside via endpoints).
           * **Inbound**: typically not required from internet; SageMaker proxy handles access. Keep it restrictive.

        Ensure endpoints’ security groups allow **inbound** from the notebook SG on port 443.

        ***

        ## 4. Update an Existing SageMaker Notebook Instance

        1. Go to **Amazon SageMaker Console**.
        2. In left menu, select **Notebook instances**.
        3. Select your notebook instance.
        4. Click **Stop** and wait until status is **Stopped**.
        5. With it selected, click **Edit** (or **Update settings** depending on console version).

        In the edit screen:

        * **Network**:
          * **VPC**: select your prepared VPC.
          * **Subnets**: choose a **private subnet** (no direct IGW route).
          * **Security group**: select the SG configured above.

        * **Direct internet access**:
          * Set to **Disable**.

        6. Save the changes.
        7. After configuration updates, click **Start** to start the instance.

        ***

        ## 5. Create a New Notebook Instance with No Direct Internet

        If creating new instead of updating:

        1. In SageMaker Console → **Notebook instances** → **Create notebook instance**.
        2. Fill in instance name and type.
        3. Under **Network**:
           * **VPC**: choose your VPC.
           * **Subnets**: choose your private subnet.
           * **Security group**: select the configured SG.
        4. Under **Permissions and encryption**, choose an appropriate IAM role.
        5. Under **Network** or **Additional configuration**:
           * **Direct internet access**: set to **Disable**.
        6. Click **Create notebook instance**.

        ***

        ## 6. Validate

        1. Start the notebook and open Jupyter/JupyterLab from the console.
        2. Confirm:
           * It can access S3 buckets (e.g., list objects via boto3).
           * It cannot reach arbitrary public internet (e.g., `!ping google.com` should fail if no NAT/internet).
           * SageMaker operations (training, inference) still work via endpoints.

        This configuration ensures the notebook instance itself has **no direct internet access**, and all required AWS service access goes through **VPC endpoints**.
      </Accordion>

      <Accordion title="Using CLI">
        You can’t turn off **DirectInternetAccess** on an existing SageMaker notebook instance. You must create a new notebook instance with internet access disabled and move your workloads to it, then delete the old one.

        Below are step‑by‑step AWS CLI instructions.

        ***

        ### 1. Identify the notebook instance and its current settings

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

        Note down:

        * `NotebookInstanceName`
        * `RoleArn`
        * `InstanceType`
        * `SubnetId`
        * `SecurityGroups`
        * `VolumeSizeInGB`
        * `NotebookInstanceLifecycleConfigName` (if any)
        * `KmsKeyId` (if any)

        ***

        ### 2. Ensure you have a VPC subnet and security group without direct internet

        Requirements for *no direct internet access*:

        * Notebook must be in a **VPC** (`--subnet-id` and `--security-group-ids`).
        * No route in the subnet’s route table directly to an **internet gateway**.
        * If outbound access is needed, use a **NAT gateway** or **VPC endpoints** (e.g., for S3, SageMaker API, etc.), not an internet gateway.

        Check the route table for your subnet:

        ```bash theme={null}
        aws ec2 describe-route-tables \
          --filters "Name=association.subnet-id,Values=<SUBNET_ID>"
        ```

        Ensure there is no route like:

        ```text theme={null}
        DestinationCidrBlock: 0.0.0.0/0
        GatewayId: igw-xxxxxxxx
        ```

        If such a route exists, either:

        * Use a different subnet without an IGW route, or
        * Adjust the route table (e.g., point 0.0.0.0/0 to a NAT gateway instead of an IGW), depending on your network design.

        ***

        ### 3. Create a new notebook instance with DirectInternetAccess disabled

        Use `--direct-internet-access Disabled` and specify VPC parameters:

        ```bash theme={null}
        aws sagemaker create-notebook-instance \
          --notebook-instance-name <NEW_NOTEBOOK_NAME> \
          --instance-type <INSTANCE_TYPE_FROM_OLD> \
          --role-arn <ROLE_ARN_FROM_OLD> \
          --subnet-id <PRIVATE_SUBNET_ID> \
          --security-group-ids <SECURITY_GROUP_ID_1> <SECURITY_GROUP_ID_2> \
          --volume-size-in-gb <VOLUME_SIZE_FROM_OLD> \
          --direct-internet-access Disabled \
          --kms-key-id <KMS_KEY_ID_FROM_OLD_OR_OMIT> \
          --notebook-instance-lifecycle-config-name <LIFECYCLE_CONFIG_FROM_OLD_OR_OMIT> \
          --no-root-access
        ```

        Notes:

        * Omit flags whose values you don’t need (e.g., `--kms-key-id`, `--notebook-instance-lifecycle-config-name`).
        * `--no-root-access` is optional but often a good security practice; you can remove it if you require root access.

        Wait for it to be ready:

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

        ***

        ### 4. Migrate notebooks / code

        From the old instance:

        * Download notebooks and data, or
        * Push them to S3, Git, or CodeCommit.

        From the new instance:

        * Pull notebooks from S3 or your repo, or upload them.

        (There is no CLI “clone with DirectInternetAccess change”, so manual migration of notebooks is required.)

        ***

        ### 5. Stop and delete the old notebook instance

        Stop:

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

        aws sagemaker wait notebook-instance-stopped \
          --notebook-instance-name <OLD_NOTEBOOK_NAME>
        ```

        Delete:

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

        ***

        ### 6. Validate that the new notebook has no direct internet access

        Describe:

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

        Output should be:

        ```text theme={null}
        "Disabled"
        ```

        Optionally, from inside the notebook, test that:

        * You cannot reach public internet directly (e.g., `ping 8.8.8.8` or `curl https://google.com` fails), and
        * You can reach necessary AWS services via VPC endpoints or NAT (e.g., access to S3 buckets used by SageMaker).
      </Accordion>

      <Accordion title="Using Python">
        To remove direct internet access from a SageMaker notebook via Python, you need to:

        1. **Ensure VPC access is in place** (subnet + security group + VPC endpoints)
        2. **Update or recreate the notebook instance with `DirectInternetAccess='Disabled'`**

        Below are concise step-by-step instructions and Python/boto3 examples.

        ***

        ## 1. Prerequisites (VPC Setup – one-time)

        You must have:

        * A **VPC** with at least one **private subnet** (no direct route to an Internet Gateway).
        * A **security group** that allows needed traffic (typically to internal resources or endpoints).
        * **VPC endpoints** for services the notebook needs, most importantly:
          * S3 interface or gateway endpoint
          * SageMaker API/Runtime endpoints if needed
          * Other services as needed (e.g., CloudWatch Logs, ECR, STS)

        Example: create S3 VPC endpoint (one-time, from a privileged environment, not necessarily in code below):

        ```python theme={null}
        import boto3

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

        response = ec2.create_vpc_endpoint(
            VpcEndpointType='Gateway',
            VpcId='vpc-xxxxxxxx',
            ServiceName='com.amazonaws.us-east-1.s3',
            RouteTableIds=['rtb-xxxxxxxx']
        )
        print(response['VpcEndpoint']['VpcEndpointId'])
        ```

        Adjust IDs/region as needed. Do similar for other endpoints (CloudWatch, STS, etc.) as required.

        ***

        ## 2. Disable Direct Internet Access for an **Existing** Notebook

        You can change an existing notebook’s internet access configuration using `update_notebook_instance`.

        **Important:**

        * You must **stop** the notebook before updating.
        * Notebook must already (or after update) be attached to a **subnet and security group** so it can function without direct internet.

        ### 2.1. Stop the notebook instance

        ```python theme={null}
        import boto3

        region = "us-east-1"
        notebook_name = "my-notebook-instance"

        sm = boto3.client("sagemaker", region_name=region)

        sm.stop_notebook_instance(NotebookInstanceName=notebook_name)

        # Optionally: wait until it stops
        waiter = sm.get_waiter('notebook_instance_stopped')
        waiter.wait(NotebookInstanceName=notebook_name)
        ```

        ### 2.2. Update notebook instance to disable direct internet

        If the notebook is **already** configured with a subnet and security group, you can just flip `DirectInternetAccess`:

        ```python theme={null}
        sm.update_notebook_instance(
            NotebookInstanceName=notebook_name,
            DirectInternetAccess='Disabled'
        )
        ```

        If it is **not** yet in a VPC, you must attach it:

        ```python theme={null}
        subnet_id = "subnet-xxxxxxxx"      # private subnet
        security_group_ids = ["sg-xxxxxxxx"]

        sm.update_notebook_instance(
            NotebookInstanceName=notebook_name,
            DirectInternetAccess='Disabled',         # key flag
            SubnetId=subnet_id,
            SecurityGroupIds=security_group_ids
        )
        ```

        Then start it again:

        ```python theme={null}
        sm.start_notebook_instance(NotebookInstanceName=notebook_name)
        ```

        ***

        ## 3. Create a New Notebook With No Direct Internet Access

        If you’re provisioning new notebooks, set `DirectInternetAccess='Disabled'` at creation time and attach to your private subnet/security group.

        ```python theme={null}
        import boto3

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

        notebook_name = "my-no-internet-notebook"
        role_arn = "arn:aws:iam::123456789012:role/SageMakerExecutionRole"
        subnet_id = "subnet-xxxxxxxx"               # private subnet
        security_group_ids = ["sg-xxxxxxxx"]

        sm.create_notebook_instance(
            NotebookInstanceName=notebook_name,
            InstanceType="ml.t3.medium",
            RoleArn=role_arn,
            SubnetId=subnet_id,
            SecurityGroupIds=security_group_ids,
            DirectInternetAccess='Disabled',         # CRITICAL SETTING
            VolumeSizeInGB=10,
            Tags=[
                {"Key": "Environment", "Value": "prod"}
            ]
        )
        ```

        Optionally, wait until it’s `InService`:

        ```python theme={null}
        waiter = sm.get_waiter('notebook_instance_in_service')
        waiter.wait(NotebookInstanceName=notebook_name)
        ```

        ***

        ## 4. Verify Configuration

        Use `describe_notebook_instance` to confirm:

        ```python theme={null}
        info = sm.describe_notebook_instance(NotebookInstanceName=notebook_name)
        print(info["DirectInternetAccess"])  # should be 'Disabled'
        print(info.get("SubnetId"), info.get("SecurityGroups"))
        ```

        ***

        **Summary in one line:**

        Use `boto3.client('sagemaker').update_notebook_instance(..., DirectInternetAccess='Disabled', SubnetId=..., SecurityGroupIds=[...])` (after stopping the notebook) and ensure required VPC endpoints exist so the notebook can function without direct internet.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
