IAM PermissionsΒΆ
Table of ContentsΒΆ
OverviewΒΆ
The ML Provisioner requires specific IAM permissions to create and manage ML product infrastructure via CloudFormation. This guide covers the minimum required permissions for the operator running the provisioner.
These are the permissions the operator needs to run the provisioner β not the roles and policies the provisioner creates for your ML pipelines.
Permissions are tier-dependent β starter requires fewer permissions than professional, which requires fewer than enterprise.
Quick Start β Generate IAM PolicyΒΆ
The ML Provisioner generates a least-privilege IAM policy tailored to your configuration:
CONFIG={your-config-filename}.yaml # e.g. techcorp-prod-a001-us-west-2-customer-churn-ml-codecommit.yaml
IMAGE={starter|professional|enterprise} # e.g. starter
docker run --rm \
-v ~/.aws:/home/mluser/.aws:ro \
-v $(pwd)/ml/configs:/app/configs:ro \
-v $(pwd)/ml/policies:/app/policies \
-v $(pwd)/ml/reports:/app/reports \
ml-provisioner:${IMAGE} \
-con ${CONFIG} \
-act create-policy
Output: ml/policies/{ml_name}-{scenario}-iam-policy.json
Example: ml/policies/techcorp-prod-a001-us-west-2-customer-churn-ml-codecommit-iam-policy.json
This generated policy includes all required permissions scoped to your ml_name, AWS account, and region. Attach it to the IAM user or role used to run the provisioner.
Generated Policy β Permissions by TierΒΆ
All TiersΒΆ
CloudFormation ManagementΒΆ
{
"Sid": "CloudFormationManagement",
"Effect": "Allow",
"Action": [
"cloudformation:CreateStack",
"cloudformation:UpdateStack",
"cloudformation:DeleteStack",
"cloudformation:DescribeStacks",
"cloudformation:DescribeStackEvents",
"cloudformation:DescribeStackResources",
"cloudformation:ValidateTemplate",
"cloudformation:CreateChangeSet",
"cloudformation:DeleteChangeSet",
"cloudformation:DescribeChangeSet",
"cloudformation:ExecuteChangeSet",
"cloudformation:DetectStackDrift",
"cloudformation:DescribeStackDriftDetectionStatus",
"cloudformation:DescribeStackResourceDrifts"
],
"Resource": "arn:aws:cloudformation:{region}:{account}:stack/{ml_name}-*"
}
SageMakerΒΆ
{
"Sid": "SageMakerUnscoped",
"Effect": "Allow",
"Action": [
"sagemaker:CreateModelPackageGroup",
"sagemaker:ListModelPackageGroups"
],
"Resource": "*"
},
{
"Sid": "SageMakerScoped",
"Effect": "Allow",
"Action": [
"sagemaker:DeleteModelPackageGroup",
"sagemaker:DescribeModelPackageGroup",
"sagemaker:UpdateModelPackageGroup"
],
"Resource": "arn:aws:sagemaker:{region}:{account}:*/{ml_name}-*"
}
CodeCommitΒΆ
{
"Sid": "CodeCommitManagement",
"Effect": "Allow",
"Action": [
"codecommit:CreateRepository",
"codecommit:DeleteRepository",
"codecommit:GetRepository",
"codecommit:TagResource"
],
"Resource": "arn:aws:codecommit:{region}:{account}:{ml_name}-*"
}
CodeBuildΒΆ
{
"Sid": "CodeBuildManagement",
"Effect": "Allow",
"Action": [
"codebuild:CreateProject",
"codebuild:DeleteProject",
"codebuild:UpdateProject",
"codebuild:BatchGetProjects"
],
"Resource": "arn:aws:codebuild:{region}:{account}:project/{ml_name}-*"
}
CodePipelineΒΆ
{
"Sid": "CodePipelineManagement",
"Effect": "Allow",
"Action": [
"codepipeline:CreatePipeline",
"codepipeline:DeletePipeline",
"codepipeline:UpdatePipeline",
"codepipeline:GetPipeline",
"codepipeline:GetPipelineState",
"codepipeline:StartPipelineExecution"
],
"Resource": "arn:aws:codepipeline:{region}:{account}:{ml_name}-*"
}
IAMΒΆ
{
"Sid": "IAMRoleManagement",
"Effect": "Allow",
"Action": [
"iam:CreateRole",
"iam:DeleteRole",
"iam:GetRole",
"iam:PassRole",
"iam:AttachRolePolicy",
"iam:DetachRolePolicy",
"iam:CreatePolicy",
"iam:DeletePolicy",
"iam:GetPolicy",
"iam:TagRole",
"iam:TagPolicy"
],
"Resource": [
"arn:aws:iam::{account}:role/{ml_name}-*",
"arn:aws:iam::{account}:policy/{ml_name}-*"
]
}
SSM Parameter StoreΒΆ
{
"Sid": "SSMManageMlParameters",
"Effect": "Allow",
"Action": [
"ssm:PutParameter",
"ssm:GetParameter",
"ssm:GetParameters",
"ssm:GetParametersByPath",
"ssm:DeleteParameter",
"ssm:AddTagsToResource"
],
"Resource": "arn:aws:ssm:{region}:{account}:parameter/ml/{ml_name}/*"
}
Professional Tier (additional)ΒΆ
S3 Artifacts BucketΒΆ
{
"Sid": "S3ArtifactsBucketManagement",
"Effect": "Allow",
"Action": [
"s3:CreateBucket",
"s3:DeleteBucket",
"s3:GetBucketVersioning",
"s3:PutBucketVersioning",
"s3:PutBucketEncryption",
"s3:PutBucketPublicAccessBlock",
"s3:PutBucketTagging"
],
"Resource": "arn:aws:s3:::{ml_name}-artifacts"
}
EventBridgeΒΆ
{
"Sid": "EventBridgeManagement",
"Effect": "Allow",
"Action": [
"events:PutRule",
"events:DeleteRule",
"events:DescribeRule",
"events:PutTargets",
"events:RemoveTargets",
"events:TagResource"
],
"Resource": "arn:aws:events:{region}:{account}:rule/{ml_name}-*"
}
CloudWatch DashboardΒΆ
{
"Sid": "CloudWatchDashboardManagement",
"Effect": "Allow",
"Action": [
"cloudwatch:PutDashboard",
"cloudwatch:DeleteDashboards",
"cloudwatch:GetDashboard"
],
"Resource": "arn:aws:cloudwatch::{account}:dashboard/{ml_name}-*"
}
Enterprise Tier (additional)ΒΆ
KMSΒΆ
{
"Sid": "KMSKeyManagement",
"Effect": "Allow",
"Action": [
"kms:CreateKey",
"kms:DescribeKey",
"kms:EnableKeyRotation",
"kms:ScheduleKeyDeletion",
"kms:CreateAlias",
"kms:DeleteAlias",
"kms:TagResource"
],
"Resource": "*"
}
CloudWatch LogsΒΆ
{
"Sid": "CloudWatchLogsManagement",
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:DeleteLogGroup",
"logs:PutRetentionPolicy",
"logs:TagLogGroup"
],
"Resource": "arn:aws:logs:{region}:{account}:log-group:/ml/{ml_name}/*"
}
SNSΒΆ
{
"Sid": "SNSManagement",
"Effect": "Allow",
"Action": [
"sns:CreateTopic",
"sns:DeleteTopic",
"sns:GetTopicAttributes",
"sns:Subscribe",
"sns:Unsubscribe",
"sns:TagResource"
],
"Resource": "arn:aws:sns:{region}:{account}:{ml_name}-*"
}
VPC Endpoints and Security GroupΒΆ
{
"Sid": "VPCEndpointManagement",
"Effect": "Allow",
"Action": [
"ec2:CreateVpcEndpoint",
"ec2:DeleteVpcEndpoints",
"ec2:DescribeVpcEndpoints",
"ec2:ModifyVpcEndpoint",
"ec2:DescribeVpcs",
"ec2:DescribeSubnets",
"ec2:CreateSecurityGroup",
"ec2:DeleteSecurityGroup",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:CreateTags"
],
"Resource": "*"
}
Permissions by ActionΒΆ
Local Actions (No AWS Calls)ΒΆ
These actions run entirely inside the Docker container and make no AWS API calls. They generate local files (templates, policies, reports) only. Safe to run at any time with no risk of infrastructure changes. No AWS permissions required beyond credential validation at startup.
Action |
AWS Permissions |
|---|---|
|
None |
|
None |
|
None |
|
None |
|
None |
|
None |
|
None |
These actions generate local files only and require no AWS permissions.
Read-Only ActionsΒΆ
These actions make AWS API calls but do not create, modify, or delete any infrastructure. Safe to run against production environments. Require valid AWS credentials and read access to CloudFormation stacks.
Action |
AWS Permissions |
|---|---|
|
|
|
|
Deployment ActionsΒΆ
These actions create, modify, or delete AWS infrastructure. They require the --force flag
(except test-deploy) and should be treated with the same care as any production change.
test-deploy deploys with a random suffix for isolation and is safe to run alongside a
live stack, but still creates real AWS resources that must be cleaned up afterwards.
Action |
AWS Permissions |
|---|---|
|
All permissions for your tier |
|
All permissions for your tier |
|
CloudFormation delete + IAM delete/detach + SSM delete |
Permission ScopingΒΆ
All generated policies are scoped to your specific ml_name to prevent access to other resources.
What is
ml_name? It is the unique identifier for your ML product, auto-generated from your config file values. Examples:
techcorp-prod-a001-us-west-2-customer-churn-ml(starter, no workload)
edge-prod-b001-us-west-2-fraud-detection-realtime-ml(professional, with workload)
globalbank-prod-c001-us-west-2-demand-forecasting-ml(enterprise)See NAMING_CONVENTIONS.md for the full construction rules.
CloudFormationΒΆ
arn:aws:cloudformation:{region}:{account}:stack/{ml_name}-*
SageMakerΒΆ
arn:aws:sagemaker:{region}:{account}:*/{ml_name}-*
CodeCommit / CodeBuild / CodePipelineΒΆ
arn:aws:codecommit:{region}:{account}:{ml_name}-*
arn:aws:codebuild:{region}:{account}:project/{ml_name}-*
arn:aws:codepipeline:{region}:{account}:{ml_name}-*
IAMΒΆ
IAM resources use the short prefix pattern (region omitted β IAM is global):
arn:aws:iam::{account}:role/{company_prefix}-{env}-{tenant_id}-{use_case}-*
arn:aws:iam::{account}:policy/{company_prefix}-{env}-{tenant_id}-{use_case}-*
SSM Parameter StoreΒΆ
arn:aws:ssm:{region}:{account}:parameter/ml/{ml_name}/*
Security Best PracticesΒΆ
Use the generated policy β run
create-policyto get a scoped policy rather than crafting one manuallySeparate roles by environment β dev, staging, and production should use different IAM roles
Require MFA for production β add
aws:MultiFactorAuthPresentcondition for deployment actionsUse temporary credentials β prefer IAM roles with assumed sessions over long-lived access keys
Rotate credentials β rotate access keys every 90 days if using IAM users
Monitor with CloudTrail β audit all CloudFormation, SageMaker, and IAM API calls
Review before deploying β use
show-changesbefore every production deployment
Troubleshooting Permission IssuesΒΆ
Check Current IdentityΒΆ
aws sts get-caller-identity
Test Specific PermissionsΒΆ
# Test CloudFormation access
aws cloudformation describe-stacks --region us-west-2 2>&1
# Test SageMaker access
aws sagemaker list-model-package-groups --region us-west-2 2>&1
# Test SSM access
aws ssm get-parameters-by-path --path /ml/ --region us-west-2 2>&1
Common IssuesΒΆ
Error |
Cause |
Fix |
|---|---|---|
|
Policy not attached or stack name mismatch |
Verify |
|
IAM resource ARN pattern mismatch |
Verify |
|
Enterprise permissions missing |
Attach enterprise-tier generated policy |
|
KMS permissions missing |
Attach enterprise-tier generated policy |
|
SSM path doesnβt match policy |
Verify |
Policy SimulatorΒΆ
Test your permissions before deploying:
Tool (requires AWS login): https://policysim.aws.amazon.com/
Documentation: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_testing-policies.html
Permission Summary by ActionΒΆ
Action |
CFN |
SageMaker |
CodeCommit |
CodeBuild |
CodePipeline |
IAM |
SSM |
S3 |
Events |
KMS |
EC2 |
|---|---|---|---|---|---|---|---|---|---|---|---|
|
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
|
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
|
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
|
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
|
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
|
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
|
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
|
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
|
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
|
β |
β |
β |
β |
β |
β |
β |
β * |
β * |
β * |
β * |
|
β |
β |
β |
β |
β |
β |
β |
β * |
β * |
β * |
β * |
*Tier-dependent β only required for professional or enterprise tier.