Sagemaker Models Should Have Network Isolation Enabled
More Info:
Sagemaker Models should have network isolation enabled
Risk Level
Medium
Address
Monitoring, 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
- Remediation
Remediation
Using Console
To enable network isolation for SageMaker models using the AWS Management Console, you must create (or recreate) the model with network isolation turned on. It cannot be enabled on an existing model in-place.
Below are step-by-step instructions.
1. Check the existing model (optional)
- Sign in to the AWS Management Console.
- Go to Amazon SageMaker.
- In the left navigation pane, choose Inference → Models.
- Click on the model name you want to remediate.
- On the Model summary page, check the configuration:
- If the model was created without network isolation, you will need to create a new model with the same settings and network isolation enabled.
2. Create a new model with Network Isolation enabled
-
In the SageMaker console, navigate to Inference → Models.
-
Click Create model.
-
Model details:
- Enter a Model name (e.g.,
my-model-ni-enabled). - Optionally add a Description and Tags.
- Enter a Model name (e.g.,
-
Container:
- Under Container definition, choose:
- Either Use an existing container image (for custom images) or
- Use a SageMaker built-in algorithm (if applicable).
- Specify:
- Container image URI.
- Model artifacts S3 path (e.g.,
s3://bucket/path/to/model.tar.gz).
- If using environment variables or container arguments, re-enter them as used in your previous model.
- Under Container definition, choose:
-
Network Isolation:
- Find the option that says Network isolation or Enable network isolation.
- Check or toggle Enable network isolation.
- This ensures the model container cannot make outbound network calls (only allowed to access its storage volume and input/output for the inference service).
-
IAM role:
- Under Permissions, choose an existing SageMaker execution role with access to your model artifacts in S3 (or create a new one).
- Ensure the role has
s3:GetObjectfor the model artifact location and any other needed permissions.
-
Review the configuration.
-
Click Create model.
3. Update endpoints or endpoint configurations to use the new model
If the model is deployed behind an endpoint, you must update the endpoint configuration to point to the new, network-isolated model.
3.1 Create a new endpoint configuration
- In the SageMaker console, go to Inference → Endpoint configurations.
- Click Create endpoint configuration.
- Enter a Name (e.g.,
my-endpoint-config-ni-enabled). - Under Production variants:
- Click Add model.
- Select the new model you just created (with network isolation).
- Set:
- Variant name
- Instance type
- Initial instance count
- Initial variant weight as required.
- Adjust any other settings (e.g., data capture, async inference) as needed.
- Click Create endpoint configuration.
3.2 Update or create the endpoint
-
If you already have an endpoint:
- Go to Inference → Endpoints.
- Click on your existing endpoint.
- Choose Update (or Update endpoint).
- Select the new endpoint configuration created above.
- Click Update endpoint and wait for the status to become InService.
-
If you don’t have an endpoint yet:
- Go to Inference → Endpoints.
- Click Create endpoint.
- Specify an Endpoint name.
- Select the endpoint configuration you just created.
- Click Create endpoint and wait until it becomes InService.
4. Decommission old models/configurations (optional but recommended)
- Once traffic is confirmed to work through the new endpoint:
- Delete the old endpoint configuration (if unused).
- Delete the old model (without network isolation), if no longer needed.
This ensures all active SageMaker models in use have network isolation enabled.
Using CLI
Below are concise, step‑by‑step steps to remediate this using only AWS CLI.
1. Identify SageMaker models without network isolation
aws sagemaker list-models --region <REGION> \
--query 'Models[].ModelName' --output text
Check each model:
MODEL_NAME=<MODEL_NAME>
aws sagemaker describe-model \
--model-name "$MODEL_NAME" \
--region <REGION> \
--query 'EnableNetworkIsolation'
If this returns false or null, it needs remediation.
2. Get full configuration of the existing model
You must recreate the model; you cannot “update” network isolation in place.
MODEL_NAME=<OLD_MODEL_NAME>
aws sagemaker describe-model \
--model-name "$MODEL_NAME" \
--region <REGION> > model-desc.json
model-desc.json will look roughly like:
{
"ModelName": "my-model",
"PrimaryContainer": { ... },
"Containers": [ ... ],
"ExecutionRoleArn": "arn:aws:iam::123456789012:role/...",
"VpcConfig": { ... },
"EnableNetworkIsolation": false
}
3. Prepare payload for new model with network isolation
Create a new JSON file, e.g. create-model-with-iso.json, keeping everything the same except:
- Use a new
ModelName - Add
"EnableNetworkIsolation": true
Example:
{
"ModelName": "my-model-ni", // new name
"ExecutionRoleArn": "arn:aws:iam::123456789012:role/...",
"PrimaryContainer": { ... }, // copy from describe-model
"VpcConfig": { ... }, // copy if present
"EnableNetworkIsolation": true
}
If your original model used Containers instead of PrimaryContainer, copy that instead.
4. Create the new model with network isolation
aws sagemaker create-model \
--cli-input-json file://create-model-with-iso.json \
--region <REGION>
Verify:
aws sagemaker describe-model \
--model-name "my-model-ni" \
--region <REGION} \
--query 'EnableNetworkIsolation'
# should return: true
5. Point existing endpoints / endpoint configs to the new model
5.1 Find endpoint configs that reference the old model
aws sagemaker list-endpoint-configs --region <REGION> \
--query 'EndpointConfigs[].EndpointConfigName' --output text
For each:
EC_NAME=<ENDPOINT_CONFIG_NAME>
aws sagemaker describe-endpoint-config \
--endpoint-config-name "$EC_NAME" \
--region <REGION} \
--query 'ProductionVariants[].ModelName'
If the output includes <OLD_MODEL_NAME>, you need a new endpoint config.
5.2 Create a new endpoint config using the new model
Export existing config:
EC_NAME=<OLD_ENDPOINT_CONFIG_NAME>
aws sagemaker describe-endpoint-config \
--endpoint-config-name "$EC_NAME" \
--region <REGION> > ec-desc.json
Edit to create create-ec-with-iso.json:
- Change
EndpointConfigName - In
ProductionVariants, replaceModelNamewith the new model name.
Example:
{
"EndpointConfigName": "my-endpoint-config-ni",
"ProductionVariants": [
{
"VariantName": "AllTraffic",
"ModelName": "my-model-ni",
"InitialInstanceCount": 1,
"InstanceType": "ml.m5.large",
"InitialVariantWeight": 1.0
}
],
"KmsKeyId": "..."
}
Create it:
aws sagemaker create-endpoint-config \
--cli-input-json file://create-ec-with-iso.json \
--region <REGION>
5.3 Update the endpoint to use the new endpoint config
ENDPOINT_NAME=<ENDPOINT_NAME>
aws sagemaker update-endpoint \
--endpoint-name "$ENDPOINT_NAME" \
--endpoint-config-name "my-endpoint-config-ni" \
--region <REGION>
Wait until the status is InService:
aws sagemaker describe-endpoint \
--endpoint-name "$ENDPOINT_NAME" \
--region <REGION} \
--query 'EndpointStatus'
6. Clean up old resources (optional but recommended)
After confirming traffic works as expected:
-
Delete old endpoint configs that are no longer used:
aws sagemaker delete-endpoint-config \--endpoint-config-name "<OLD_ENDPOINT_CONFIG_NAME>" \--region <REGION> -
Delete old models:
aws sagemaker delete-model \--model-name "<OLD_MODEL_NAME>" \--region <REGION>
7. Automate for all non‑isolated models (outline)
Script pattern (bash):
for MODEL in $(aws sagemaker list-models --region <REGION> --query 'Models[].ModelName' --output text); do
ISO=$(aws sagemaker describe-model --model-name "$MODEL" --region <REGION> --query 'EnableNetworkIsolation' --output text)
if [ "$ISO" != "True" ]; then
echo "Model $MODEL missing network isolation – migrate manually or via script."
# Insert the create-model + update-endpoint logic here
fi
done
This is the required AWS CLI–based remediation: recreate each SageMaker model with EnableNetworkIsolation=true and repoint any endpoint configs/endpoints to the new model.
Using Python
To enable network isolation on SageMaker models, you must (re)create the model with EnableNetworkIsolation=True. This setting is immutable—you cannot “turn it on” for an existing model in-place. So remediation is:
- Identify models without network isolation
- Recreate those models with
EnableNetworkIsolation=True - (If used in endpoints) create new endpoint configs pointing to the new models and update endpoints
Below is a concise Python/boto3 walkthrough.
1. List models and find ones without network isolation
import boto3
sm = boto3.client("sagemaker")
def list_models():
models = []
next_token = None
while True:
kwargs = {}
if next_token:
kwargs["NextToken"] = next_token
resp = sm.list_models(**kwargs)
models.extend(resp["Models"])
next_token = resp.get("NextToken")
if not next_token:
break
return [m["ModelName"] for m in models]
def models_without_network_isolation():
bad = []
for name in list_models():
desc = sm.describe_model(ModelName=name)
# If key missing, treat as False
if not desc.get("EnableNetworkIsolation", False):
bad.append(desc)
return bad
bad_models = models_without_network_isolation()
print("Models without network isolation:", [m["ModelName"] for m in bad_models])
2. Recreate each model with EnableNetworkIsolation=True
You can clone the existing model definition, add EnableNetworkIsolation=True, and create a new model (recommended: use a new name to avoid endpoint disruption).
def clone_model_with_network_isolation(model_desc, new_model_name=None):
if not new_model_name:
new_model_name = model_desc["ModelName"] + "-ni"
# Build args for create_model from describe_model output
create_args = {
"ModelName": new_model_name,
"ExecutionRoleArn": model_desc["ExecutionRoleArn"],
}
# Optional blocks – only include if present
for key in [
"PrimaryContainer",
"Containers",
"VpcConfig",
"InferenceExecutionConfig",
"Tags",
"EnableNetworkIsolation", # we’ll override below
"ModelKmsKeyId",
"Domain",
"DriftCheckBaselines"
]:
if key in model_desc:
create_args[key] = model_desc[key]
# Force network isolation
create_args["EnableNetworkIsolation"] = True
# Keys that are *only* returned by describe_model and not accepted by create_model
for bad_key in [
"ModelArn", "CreationTime", "LastModifiedTime",
"ResponseMetadata"
]:
create_args.pop(bad_key, None)
resp = sm.create_model(**create_args)
return resp["ModelArn"], new_model_name
for m in bad_models:
arn, new_name = clone_model_with_network_isolation(m)
print(f"Created model {new_name} with network isolation: {arn}")
3. (If the model is used in endpoints) update endpoint configs
If existing endpoints use the old model, you must:
- Create a new endpoint config referencing the new model
- Update the endpoint to use the new config
Example:
def list_endpoint_configs_using_model(model_name):
configs = []
next_token = None
while True:
kwargs = {}
if next_token:
kwargs["NextToken"] = next_token
resp = sm.list_endpoint_configs(**kwargs)
for c in resp["EndpointConfigs"]:
cfg = sm.describe_endpoint_config(
EndpointConfigName=c["EndpointConfigName"]
)
for prod in cfg["ProductionVariants"]:
if prod["ModelName"] == model_name:
configs.append(cfg)
break
next_token = resp.get("NextToken")
if not next_token:
break
return configs
def create_new_endpoint_config_with_model(old_cfg, old_model, new_model):
new_cfg_name = old_cfg["EndpointConfigName"] + "-ni"
new_variants = []
for v in old_cfg["ProductionVariants"]:
v = v.copy()
if v["ModelName"] == old_model:
v["ModelName"] = new_model
new_variants.append(v)
args = {
"EndpointConfigName": new_cfg_name,
"ProductionVariants": new_variants,
}
if "DataCaptureConfig" in old_cfg:
args["DataCaptureConfig"] = old_cfg["DataCaptureConfig"]
if "KmsKeyId" in old_cfg:
args["KmsKeyId"] = old_cfg["KmsKeyId"]
resp = sm.create_endpoint_config(**args)
return new_cfg_name, resp["EndpointConfigArn"]
def update_endpoints_to_new_config(old_cfg_name, new_cfg_name):
# Find endpoints that use old endpoint config
next_token = None
while True:
kwargs = {}
if next_token:
kwargs["NextToken"] = next_token
resp = sm.list_endpoints(**kwargs)
for e in resp["Endpoints"]:
ep = sm.describe_endpoint(EndpointName=e["EndpointName"])
if ep["EndpointConfigName"] == old_cfg_name:
print(f"Updating endpoint {ep['EndpointName']}...")
sm.update_endpoint(
EndpointName=ep["EndpointName"],
EndpointConfigName=new_cfg_name,
)
next_token = resp.get("NextToken")
if not next_token:
break
Tie it together (for one model example):
old_model_name = "my-model"
old_desc = sm.describe_model(ModelName=old_model_name)
_, new_model_name = clone_model_with_network_isolation(old_desc)
cfgs = list_endpoint_configs_using_model(old_model_name)
for cfg in cfgs:
new_cfg_name, _ = create_new_endpoint_config_with_model(
cfg, old_model_name, new_model_name
)
update_endpoints_to_new_config(cfg["EndpointConfigName"], new_cfg_name)
4. Going forward
When creating any new model, always set:
sm.create_model(
ModelName="my-secure-model",
ExecutionRoleArn="arn:aws:iam::123456789012:role/sagemaker-role",
PrimaryContainer={...},
EnableNetworkIsolation=True,
# other params...
)
This ensures the control is satisfied for all future models.
Using Terraform
resource "aws_sagemaker_model" "SAGEMAKER_MODEL_NAME" {
name = "SAGEMAKER_MODEL_NAME" # replace with your model name
execution_role_arn = aws_iam_role.SAGEMAKER_EXECUTION_ROLE.arn
primary_container {
image = "ECR_IMAGE_URI" # replace with your image URI
model_data_url = "S3_MODEL_ARTIFACT" # replace with your model artifact S3 path
}
# Enable network isolation so the model container cannot make outbound network calls
enable_network_isolation = true
}
Substitute:
SAGEMAKER_MODEL_NAMEwith your SageMaker model name.aws_iam_role.SAGEMAKER_EXECUTION_ROLE.arnwith your actual IAM role resource or ARN.ECR_IMAGE_URIwith your container image URI in ECR.S3_MODEL_ARTIFACTwith the S3 URI of your model artifacts.
Changing enable_network_isolation on an existing aws_sagemaker_model forces replacement of the model resource (Terraform will destroy and recreate the model in SageMaker, which may impact any endpoints using it).
Verification: terraform plan should show enable_network_isolation changing from false (or unset) to true and a -/+ replacement for the aws_sagemaker_model resource.