AWS sagemaker documentation change
Summary
Added SageMaker Python SDK v2 (Legacy) code examples for cross-account model registry operations including ECR/S3/KMS permissions, model package creation, and policy configurations
Security assessment
The changes add detailed documentation about configuring cross-account resource policies (ECR, S3, KMS) and IAM permissions for model registry operations. While this demonstrates security best practices for access control, there's no evidence of addressing a specific vulnerability. The examples explicitly show how to grant minimum required permissions ('ecr:BatchGetImage', 's3:GetObject', 'kms:Decrypt') which improves security posture documentation.
Diff
diff --git a/sagemaker/latest/dg/model-registry-version.md b/sagemaker/latest/dg/model-registry-version.md index f8ec89f5a..0e57354f6 100644 --- a//sagemaker/latest/dg/model-registry-version.md +++ b//sagemaker/latest/dg/model-registry-version.md @@ -39,0 +40,3 @@ First, you set up the parameter dictionary to pass to the `create_model_package` +SageMaker Python SDK v3 + + @@ -66,0 +70,36 @@ First, you set up the parameter dictionary to pass to the `create_model_package` +SageMaker Python SDK v2 (Legacy) + + + + # Specify the model source + model_url = "s3://{bucket}/model.tar.gz" + + #Set up the parameter dictionary to pass to the create_model_package API operation + modelpackage_inference_specification = { + "InferenceSpecification": { + "Containers": [ + { + "Image": f"{model_training_account}.dkr.ecr.us-east-2.amazonaws.com/decision-trees-sample:latest", + "ModelDataUrl": model_url + } + ], + "SupportedContentTypes": [ "text/csv" ], + "SupportedResponseMIMETypes": [ "text/csv" ], + } + } + + # Alternatively, you can specify the model source like this: + # modelpackage_inference_specification["InferenceSpecification"]["Containers"][0]["ModelDataUrl"]=model_url + + create_model_package_input_dict = { + "ModelPackageGroupName" : model_package_group_arn, + "ModelPackageDescription" : "Model to detect 3 different types of irises (Setosa, Versicolour, and Virginica)", + "ModelApprovalStatus" : "PendingManualApproval" + } + create_model_package_input_dict.update(modelpackage_inference_specification) + + # Create the model package in the Model Registry account + create_model_package_response = sm_client.create_model_package(**create_model_package_input_dict) + model_package_arn = create_model_package_response["ModelPackageArn"] + print('ModelPackage Version ARN : {}'.format(model_package_arn)) + @@ -103 +142 @@ Studio Classic - 2. In the left navigation pane, choose the **Home** icon (  ). + 2. In the left navigation pane, choose the **Home** icon (  ). @@ -274,0 +314,3 @@ The following policy configuration applies the policies discussed in the previou +SageMaker Python SDK v3 + + @@ -350,0 +393,108 @@ The following policy configuration applies the policies discussed in the previou +SageMaker Python SDK v2 (Legacy) + + + + import json + + # The cross-account id to grant access to + cross_account_id = "123456789012" + + # Create the policy for access to the ECR repository + ecr_repository_policy = { + 'Version': '2012-10-17', + 'Statement': [{ + 'Sid': 'AddPerm', + 'Effect': 'Allow', + 'Principal': { + 'AWS': f'arn:aws:iam::{cross_account_id}:root' + }, + 'Action': ['ecr:*'] + }] + } + + # Convert the ECR policy from JSON dict to string + ecr_repository_policy = json.dumps(ecr_repository_policy) + + # Set the new ECR policy + ecr = boto3.client('ecr') + response = ecr.set_repository_policy( + registryId = account, + repositoryName = 'decision-trees-sample', + policyText = ecr_repository_policy + ) + + # Create a policy for accessing the S3 bucket + bucket_policy = { + 'Version': '2012-10-17', + 'Statement': [{ + 'Sid': 'AddPerm', + 'Effect': 'Allow', + 'Principal': { + 'AWS': f'arn:aws:iam::{cross_account_id}:root' + }, + 'Action': 's3:*', + 'Resource': f'arn:aws:s3:::{bucket}/*' + }] + } + + # Convert the policy from JSON dict to string + bucket_policy = json.dumps(bucket_policy) + + # Set the new policy + s3 = boto3.client('s3') + response = s3.put_bucket_policy( + Bucket = bucket, + Policy = bucket_policy) + + # Create the KMS grant for encryption in the source account to the + # Model Registry account Model Group + client = boto3.client('kms') + + response = client.create_grant( + GranteePrincipal=cross_account_id, + KeyId=kms_key_id + Operations=[ + 'Decrypt', + 'GenerateDataKey', + ], + ) + + # 3. Create a policy for access to the Model Group. + model_package_group_policy = { + 'Version': '2012-10-17', + 'Statement': [{ + 'Sid': 'AddPermModelPackageGroup', + 'Effect': 'Allow', + 'Principal': { + 'AWS': f'arn:aws:iam::{cross_account_id}:root' + }, + 'Action': ['sagemaker:DescribeModelPackageGroup'], + 'Resource': f'arn:aws:sagemaker:{region}:{account}:model-package-group/{model_package_group_name}' + },{ + 'Sid': 'AddPermModelPackageVersion', + 'Effect': 'Allow', + 'Principal': { + 'AWS': f'arn:aws:iam::{cross_account_id}:root' + }, + 'Action': ["sagemaker:DescribeModelPackage", + "sagemaker:ListModelPackages", + "sagemaker:UpdateModelPackage", + "sagemaker:CreateModel"], + 'Resource': f'arn:aws:sagemaker:{region}:{account}:model-package/{model_package_group_name}/*' + }] + } + + # Convert the policy from JSON dict to string + model_package_group_policy = json.dumps(model_package_group_policy) + + # Set the policy to the Model Group + response = sm_client.put_model_package_group_policy( + ModelPackageGroupName = model_package_group_name, + ResourcePolicy = model_package_group_policy) + + print('ModelPackageGroupArn : {}'.format(create_model_package_group_response['ModelPackageGroupArn'])) + print("First Versioned ModelPackageArn: " + model_package_arn) + print("Second Versioned ModelPackageArn: " + model_package_arn2) + + print("Success! You are all set to proceed for cross-account deployment.") + @@ -352,0 +503,3 @@ The following configuration needs to be put in the Model Registry account where +SageMaker Python SDK v3 + + @@ -379,0 +533,79 @@ The following configuration needs to be put in the Model Registry account where +SageMaker Python SDK v2 (Legacy) + + + + import json + + # The Model Registry account id of the Model Group + model_registry_account = "111111111111" + + # The model training account id where training happens + model_training_account = "222222222222" + + # 1. Create a policy for access to the ECR repository + # in the model training account for the Model Registry account Model Group + ecr_repository_policy = {"Version": "2012-10-17", + "Statement": [{"Sid": "AddPerm", + "Effect": "Allow", + "Principal": { + "AWS": f"arn:aws:iam::{model_registry_account}:root" + }, + "Action": [ + "ecr:BatchGetImage", + "ecr:Describe*" + ] + }] + } + + # Convert the ECR policy from JSON dict to string + ecr_repository_policy = json.dumps(ecr_repository_policy) + + # Set the new ECR policy + ecr = boto3.client('ecr') + response = ecr.set_repository_policy( + registryId = model_training_account,