IAM PermissionsΒΆ

Table of ContentsΒΆ

OverviewΒΆ

The SEC Provisioner requires specific IAM permissions to create and manage IAM groups, roles, and policies via CloudFormation. This guide provides the minimum required permissions and best practices for security.

These are the permissions the operator needs to run the provisioner β€” not the policies the provisioner creates for your ML teams.

Quick Start - Generate IAM PolicyΒΆ

The SEC Provisioner generates an IAM policy file tailored to your configuration:

docker run --rm \
  -v ~/.aws:/home/secuser/.aws:ro \
  -v $(pwd)/sec/configs:/app/configs:ro \
  -v $(pwd)/sec/policies:/app/policies \
  -v $(pwd)/sec/reports:/app/reports \
  sec-provisioner:medium-10 \
  --config edge-prod-b001-us-west-1-sec.yaml \
  --action export-iam-policy

Output: sec/policies/{stem}-iam-policy.json

This generated policy includes all required permissions scoped to your company prefix, tenant ID, and AWS account.

Minimum Required PermissionsΒΆ

The generated policy contains 5 permission groups:

1. IAM ManagementΒΆ

Permissions to create and manage IAM groups, roles, and policies:

{
  "Sid": "IAMManagement",
  "Effect": "Allow",
  "Action": [
    "iam:CreateGroup",
    "iam:DeleteGroup",
    "iam:GetGroup",
    "iam:ListGroups",
    "iam:ListAttachedGroupPolicies",
    "iam:ListGroupPolicies",
    "iam:CreateRole",
    "iam:DeleteRole",
    "iam:GetRole",
    "iam:ListRoles",
    "iam:ListAttachedRolePolicies",
    "iam:ListRolePolicies",
    "iam:CreatePolicy",
    "iam:DeletePolicy",
    "iam:GetPolicy",
    "iam:ListPolicies",
    "iam:GetPolicyVersion",
    "iam:ListPolicyVersions",
    "iam:AttachGroupPolicy",
    "iam:DetachGroupPolicy",
    "iam:AttachRolePolicy",
    "iam:DetachRolePolicy",
    "iam:PutGroupPolicy",
    "iam:DeleteGroupPolicy",
    "iam:PutRolePolicy",
    "iam:DeleteRolePolicy",
    "iam:TagRole",
    "iam:TagPolicy",
    "iam:UntagRole",
    "iam:UntagPolicy",
    "iam:PassRole"
  ],
  "Resource": [
    "arn:aws:iam::<account>:group/<prefix>-<env>-<tenant>-group-*",
    "arn:aws:iam::<account>:role/<prefix>-<env>-<tenant>-role-*",
    "arn:aws:iam::<account>:role/<prefix>-<env>-<tenant>-xacct-*",
    "arn:aws:iam::<account>:policy/<prefix>-<env>-<tenant>-policy-*"
  ]
}

2. CloudFormation ManagementΒΆ

Permissions to create, update, and delete CloudFormation stacks:

{
  "Sid": "CloudFormationManagement",
  "Effect": "Allow",
  "Action": [
    "cloudformation:CreateStack",
    "cloudformation:DeleteStack",
    "cloudformation:DescribeStacks",
    "cloudformation:UpdateStack",
    "cloudformation:ValidateTemplate",
    "cloudformation:DescribeStackEvents",
    "cloudformation:DescribeStackResources",
    "cloudformation:CreateChangeSet",
    "cloudformation:DescribeChangeSet",
    "cloudformation:ExecuteChangeSet",
    "cloudformation:DeleteChangeSet",
    "cloudformation:DetectStackDrift",
    "cloudformation:DescribeStackDriftDetectionStatus",
    "cloudformation:DescribeStackResourceDrifts"
  ],
  "Resource": "arn:aws:cloudformation:<region>:<account>:stack/<prefix>-<env>-<tenant>-<region>-*-sec-stack/*"
}

3. S3 Template AccessΒΆ

Permissions to upload CloudFormation templates to S3 (required for medium and enterprise tiers where templates exceed the 51,200-byte TemplateBody limit):

{
  "Sid": "S3TemplateAccess",
  "Effect": "Allow",
  "Action": [
    "s3:GetObject",
    "s3:PutObject",
    "s3:DeleteObject"
  ],
  "Resource": "arn:aws:s3:::<prefix>-<env>-<tenant>-<region>-*/templates/*"
}

4. S3 Bucket ListΒΆ

{
  "Sid": "S3BucketList",
  "Effect": "Allow",
  "Action": "s3:ListBucket",
  "Resource": "arn:aws:s3:::<prefix>-<env>-<tenant>-<region>-*"
}

5. SSM Parameter StoreΒΆ

Permissions to store and retrieve stack outputs in Parameter Store:

{
  "Sid": "SSMParameterManagement",
  "Effect": "Allow",
  "Action": [
    "ssm:PutParameter",
    "ssm:GetParameter",
    "ssm:GetParameters",
    "ssm:GetParametersByPath",
    "ssm:DeleteParameter",
    "ssm:AddTagsToResource"
  ],
  "Resource": "arn:aws:ssm:<region>:<account>:parameter/security/<prefix>-<env>-<tenant>-<region>/*"
}

Permissions by ActionΒΆ

Local Actions (No Infrastructure Changes)ΒΆ

Action

AWS Permissions

validate-config

AWS Marketplace license check only

export-iam-policy

AWS Marketplace license check only

export-service-policies

AWS Marketplace license check only

export-groups

AWS Marketplace license check only

export-roles

AWS Marketplace license check only

create-prov-template

AWS Marketplace license check only

These actions generate local files only. They require valid AWS credentials for license validation but make no infrastructure changes.

Read-Only ActionsΒΆ

Action

AWS Permissions

validate-prov-template

cloudformation:ValidateTemplate

show-changes

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

check-drift

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

Deployment ActionsΒΆ

Action

AWS Permissions

deploy

All IAM + CloudFormation + S3 + SSM permissions

test-deploy

All IAM + CloudFormation + S3 + SSM permissions

delete-stack

cloudformation:DeleteStack, cloudformation:DescribeStacks, cloudformation:DescribeStackEvents, all IAM delete/detach permissions, ssm:DeleteParameter, ssm:GetParametersByPath

Permission ScopingΒΆ

All generated policies are scoped to your specific resources:

IAM ResourcesΒΆ

Scoped to your company prefix, environment, and tenant ID:

arn:aws:iam::<account>:group/<prefix>-<env>-<tenant>-group-*
arn:aws:iam::<account>:role/<prefix>-<env>-<tenant>-role-*
arn:aws:iam::<account>:role/<prefix>-<env>-<tenant>-xacct-*
arn:aws:iam::<account>:policy/<prefix>-<env>-<tenant>-policy-*

The provisioner cannot create, modify, or delete IAM resources outside your naming scope.

CloudFormation StacksΒΆ

Scoped to your security stacks only:

arn:aws:cloudformation:<region>:<account>:stack/<prefix>-<env>-<tenant>-<region>-*-sec-stack/*

SSM ParametersΒΆ

Scoped to your security parameter path:

arn:aws:ssm:<region>:<account>:parameter/security/<prefix>-<env>-<tenant>-<region>/*

S3 TemplatesΒΆ

Scoped to your S3 bucket and templates prefix:

arn:aws:s3:::<prefix>-<env>-<tenant>-<region>-*/templates/*

IAM Policy ExamplesΒΆ

Read-Only Access (Validation and Monitoring)ΒΆ

For users who only validate configurations and monitor drift:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "cloudformation:ValidateTemplate",
        "cloudformation:DescribeStacks",
        "cloudformation:DescribeStackResources",
        "cloudformation:DetectStackDrift",
        "cloudformation:DescribeStackDriftDetectionStatus",
        "cloudformation:DescribeStackResourceDrifts"
      ],
      "Resource": "arn:aws:cloudformation:*:*:stack/*-sec-stack/*"
    }
  ]
}

Separate Roles by EnvironmentΒΆ

Create distinct policies for each environment:

  • sec-provisioner-dev-role β€” full deploy/delete permissions in dev

  • sec-provisioner-staging-role β€” deploy only (no delete) in staging

  • sec-provisioner-prod-role β€” deploy with MFA requirement in production

Production with MFA RequirementΒΆ

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "cloudformation:CreateStack",
        "cloudformation:UpdateStack",
        "cloudformation:DeleteStack"
      ],
      "Resource": "arn:aws:cloudformation:*:*:stack/*-prod-*-sec-stack/*",
      "Condition": {
        "Bool": {
          "aws:MultiFactorAuthPresent": "true"
        }
      }
    }
  ]
}

Security Best PracticesΒΆ

  1. Use the generated policy β€” run export-iam-policy to get a policy scoped to your exact configuration 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 over long-lived access keys

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

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

  7. Review before applying β€” use show-changes and --dry-run before every production deployment

Troubleshooting Permission IssuesΒΆ

Access Denied ErrorsΒΆ

# Check current identity
aws sts get-caller-identity

# Test IAM permissions
aws iam get-group --group-name test-group 2>&1

# Test CloudFormation permissions
aws cloudformation describe-stacks --region us-west-1 2>&1

Common IssuesΒΆ

Error

Cause

Fix

AccessDenied on iam:CreateGroup

IAM policy not attached or resource ARN mismatch

Verify policy is attached and company prefix matches

AccessDenied on cloudformation:CreateStack

Stack name doesn’t match resource ARN pattern

Ensure config produces a stack name matching *-sec-stack

AccessDenied on ssm:PutParameter

Parameter path doesn’t match resource ARN

Verify /security/ prefix in SSM path matches policy

AccessDenied on s3:PutObject

No S3 bucket exists for template upload

Create the S3 bucket first (via S3 Provisioner)

Policy SimulatorΒΆ

Test your permissions before deploying: https://policysim.aws.amazon.com/

Permission Summary by ActionΒΆ

Action

IAM

CloudFormation

S3

SSM

validate-config

❌

❌

❌

❌

export-iam-policy

❌

❌

❌

❌

export-service-policies

❌

❌

❌

❌

export-groups

❌

❌

❌

❌

export-roles

❌

❌

❌

❌

create-prov-template

❌

❌

❌

❌

validate-prov-template

❌

βœ…

❌

❌

show-changes

❌

βœ…

❌

❌

check-drift

❌

βœ…

❌

❌

test-deploy

βœ…

βœ…

βœ…*

βœ…

deploy

βœ…

βœ…

βœ…*

βœ…

delete-stack

βœ…

βœ…

❌

βœ…

*S3 required only for medium/enterprise tiers (template upload)

All actions require valid AWS credentials for Marketplace license validation.