IAM PermissionsΒΆ

Table of ContentsΒΆ


OverviewΒΆ

The S3 Provisioner requires specific IAM permissions to create and manage S3 buckets via CloudFormation. This guide provides the minimum required permissions and best practices for security.

Quick Start - Generate IAM PolicyΒΆ

The S3 Provisioner can generate an IAM policy file tailored to your configuration:

docker run --rm \
  -v $(pwd)/s3/configs:/app/configs \
  -v $(pwd)/s3/policies:/app/policies \
  -v $(pwd)/s3/reports:/app/reports \
  s3-provisioner:latest \
  --config edge-prod-a001-us-west-1-s3.yaml \
  --action create-policy

Output: policies/<config-name>_iam_policy.json

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


Minimum Required PermissionsΒΆ

Complete IAM PolicyΒΆ

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "CloudFormationManagement",
      "Effect": "Allow",
      "Action": [
        "cloudformation:CreateStack",
        "cloudformation:DeleteStack",
        "cloudformation:DescribeStacks",
        "cloudformation:GetTemplate",
        "cloudformation:DescribeStackEvents",
        "cloudformation:DescribeStackResources"
      ],
      "Resource": "arn:aws:cloudformation:*:*:stack/*/*"
    },
    {
      "Sid": "S3BucketManagement",
      "Effect": "Allow",
      "Action": [
        "s3:CreateBucket",
        "s3:DeleteBucket",
        "s3:PutBucketVersioning",
        "s3:PutBucketPublicAccessBlock",
        "s3:PutBucketTagging",
        "s3:PutBucketLifecycleConfiguration",
        "s3:GetBucketLifecycleConfiguration"
      ],
      "Resource": "arn:aws:s3:::*"
    },
    {
      "Sid": "S3ObjectOperations",
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::*",
        "arn:aws:s3:::*/*"
      ]
    },
    {
      "Sid": "IAMLambdaRoleManagement",
      "Effect": "Allow",
      "Action": [
        "iam:CreateRole",
        "iam:DeleteRole",
        "iam:GetRole",
        "iam:PassRole",
        "iam:AttachRolePolicy",
        "iam:DetachRolePolicy",
        "iam:PutRolePolicy",
        "iam:DeleteRolePolicy"
      ],
      "Resource": "arn:aws:iam::*:role/*"
    },
    {
      "Sid": "LambdaManagement",
      "Effect": "Allow",
      "Action": [
        "lambda:CreateFunction",
        "lambda:DeleteFunction",
        "lambda:GetFunction",
        "lambda:InvokeFunction",
        "lambda:UpdateFunctionCode",
        "lambda:UpdateFunctionConfiguration"
      ],
      "Resource": "arn:aws:lambda:*:*:function:*"
    },
    {
      "Sid": "EC2VPCEndpoint",
      "Effect": "Allow",
      "Action": [
        "ec2:CreateVpcEndpoint",
        "ec2:DeleteVpcEndpoints",
        "ec2:DescribeVpcEndpoints",
        "ec2:ModifyVpcEndpoint"
      ],
      "Resource": "*"
    }
  ]
}

Permissions by ActionΒΆ

Actions Requiring No AWS PermissionsΒΆ

These actions only validate or generate files locally:

  • validate-config - Validates YAML against schema

  • create-policy - Generates IAM policy JSON file

  • create-prov-template - Generates CloudFormation template

  • validate-prov-template - Validates generated template locally (YAML syntax, structure, reference integrity)

Required: None (no AWS API calls)


Actions Requiring AWS PermissionsΒΆ

create-bucketΒΆ

Creates S3 bucket via CloudFormation stack.

Required Permissions:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "cloudformation:CreateStack",
        "cloudformation:DescribeStacks",
        "cloudformation:DescribeStackEvents",
        "s3:CreateBucket",
        "s3:PutBucketVersioning",
        "s3:PutBucketPublicAccessBlock",
        "s3:PutBucketTagging",
        "s3:PutBucketLifecycleConfiguration",
        "iam:CreateRole",
        "iam:PutRolePolicy",
        "iam:PassRole",
        "lambda:CreateFunction",
        "ec2:CreateVpcEndpoint"
      ],
      "Resource": "*"
    }
  ]
}

prep-master, deploy-solution, deploy-foldersΒΆ

Creates folder structure in S3 bucket.

Required Permissions:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::your-bucket-name",
        "arn:aws:s3:::your-bucket-name/*"
      ]
    }
  ]
}

upload-templateΒΆ

Uploads CloudFormation template to S3.

Required Permissions:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::your-bucket-name/*"
    }
  ]
}

gitkeep-full, gitkeep-none, gitkeep-partial, purge-bucketΒΆ

Manages .gitkeep files in S3 bucket.

Required Permissions:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:DeleteObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::your-bucket-name",
        "arn:aws:s3:::your-bucket-name/*"
      ]
    }
  ]
}

delete-bucketΒΆ

Deletes S3 bucket directly (bypasses CloudFormation).

Required Permissions:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:DeleteBucket",
        "s3:DeleteObject",
        "s3:ListBucket",
        "s3:ListBucketVersions",
        "s3:DeleteObjectVersion"
      ],
      "Resource": [
        "arn:aws:s3:::your-bucket-name",
        "arn:aws:s3:::your-bucket-name/*"
      ]
    }
  ]
}

delete-cfn-stack, tear-downΒΆ

Deletes CloudFormation stack and resources.

Required Permissions:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "cloudformation:DeleteStack",
        "cloudformation:DescribeStacks",
        "cloudformation:DescribeStackEvents",
        "s3:DeleteBucket",
        "s3:DeleteObject",
        "s3:ListBucket",
        "iam:DeleteRole",
        "iam:DeleteRolePolicy",
        "iam:DetachRolePolicy",
        "lambda:DeleteFunction",
        "ec2:DeleteVpcEndpoints"
      ],
      "Resource": "*"
    }
  ]
}

Permission Scoping Best PracticesΒΆ

1. Scope by Company PrefixΒΆ

Limit permissions to buckets matching your company prefix:

{
  "Resource": "arn:aws:s3:::edge-*"
}

2. Scope by AWS AccountΒΆ

Limit IAM and Lambda permissions to your account:

{
  "Resource": "arn:aws:iam::123456789012:role/edge-*"
}

3. Scope by RegionΒΆ

Limit CloudFormation and Lambda to specific regions:

{
  "Resource": "arn:aws:cloudformation:us-west-1:123456789012:stack/*/*"
}

4. Scope by EnvironmentΒΆ

Create separate IAM policies for dev, staging, prod:

{
  "Resource": "arn:aws:s3:::edge-prod-*"
}

IAM Policy ExamplesΒΆ

Read-Only Access (Validation Only)ΒΆ

For users who only validate configurations:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket",
        "s3:GetObject",
        "s3:GetBucketVersioning",
        "s3:GetBucketTagging",
        "s3:GetBucketLifecycleConfiguration"
      ],
      "Resource": [
        "arn:aws:s3:::edge-*",
        "arn:aws:s3:::edge-*/*"
      ]
    }
  ]
}

Development EnvironmentΒΆ

For dev/test environments with limited scope:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "cloudformation:*",
        "s3:*",
        "iam:*",
        "lambda:*",
        "ec2:*VpcEndpoint*"
      ],
      "Resource": "*",
      "Condition": {
        "StringLike": {
          "aws:RequestedRegion": "us-west-2"
        }
      }
    }
  ]
}

Production EnvironmentΒΆ

For production with strict scoping:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "CloudFormationProd",
      "Effect": "Allow",
      "Action": [
        "cloudformation:CreateStack",
        "cloudformation:DeleteStack",
        "cloudformation:DescribeStacks",
        "cloudformation:GetTemplate",
        "cloudformation:DescribeStackEvents"
      ],
      "Resource": "arn:aws:cloudformation:us-west-1:123456789012:stack/edge-prod-*/*"
    },
    {
      "Sid": "S3BucketProd",
      "Effect": "Allow",
      "Action": [
        "s3:CreateBucket",
        "s3:DeleteBucket",
        "s3:PutBucketVersioning",
        "s3:PutBucketPublicAccessBlock",
        "s3:PutBucketTagging",
        "s3:PutBucketLifecycleConfiguration"
      ],
      "Resource": "arn:aws:s3:::edge-prod-*"
    },
    {
      "Sid": "S3ObjectProd",
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::edge-prod-*",
        "arn:aws:s3:::edge-prod-*/*"
      ]
    },
    {
      "Sid": "IAMRoleProd",
      "Effect": "Allow",
      "Action": [
        "iam:CreateRole",
        "iam:DeleteRole",
        "iam:GetRole",
        "iam:PassRole",
        "iam:PutRolePolicy",
        "iam:DeleteRolePolicy"
      ],
      "Resource": "arn:aws:iam::123456789012:role/edge-prod-*"
    },
    {
      "Sid": "LambdaProd",
      "Effect": "Allow",
      "Action": [
        "lambda:CreateFunction",
        "lambda:DeleteFunction",
        "lambda:GetFunction",
        "lambda:InvokeFunction"
      ],
      "Resource": "arn:aws:lambda:us-west-1:123456789012:function:edge-prod-*"
    }
  ]
}

IAM Role for EC2/ECSΒΆ

Trust PolicyΒΆ

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Permissions PolicyΒΆ

Attach the complete IAM policy (see above) to this role.


IAM User SetupΒΆ

Create IAM UserΒΆ

aws iam create-user --user-name s3-provisioner-user

Attach PolicyΒΆ

# Create policy
aws iam create-policy \
  --policy-name S3ProvisionerPolicy \
  --policy-document file://policies/edge-prod-a001-us-west-1-s3_iam_policy.json

# Attach to user
aws iam attach-user-policy \
  --user-name s3-provisioner-user \
  --policy-arn arn:aws:iam::123456789012:policy/S3ProvisionerPolicy

Create Access KeysΒΆ

aws iam create-access-key --user-name s3-provisioner-user

Additional Permissions for Optional FeaturesΒΆ

VPC EndpointΒΆ

If using VPC endpoints (vpc_id configured):

{
  "Effect": "Allow",
  "Action": [
    "ec2:CreateVpcEndpoint",
    "ec2:DeleteVpcEndpoints",
    "ec2:DescribeVpcEndpoints",
    "ec2:ModifyVpcEndpoint",
    "ec2:DescribeRouteTables",
    "ec2:DescribeVpcs"
  ],
  "Resource": "*"
}

Lifecycle PoliciesΒΆ

Lifecycle policies are configured via CloudFormation, so no additional permissions needed beyond S3 bucket management.


Security Best PracticesΒΆ

1. Principle of Least PrivilegeΒΆ

Grant only permissions needed for specific actions. Use the generated IAM policy as a starting point.

2. Use Resource RestrictionsΒΆ

Always scope permissions to specific resources:

{
  "Resource": "arn:aws:s3:::edge-prod-*"
}

3. Use Condition KeysΒΆ

Add conditions for additional security:

{
  "Condition": {
    "StringEquals": {
      "aws:RequestedRegion": "us-west-1"
    }
  }
}

4. Separate Roles by EnvironmentΒΆ

  • s3-provisioner-dev-role - Development

  • s3-provisioner-staging-role - Staging

  • s3-provisioner-prod-role - Production

5. Enable MFA for Sensitive OperationsΒΆ

{
  "Condition": {
    "Bool": {
      "aws:MultiFactorAuthPresent": "true"
    }
  }
}

6. Rotate Credentials RegularlyΒΆ

  • Rotate access keys every 90 days

  • Use temporary credentials when possible

  • Audit credential usage with CloudTrail

7. Monitor IAM ActivityΒΆ

# Enable CloudTrail
aws cloudtrail create-trail \
  --name s3-provisioner-audit \
  --s3-bucket-name audit-logs-bucket

# Start logging
aws cloudtrail start-logging --name s3-provisioner-audit

Troubleshooting Permission IssuesΒΆ

Access Denied ErrorsΒΆ

# Check current user/role
aws sts get-caller-identity

# Test specific permission
aws s3api create-bucket \
  --bucket test-bucket-name \
  --region us-west-1 \
  --dry-run

Policy SimulatorΒΆ

Use AWS Policy Simulator to test permissions: https://policysim.aws.amazon.com/

CloudTrail LogsΒΆ

Check CloudTrail for denied API calls:

aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=CreateBucket \
  --max-results 10

Permission Summary by ActionΒΆ

Action

CloudFormation

S3

IAM

Lambda

EC2

validate-config

❌

❌

❌

❌

❌

create-policy

❌

❌

❌

❌

❌

create-prov-template

❌

❌

❌

❌

❌

validate-prov-template

❌

❌

❌

❌

❌

show-changes

βœ…

❌

❌

❌

❌

check-drift

βœ…

❌

❌

❌

❌

test-deploy

βœ…

βœ…

βœ…

βœ…

βœ…*

create-bucket

βœ…

βœ…

βœ…

βœ…

βœ…*

prep-master

❌

βœ…

❌

❌

❌

deploy-solution

❌

βœ…

❌

❌

❌

deploy-folders

❌

βœ…

❌

❌

❌

upload-template

❌

βœ…

❌

❌

❌

gitkeep-*

❌

βœ…

❌

❌

❌

purge-bucket

❌

βœ…

❌

❌

❌

delete-bucket

❌

βœ…

❌

❌

❌

delete-cfn-stack

βœ…

βœ…

βœ…

βœ…

βœ…*

tear-down

βœ…

βœ…

βœ…

βœ…

βœ…*

*Only if VPC endpoint configured


Additional ResourcesΒΆ

  • USER_GUIDE.md - Complete command reference

  • CONFIGURATION.md - Configuration reference

  • TROUBLESHOOTING.md - Common issues and solutions

  • S3_FOLDERS.md - Complete folder hierarchy reference

  • GOVERNANCE_COMPLIANCE.md - Enterprise governance implementation guide

  • ML_LIFECYCLE_POLICIES.md - Lifecycle policy patterns

  • AWS IAM Best Practices: https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html

  • S3 Security Best Practices: https://docs.aws.amazon.com/AmazonS3/latest/userguide/security-best-practices.html

  • IAM Policy Simulator: https://policysim.aws.amazon.com/

  • CloudFormation Permissions: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-iam-template.html


Copyright Β© 2025 Axon Tech Labs All rights reserved.

See LICENSE.txt for terms and conditions.