aws-cloudformation-iam · git:20260323.2528036 · 2026-03-23 · sha256 99f9339cfb7541a1

aws-cloudformation-iam git:20260323.2528036A

Immutable. This exact content is served forever at /api/v1/blob/99f9339cfb7541a1.

---
name: aws-cloudformation-iam
description: Provides AWS CloudFormation patterns for IAM roles, policies, managed policies, permission boundaries, and trust relationships. Use when modeling least-privilege access, cross-account assumptions, service roles, or reusable IAM stacks that other CloudFormation templates consume.
allowed-tools: Read, Write, Bash
---

# AWS CloudFormation IAM Security

## Overview

Use this skill to model IAM with CloudFormation in a way that stays secure, auditable, and maintainable.

The most important design concerns are:
- separating trust policies from permission policies
- preferring roles over long-lived users wherever possible
- keeping least-privilege boundaries readable and reusable

Do not treat `SKILL.md` as a full IAM encyclopedia. Use the bundled references for larger policy examples and service-specific variants.

## When to Use

Use this skill when:
- creating IAM roles for Lambda, ECS, EC2, Step Functions, or other AWS services
- defining inline policies, managed policies, and permission boundaries in CloudFormation
- modeling cross-account assume-role access with constrained trust policies
- exporting IAM role ARNs or managed policy ARNs to downstream stacks
- reviewing wildcard permissions, boundary drift, or role replacement risk
- creating small reusable IAM stacks for platform or application teams

Typical trigger phrases include `cloudformation iam`, `iam role template`, `assume role policy`, `permission boundary`, `cross account role`, and `least privilege cloudformation`.

## Instructions

### 1. Prefer roles, then define the trust boundary first

Start by deciding who or what needs to assume the role:
- AWS service principal such as Lambda or ECS tasks
- a user or role in another AWS account
- a federated identity provider or workload identity flow

Write the trust policy first so the principal and assumption conditions are explicit before you add permissions.

### 2. Add the smallest permission set that supports the workload

Grant only the actions and resources the workload needs:
- use inline policies for highly local role-specific access
- use managed policies when the same access pattern is shared across multiple principals
- scope resources tightly and use conditions where possible

Keep permission documents readable; break up very large policies instead of hiding complexity in one giant statement.

### 3. Use permission boundaries and naming conventions intentionally

Permission boundaries help platform teams constrain delegated role creation.

Apply them when:
- teams create or extend roles in their own stacks
- you need guardrails around privileged services such as IAM, KMS, or Organizations
- you want to separate maximum allowed permissions from application-specific policies

Name roles and policies consistently so stack outputs and audits remain easy to trace.

### 4. Model cross-account access carefully

For cross-account roles:
- trust only the exact source account, role, or principal type that needs access
- add conditions such as `sts:ExternalId` when appropriate
- keep the permission policy separate from the trust policy so audits stay clear
- export only the ARNs or names that consuming accounts actually need

### 5. Validate the effective behavior, not just the template

Before rollout:
- validate the template and review change sets
- inspect trust relationships for unintended principals
- review wildcard actions and resources
- test assume-role behavior from the real caller when possible
- confirm policy attachment, boundary application, and stack outputs match the intended security model

## Examples

### Example 1: Service role for Lambda with tightly scoped permissions

```yaml
Resources:
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: DynamoDbWritePolicy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - dynamodb:GetItem
                  - dynamodb:PutItem
                Resource: !GetAtt OrdersTable.Arn
```

### Example 2: Cross-account role with an external ID condition

```yaml
Resources:
  PartnerReadRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              AWS: arn:aws:iam::123456789012:role/partner-reader
            Action: sts:AssumeRole
            Condition:
              StringEquals:
                sts:ExternalId: partner-contract-001
```

Keep the trust relationship narrow and pair it with a separate read-only permission policy.

## Best Practices

- Prefer IAM roles over long-lived IAM users for application and automation access.
- Separate trust policies from permission policies when reviewing or refactoring templates.
- Use permission boundaries when delegating role creation to other teams.
- Scope resources, actions, and conditions as tightly as the workload allows.
- Export stable ARNs and names only when another stack truly consumes them.
- Keep expanded policy libraries and edge cases in `references/` instead of bloating the root skill.

## Constraints and Warnings

- Overly broad wildcards in IAM are easy to deploy and hard to notice later.
- Named IAM resources can be hard to replace safely once other systems depend on them.
- IAM changes may appear successful in CloudFormation before eventual consistency settles across AWS services.
- Some Identity Center or organization-wide access patterns need complementary tooling outside a single CloudFormation stack.
- Misconfigured trust policies are often a bigger risk than missing permissions.

## References

- `references/examples.md`
- `references/reference.md`

## Related Skills

- `aws-cloudformation-security`
- `aws-cloudformation-ec2`
- `aws-cloudformation-ecs`
- `aws-cloudformation-lambda`