5 views
This guide covers IAM Access Analyzer AI policies with production-focused examples and trade-offs.
AI coding agents invent IAM JSON with the confidence of a junior who discovered ChatGPT and the blast radius of a senior who forgot to open the simulator. Wildcards, missingCondition blocks, and Resource: "*" on s3:* show up dressed as “least privilege.” Access Analyzer plus the policy simulator are the gates—not vibes.
⚡ TL;DR: Treat model-emitted IAM as untrusted input. Run Access Analyzer (policy validation + external access findings), simulate every statement against deny/allow fixtures, and only then attach via CI. Reject * Actions/Resources unless an allowlisted exception ticket exists. Pair with Cursor Rules for AWS CDK and AI-Written Terraform Plan Diff Gates.
Never attach raw model JSON — IAM Access Analyzer AI policies
typescript
✅ Analyzer + regex denylist before any // scripts/iam-ai-gate.ts
import { IAMClient, SimulatePrincipalPolicyCommand } from "@aws-sdk/client-iam";
import { AccessAnalyzerClient, ValidatePolicyCommand } from "@aws-sdk/client-accessanalyzer";
export type AiPolicyDraft = {
policyDocument: string;
roleName: string;
ticket: string;
};
const FORBIDDEN = [
/"Action"\s*:\s*"\*"/,
/"Action"\s*:\s*\[["']\*["']\]/,
/"Resource"\s*:\s*"\*"/,
/"NotAction"/,
];
export function assertNoWildcards(doc: string) {
for (const re of FORBIDDEN) {
if (re.test(doc)) throw new Error(`forbidden_iam_pattern:${re}`);
}
}
export async function validateWithAnalyzer(doc: string) {
const aa = new AccessAnalyzerClient({});
const out = await aa.send(new ValidatePolicyCommand({
policyDocument: doc,
policyType: "IDENTITY_POLICY",
}));
const errors = (out.findings ?? []).filter((f) => f.findingType === "ERROR");
if (errors.length) throw new Error(JSON.stringify(errors));
return out.findings ?? [];
}
PutRolePolicy.❌
aws iam put-role-policy from an agent shell with no simulation.
Simulate the happy path and the deny path
typescript
Encode fixtures next to the policy in the PR so reviewers see intent, not only JSON. For CDK-generated policies from agents, see Secure AI Sandboxes.
const iam = new IAMClient({});
export async function simulateMustAllow(roleArn: string, actions: string[], resources: string[]) {
const r = await iam.send(new SimulatePrincipalPolicyCommand({
PolicySourceArn: roleArn,
ActionNames: actions,
ResourceArns: resources,
}));
for (const e of r.EvaluationResults ?? []) {
if (e.EvalDecision !== "allowed") {
throw new Error(`expected_allow:${e.EvalActionName}:${e.EvalDecision}`);
}
}
}
export async function simulateMustDeny(roleArn: string, actions: string[], resources: string[]) {
const r = await iam.send(new SimulatePrincipalPolicyCommand({
PolicySourceArn: roleArn,
ActionNames: actions,
ResourceArns: resources,
}));
for (const e of r.EvaluationResults ?? []) {
if (e.EvalDecision === "allowed") {
throw new Error(`expected_deny_got_allow:${e.EvalActionName}`);
}
}
}
// Fixture: agent proposed s3:GetObject on payments bucket — must allow
// Same role must DENY s3:DeleteBucket on org-security bucket
CI gate shape
yaml
# .github/workflows/iam-ai-gate.yml
name: iam-ai-gate
on:
pull_request:
paths: ["infra/iam/**", "**/iam-policies/**"]
jobs:
analyze:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: pnpm tsx scripts/iam-ai-gate.ts --dir infra/iam
- name: Fail on Access Analyzer ERROR findings
run: test ! -s analyzer-errors.json
Feedback loop into the generator
Feed Analyzer findings back into the next model prompt as structured negatives—same spirit as banned-API allowlists in Agent Tool Allowlists—paste Analyzer findings into the agent system prompt as hard bans.text
DENIED_PATTERNS:
- Action "*"
- Resource "*" on iam:*, kms:*, s3:*
- Missing aws:PrincipalOrgID on cross-account trusts
Closing checklist
- [ ] Access Analyzer
ValidatePolicyreturns zero ERROR findings - [ ] Policy simulator has allow fixtures and deny fixtures
- [ ] Wildcards blocked unless exception ticket referenced in PR body
- [ ] Attach only from CI role, never from laptop long-lived keys
- [ ] CloudTrail alarm on
PutRolePolicy/AttachRolePolicyoutside the pipeline - [ ] Agent tool that mutates IAM requires human dual-control (see AI On-Call Copilots)
Related reading
- Cursor Rules for AWS CDK: Stop AI From Inventing IAM Wildcards
- AI-Written Terraform: Plan Diff Gates Before Any Apply Runs
- Agent Tool Allowlists: Least Privilege for Filesystem and Shell Access
- Cross-Account Bedrock Access: Platform Teams Without Shared Keys
Related: IAM Credential Canaries: Catch Leaked Laptop Keys Before Prod Blast Radius · Day 65: PII Redaction Before Embeddings · Day 14: Guardrails Before Clever Prompts
Watch: 100 Days of AI on YouTube
Short videos from CheatCoders, one AI engineering topic per day.
Most viewed
- Python Decorators Explained: From Simple Wrappers to Production Patterns
- Claude Code vs Cursor vs GitHub Copilot: Choose by Workflow, and Set Up One Repo That Works With All Three
- AI Agent Frameworks in 2025: LangGraph vs CrewAI vs AutoGen vs Raw API
- Python String Methods: Every str Method With Real Production Examples
- Css Animation Performance: Performance-Optimized Motion for Modern UIs
Newly added
- AWS Systems Manager Parameter Store: Hierarchical Runtime Config for Coding Agents
- Amazon Cognito Identity Pools: Federate Coding-Agent Tool Callers Without Long-Lived Keys
- Amazon Athena for Coding Agents: Query Tool Audit Logs and Eval Traces on S3 Without a Warehouse
- AWS Batch for Coding Agents: Parallel Overnight PR Reviews and Long-Running Jobs Without Lambda Timeouts
- Amazon Bedrock Prompt Management: Version and A/B Test Coding-Agent System Prompts
Deep-dive PDF
Get the expanded guide for this post — extra diagrams-style checklists, failure modes, and a production walkthrough. Free when you subscribe to CheatCoders.
Already subscribed? or open the subscribe page.
Discover more from CheatCoders
Subscribe to get the latest posts sent to your email.
