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

validate-config

None

list-products

None

show-product

None

create-policy

None

create-prov-template

None

validate-prov-template

None

create-review-report

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

show-changes

cloudformation:CreateChangeSet, cloudformation:DescribeChangeSet, cloudformation:DeleteChangeSet, cloudformation:DescribeStacks

check-drift

cloudformation:DetectStackDrift, cloudformation:DescribeStackDriftDetectionStatus, cloudformation:DescribeStackResourceDrifts, cloudformation:DescribeStacks

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

deploy-product

All permissions for your tier

test-deploy

All permissions for your tier

delete-product

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ΒΆ

  1. Use the generated policy β€” run create-policy to get a scoped policy rather than crafting one manually

  2. Separate roles by environment β€” dev, staging, and production should use different IAM roles

  3. Require MFA for production β€” add aws:MultiFactorAuthPresent condition for deployment actions

  4. Use temporary credentials β€” prefer IAM roles with assumed sessions over long-lived access keys

  5. Rotate credentials β€” rotate access keys every 90 days if using IAM users

  6. Monitor with CloudTrail β€” audit all CloudFormation, SageMaker, and IAM API calls

  7. Review before deploying β€” use show-changes before 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

AccessDenied on cloudformation:CreateStack

Policy not attached or stack name mismatch

Verify ml_name in config matches policy resource ARN

AccessDenied on iam:CreateRole

IAM resource ARN pattern mismatch

Verify company_prefix, env, tenant_id match policy

AccessDenied on ec2:CreateVpcEndpoint

Enterprise permissions missing

Attach enterprise-tier generated policy

AccessDenied on kms:CreateKey

KMS permissions missing

Attach enterprise-tier generated policy

AccessDenied on ssm:PutParameter

SSM path doesn’t match policy

Verify /ml/{ml_name}/ path in policy matches config

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

validate-config

❌

❌

❌

❌

❌

❌

❌

❌

❌

❌

❌

create-policy

❌

❌

❌

❌

❌

❌

❌

❌

❌

❌

❌

create-prov-template

❌

❌

❌

❌

❌

❌

❌

❌

❌

❌

❌

validate-prov-template

❌

❌

❌

❌

❌

❌

❌

❌

❌

❌

❌

show-changes

βœ…

❌

❌

❌

❌

❌

❌

❌

❌

❌

❌

check-drift

βœ…

❌

❌

❌

❌

❌

❌

❌

❌

❌

❌

deploy-product (starter)

βœ…

βœ…

βœ…

βœ…

βœ…

βœ…

βœ…

❌

❌

❌

❌

deploy-product (professional)

βœ…

βœ…

βœ…

βœ…

βœ…

βœ…

βœ…

βœ…

βœ…

❌

❌

deploy-product (enterprise)

βœ…

βœ…

βœ…

βœ…

βœ…

βœ…

βœ…

βœ…

βœ…

βœ…

βœ…

test-deploy

βœ…

βœ…

βœ…

βœ…

βœ…

βœ…

❌

βœ…*

βœ…*

βœ…*

βœ…*

delete-product

βœ…

βœ…

βœ…

βœ…

βœ…

βœ…

βœ…

βœ…*

βœ…*

βœ…*

βœ…*

*Tier-dependent β€” only required for professional or enterprise tier.