Safeguard Docs
Integrations

Amazon SageMaker AI

Connect Amazon SageMaker AI to Safeguard. The exact IAM policy the read-only role needs, which credentials work, and step-by-step setup with CloudFormation, Terraform or the AWS CLI.

Availability

This integration is switched on per workspace. If you do not see the card under Integrations, ask your Safeguard contact.

What it does

Safeguard reads an inventory of the AI assets you run in Amazon SageMaker AI (including JumpStart): models, Model Registry groups and versions, real-time endpoints and their endpoint configurations, and inference components, in every region the connection reads. For each one it records where the model came from (JumpStart, your own S3 or Model Registry, or unknown), whether the endpoint serves a pinned version, network isolation, the customer-managed key on the endpoint's storage, and how broad each execution role is. The results appear as AI asset inventory entries and continuous tests (asset inventory, public access, network isolation, customer-managed keys, least-privilege execution roles, pinned model versions, licence risk and model provenance). Find the Amazon SageMaker AI card under Integrations on the Project/Product tab (the AI Model filter shows only AI model cards). Safeguard never invokes an endpoint, and no customer data goes to third-party LLMs.

This is a separate connection from the AWS compliance connection: its role holds only the SageMaker AI reads below, and the AWS compliance tests never run on it.

Public vs private

PublicPrivate
What you enterNothing: there is no public modeA cross-account role ARN (or an IAM user's access key) and, optionally, the regions to read
Credential neededNot applicableA role or IAM user with the Safeguard ML inventory policy
What you can scanNot applicableEvery SageMaker AI model, endpoint, inference component and Model Registry entry in the regions read

Supported auth methods

MethodUse it whenNotes
Cross-account IAM role with an external IDThe recommended defaultSafeguard assumes the role with the external ID it generates for this connection; no long-lived key leaves your account
IAM user access keyYour installation has no AWS platform principal, or your policy forbids cross-account rolesAttach the same policy to the user; rotate the key yourself

Permissions required

Safeguard only reads. Every action below is a List, Describe or Get call; there is no write action and no data-plane action (Safeguard never calls sagemaker:InvokeEndpoint). The least-privilege choice is the inline policy below on a dedicated role. Do not use the AWS managed policy AmazonSageMakerReadOnly: it also grants Feature Store record reads (sagemaker:GetRecord, sagemaker:BatchGetRecord), sagemaker:Search and Cognito user lists, which Safeguard does not need.

Cross-account IAM role with an external ID

Permission / scopeRequired?What Safeguard uses it for
sts:AssumeRole for Safeguard's principal, with the condition sts:ExternalId (in the role's trust policy)RequiredLets Safeguard assume the role, only with this connection's external ID
sagemaker:ListModelsRequiredLists the models in each region
sagemaker:DescribeModelRequiredEach model's containers (image, model data location, JumpStart hub content, Model Registry package), execution role, VPC and network isolation
sagemaker:ListEndpointsRequiredLists the endpoints in each region (also the action Check access tries)
sagemaker:DescribeEndpointRequiredEach endpoint's configuration name, status and deployed images
sagemaker:DescribeEndpointConfigRequiredEach endpoint's production variants (model, instance type, serverless), KMS key, execution role, VPC and network isolation
sagemaker:ListInferenceComponentsRequiredLists the inference components in each region
sagemaker:DescribeInferenceComponentRequiredEach inference component's endpoint, model, deployed image and status
sagemaker:ListModelPackageGroupsRequiredLists the Model Registry groups
sagemaker:ListModelPackagesRequiredLists the versions in each Model Registry group
sagemaker:DescribeModelPackageRequiredEach registry version's containers, image digest, model data location, JumpStart base model and approval status
sagemaker:ListTagsRequiredThe JumpStart tags the SageMaker Python SDK and Studio add (model id, version, model type, hub content ARN)
sagemaker:DescribeHubContentRequiredA JumpStart model's display name and support status (Supported, Deprecated, Restricted)
iam:ListAttachedRolePoliciesRequiredWhich managed policies each execution role holds, to judge how broad it is
iam:ListRolePoliciesRequiredWhich inline policies each execution role holds
iam:GetRolePolicyRequiredReads each inline policy document (never the role's credentials)
ec2:DescribeRegionsRequiredFinds the account's enabled regions; not needed when the connection lists its regions
s3:GetObjectOptionalReserved for a later model-artifact scan; off by default and not used today. If you ever grant it, grant it only on the buckets that hold model artifacts

The exact permissions policy (the setup steps in the app show the same JSON with a copy button):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "SafeguardSageMakerInventoryRead",
      "Effect": "Allow",
      "Action": [
        "sagemaker:ListModels",
        "sagemaker:DescribeModel",
        "sagemaker:ListEndpoints",
        "sagemaker:DescribeEndpoint",
        "sagemaker:DescribeEndpointConfig",
        "sagemaker:ListInferenceComponents",
        "sagemaker:DescribeInferenceComponent",
        "sagemaker:ListModelPackageGroups",
        "sagemaker:ListModelPackages",
        "sagemaker:DescribeModelPackage",
        "sagemaker:ListTags",
        "sagemaker:DescribeHubContent"
      ],
      "Resource": "*"
    },
    {
      "Sid": "SafeguardExecutionRoleBreadthRead",
      "Effect": "Allow",
      "Action": [
        "iam:ListAttachedRolePolicies",
        "iam:ListRolePolicies",
        "iam:GetRolePolicy"
      ],
      "Resource": "*"
    },
    {
      "Sid": "SafeguardRegionsRead",
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeRegions"
      ],
      "Resource": "*"
    }
  ]
}

The trust policy. In the app, <SAFEGUARD_PRINCIPAL_ARN> and <EXTERNAL_ID> are filled in for your connection:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "<SAFEGUARD_PRINCIPAL_ARN>"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "<EXTERNAL_ID>"
        }
      }
    }
  ]
}

Least privilege: the role SafeguardMlInventory with exactly the policy above. If the connection lists its regions, you may drop ec2:DescribeRegions. Without the three iam: actions the inventory still works, but every execution role is reported as not judged.

IAM user access key

Permission / scopeRequired?What Safeguard uses it for
The permissions policy above, attached to the IAM userRequiredThe same reads as the role, signed with the user's key
s3:GetObjectOptionalReserved for a later model-artifact scan; not used today

Least privilege: a dedicated IAM user with only the policy above as an inline policy, no console password and one active access key.

Token types

Token typeWorks?Notes
Role assumed with an external ID (temporary credentials)Yes (recommended)The template sets MaxSessionDuration to 3600 seconds; Safeguard assumes the role again for each run
IAM user access key (access key ID and secret access key)YesLong-lived: rotate it on a schedule
Read-only vs adminRead-only onlyThe policy above holds only reads; Safeguard never needs an administrator role
AWS managed policy AmazonSageMakerReadOnlyNot recommendedBroader than needed (Feature Store records, Search, Cognito user lists)
Root user keysNoNever use root credentials

Expiry: role sessions end after at most one hour and are renewed automatically, so the role itself has nothing to rotate. An access key does not expire on its own: rotate it at least every 90 days.

What we never need: any write action, sagemaker:InvokeEndpoint or any other data-plane access, AmazonSageMakerReadOnly, AdministratorAccess, s3:GetObject today, or root credentials. A model's Environment variables can hold secrets: Safeguard drops them from every response unread and never stores them.

Step-by-step setup

Get the external ID from Safeguard (cross-account role)

  1. Open Integrations and choose the Project/Product tab (optionally the AI Model filter).
  2. Click Connect on the Amazon SageMaker AI card.
  3. Give the connection a name, choose the cross-account role method, and save. Safeguard generates the connection's external ID on this first save; you cannot choose it.
  4. The dialog now shows the external ID, and its Setup steps section shows the CloudFormation template, the AWS CLI commands, the Terraform, the permissions policy and the trust policy with your external ID and Safeguard's principal filled in. Each has a copy button.

Create the credential in Amazon SageMaker AI

  1. Copy the CloudFormation template from Setup steps and save it as safeguard-ml-inventory.yaml.
  2. In the AWS console, open CloudFormation > Create stack > With new resources, upload the file, and acknowledge that it creates a named IAM role.
  3. When the stack finishes, open its Outputs tab and copy RoleArn.

The template, with placeholders where the app fills in your values:

AWSTemplateFormatVersion: '2010-09-09'
Description: Safeguard ML inventory - read-only access to Amazon SageMaker AI (no write action, no data plane).
Resources:
  SafeguardMlInventoryRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: SafeguardMlInventory
      MaxSessionDuration: 3600
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              AWS: '<SAFEGUARD_PRINCIPAL_ARN>'
            Action: sts:AssumeRole
            Condition:
              StringEquals:
                sts:ExternalId: '<EXTERNAL_ID>'
      Policies:
        - PolicyName: SafeguardMlInventoryRead
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Sid: SafeguardSageMakerInventoryRead
                Effect: Allow
                Action:
                  - sagemaker:ListModels
                  - sagemaker:DescribeModel
                  - sagemaker:ListEndpoints
                  - sagemaker:DescribeEndpoint
                  - sagemaker:DescribeEndpointConfig
                  - sagemaker:ListInferenceComponents
                  - sagemaker:DescribeInferenceComponent
                  - sagemaker:ListModelPackageGroups
                  - sagemaker:ListModelPackages
                  - sagemaker:DescribeModelPackage
                  - sagemaker:ListTags
                  - sagemaker:DescribeHubContent
                Resource: '*'
              - Sid: SafeguardExecutionRoleBreadthRead
                Effect: Allow
                Action:
                  - iam:ListAttachedRolePolicies
                  - iam:ListRolePolicies
                  - iam:GetRolePolicy
                Resource: '*'
              - Sid: SafeguardRegionsRead
                Effect: Allow
                Action:
                  - ec2:DescribeRegions
                Resource: '*'
Outputs:
  RoleArn:
    Description: Paste this into the Safeguard connection.
    Value: !GetAtt SafeguardMlInventoryRole.Arn

Or with the AWS CLI

Deploy the same template and print the role ARN:

aws cloudformation deploy --stack-name safeguard-ml-inventory --template-file safeguard-ml-inventory.yaml --capabilities CAPABILITY_NAMED_IAM
aws cloudformation describe-stacks --stack-name safeguard-ml-inventory --query "Stacks[0].Outputs[?OutputKey=='RoleArn'].OutputValue" --output text

Or with Terraform

resource "aws_iam_role" "safeguard_ml_inventory" {
  name                 = "SafeguardMlInventory"
  max_session_duration = 3600
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect    = "Allow"
      Principal = { AWS = "<SAFEGUARD_PRINCIPAL_ARN>" }
      Action    = "sts:AssumeRole"
      Condition = { StringEquals = { "sts:ExternalId" = "<EXTERNAL_ID>" } }
    }]
  })
}

resource "aws_iam_role_policy" "safeguard_ml_inventory_read" {
  name = "SafeguardMlInventoryRead"
  role = aws_iam_role.safeguard_ml_inventory.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      { Sid = "SafeguardSageMakerInventoryRead", Effect = "Allow", Action = ["sagemaker:ListModels", "sagemaker:DescribeModel", "sagemaker:ListEndpoints", "sagemaker:DescribeEndpoint", "sagemaker:DescribeEndpointConfig", "sagemaker:ListInferenceComponents", "sagemaker:DescribeInferenceComponent", "sagemaker:ListModelPackageGroups", "sagemaker:ListModelPackages", "sagemaker:DescribeModelPackage", "sagemaker:ListTags", "sagemaker:DescribeHubContent"], Resource = "*" },
      { Sid = "SafeguardExecutionRoleBreadthRead", Effect = "Allow", Action = ["iam:ListAttachedRolePolicies", "iam:ListRolePolicies", "iam:GetRolePolicy"], Resource = "*" },
      { Sid = "SafeguardRegionsRead", Effect = "Allow", Action = ["ec2:DescribeRegions"], Resource = "*" },
    ]
  })
}

output "safeguard_role_arn" {
  value = aws_iam_role.safeguard_ml_inventory.arn
}

Or with an IAM user access key

Save the permissions policy above as safeguard-ml-inventory-policy.json, then:

aws iam create-user --user-name safeguard-ml-inventory
aws iam put-user-policy --user-name safeguard-ml-inventory --policy-name SafeguardMlInventoryRead --policy-document file://safeguard-ml-inventory-policy.json
aws iam create-access-key --user-name safeguard-ml-inventory

Copy the access key ID and secret access key. AWS shows the secret only once.

Connect it in Safeguard

  1. Back in the Amazon SageMaker AI dialog, paste the role ARN from the stack output (or, for the access key method, the access key ID and secret access key).
  2. Optionally list the regions to read. Leave it empty to read every enabled region of the account.
  3. Save, then click Check access. Safeguard assumes the role (or uses the key) and lists one SageMaker AI endpoint. Success reads Read SageMaker AI in <region> as <role ARN>. A failure names the missing permission (see Troubleshooting).

Check access tries one action, sagemaker:ListEndpoints. If another action from the policy is missing, the next test run shows an error row for that region that names it.

Webhooks and triggers

This integration has no webhooks. The inventory is read each time the connection's tests run, on their schedule or when you run them by hand.

What we read and store

  • Read: the configuration of models, endpoints, endpoint configurations, inference components and Model Registry groups and versions; the JumpStart tags and catalog entries they name; the managed and inline policies of each execution role in the same account (to judge breadth, never its credentials); the account's enabled regions.
  • Stored: the inventory (names, ARNs, regions, images, model data locations, JumpStart model ids and versions, instance types, network, encryption and execution role findings) in the AI asset inventory, and the test results. An asset that disappears is marked inactive, not deleted. Access keys are encrypted at rest and never shown again after you save them.
  • Not stored or read: predictions and endpoint invocations, model artifacts in S3, training data, Feature Store records, and the containers' Environment variables. Model Registry model cards, metrics, drift baselines and custom metadata are dropped unread.
  • No customer data from this integration is sent to third-party LLMs.

Troubleshooting

Message you seeCauseFix
Safeguard could not assume <role ARN>: deploy the SafeguardMlInventory template from the setup steps, trusting this installation's principal with this connection's external ID.The role does not exist, or its trust policy names another principal or external IDDeploy the template from Setup steps (it carries this connection's external ID), or fix the trust policy
The role was assumed but cannot list SageMaker AI endpoints: attach the Safeguard ML inventory policy from the setup steps (it needs sagemaker:ListEndpoints and the other read actions).The role exists but lacks the permissions policyAttach the permissions policy above to the role
The platform role method needs the ARN of the role Safeguard assumes in your account.The role ARN is emptyPaste the RoleArn output of the stack
This connection has no external ID yet; save it again so the server can generate one.The connection was not saved before the role stepSave the connection, then copy the template again
This installation has no AWS platform principal to assume a role with; use an access key.This Safeguard installation cannot assume rolesUse the IAM user access key method
AWS needs an access key id and a secret access key on this connection.One of the key fields is emptyEnter both the access key ID and the secret access key
The role ARN is not in the AWS partition <partition>.The ARN belongs to another partition (for example GovCloud)Use the role ARN from the same partition as the connection
Region(s) <regions> are not in the AWS partition <partition>.A listed region is not in the connection's partitionCorrect or remove the region
... AWS did not accept the connection's credential.The access key was deleted, deactivated or mistypedCreate a new access key and update the connection
sagemaker:ListTags refused in <region>: JumpStart tags were not read thereThe policy lacks sagemaker:ListTagsAdd it; until then JumpStart models in that region may show as unknown provenance
sagemaker:DescribeHubContent failed for <model>: <code>The JumpStart catalog entry could not be readAdd sagemaker:DescribeHubContent; the model is still inventoried without its display name
IAM refused reading the role's policies (<code>): grant iam:ListAttachedRolePolicies, iam:ListRolePolicies and iam:GetRolePolicyThe policy lacks the three iam: actionsAdd them; until then execution roles are not judged
the role is in another account, which this connection does not readAn execution role lives in another AWS accountNothing to fix: that role is reported as not judged
...: the service is not offered to this account in this region.SageMaker AI is not available in a listed regionRemove the region from the connection

Rotation and disconnect

  • Rotate: a role has nothing to rotate. For an access key, create a second key (aws iam create-access-key --user-name safeguard-ml-inventory), paste it into the connection and save, then delete the old one (aws iam delete-access-key --user-name safeguard-ml-inventory --access-key-id <OLD_KEY_ID>).
  • Disconnect: delete the connection in Safeguard, then delete the stack (aws cloudformation delete-stack --stack-name safeguard-ml-inventory), run terraform destroy on the role, or delete the IAM user and its keys.

Vendor references

On this page