Skip to main content
emnode
Compliance High severity

AWS Security Hub · SageMaker

SageMaker.2: A SageMaker notebook is not launched in a VPC

Written and reviewed by Emnode · Last reviewed

What does AWS Security Hub SageMaker.2 check?

SageMaker.2 fails when a notebook instance is not launched into a VPC subnet you control. A notebook created without a specified subnet lands in the SageMaker service VPC, outside your account's network entirely.

Why does SageMaker.2 matter?

A notebook in the service VPC escapes every network control you own: no security group you manage applies to it, no VPC flow logs capture its traffic, and yet it can still carry an IAM role with access to sensitive S3 data. For auditors it is unevidenceable: you cannot prove a workspace is contained when it sits outside any boundary you control.

How do I fix SageMaker.2?

  1. Audit notebook instances for a missing or empty subnet to find the ones in the service VPC.
  2. Because the VPC assignment is immutable, commit any in-progress work, then stop and delete the notebook.
  3. Recreate it in a private subnet with a security group, and add the VPC endpoints (S3, STS, SageMaker API) it needs to keep functioning.
  4. Make a custom subnet the default in your notebook templates so new instances never land in the service VPC.

Remediation script · bash

# Disable root across every notebook that has it on (mutable on a stopped instance).
for n in $(aws sagemaker list-notebook-instances \
    --query 'NotebookInstances[].NotebookInstanceName' --output text); do
  root=$(aws sagemaker describe-notebook-instance --notebook-instance-name "$n" \
    --query 'RootAccess' --output text)
  if [ "$root" = "Enabled" ]; then
    aws sagemaker stop-notebook-instance --notebook-instance-name "$n"
    aws sagemaker wait notebook-instance-stopped --notebook-instance-name "$n"
    aws sagemaker update-notebook-instance --notebook-instance-name "$n" --root-access Disabled
    aws sagemaker start-notebook-instance --notebook-instance-name "$n"
    echo "$n: root access disabled"
  fi
done

# Immutable settings need a rebuild. Recreate a notebook locked down: private subnet,
# no direct internet. (DirectInternetAccess and SubnetId cannot be changed in place.)
aws sagemaker create-notebook-instance \
  --notebook-instance-name ml-feature-exploration \
  --instance-type ml.t3.medium \
  --role-arn arn:aws:iam::111122223333:role/SageMakerExecution \
  --subnet-id subnet-0ab12cd34ef56 \
  --security-group-ids sg-0aa11bb22cc33 \
  --direct-internet-access Disabled \
  --root-access Disabled

Full walkthrough (console steps, edge cases and verification) in the lesson Harden SageMaker and ML workloads.

Is SageMaker.2 a false positive?

There is no benign way to pass this control while failing it: a notebook is either in a subnet you own or in the SageMaker service VPC, and the latter is never the intended state for a workspace carrying an IAM role. The honest gap is the reverse: a notebook can sit in a custom subnet and still pass SageMaker.2 while reaching the internet through a NAT gateway, so passing here does not mean the notebook is contained (that is SageMaker.1's job). If you must keep a service-VPC notebook for a short-lived migration, suppress the finding with a dated workflow status and a comment naming the cutover date rather than treating the pass as network containment.

Part of the learning path Lock down access