Originally published at shieldly.io/blog.
Most IAM security conversations center on the AWS console or raw JSON policy documents. But a significant share of production IAM misconfigurations originates in CloudFormation templates. By the time a CF stack is deployed, the IAM roles and policies inside it are live — and unless you reviewed the template before running cdk deploy or aws cloudformation create-stack, you may not have noticed what you just granted.
Why CloudFormation IAM Risk Is Different
In a CloudFormation template, IAM roles are buried alongside compute resources, storage buckets, and networking config. Reviewers focused on architecture often skim past the Properties.Policies block on a Lambda execution role.
A single CloudFormation template may create five roles, two managed policy attachments, and three inline policies — all in a single deploy. The blast radius of an overly-permissive role is multiplied by every resource that role is attached to.
The Most Common CF IAM Mistakes
AdministratorAccess on Lambda execution roles. Tempting during development. In production it grants Action: * on Resource: * to every invocation:
# DO NOT SHIP THIS
Type: AWS::IAM::Role
Properties:
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AdministratorAccess
Action: * in inline policies. Inline policies defined inside an AWS::IAM::Role resource are easy to overlook:
Policies:
- PolicyName: InlinePolicy
PolicyDocument:
Statement:
- Effect: Allow
Action: "*" # Admin access, probably unintentional
Resource: "*"
Missing permission boundaries on auto-created roles. Without a boundary, any policy attached to the role later is unconstrained.
Wildcard Resource on DynamoDB and S3. Scoping actions correctly but leaving Resource: *:
Statement:
- Effect: Allow
Action:
- dynamodb:GetItem
- dynamodb:PutItem
Resource: "*" # applies to every table in the account
Fix: replace with the specific table ARN.
How CDK Makes It Easier to Slip Up
CDK provides escape hatches — addToRolePolicy, addOverride, raw PolicyStatement objects — that let developers bypass guardrails. A single escape-hatch call can inject an Action: * statement into an otherwise well-scoped role, and nothing in the CDK build output will flag it.
Catching It Before Deploy
1. Analyze the synthesized template. cdk synth produces the CloudFormation JSON/YAML. Analyze that output before any deploy command runs.
2. Policy review gates in CI. Add a template analysis step to your CI pipeline that runs on every PR touching infrastructure files. Fail the pipeline on HIGH or CRITICAL IAM findings.
# .github/workflows/shieldly.yml
- name: Analyze CloudFormation IAM
uses: shieldly-io/action@v1
with:
paths: cdk.out/**/*.template.json
fail-on-severity: HIGH
env:
SHIELDLY_API_KEY: ${{ secrets.SHIELDLY_API_KEY }}
Analyze CF templates automatically — paste a template into Shieldly's free AI-Powered analysis. No signup, no credit card.
Launch offer: code 90Off2M — 90% off first 2 months. Pro from $1.90/mo. shieldly.io/pricing












