AWS IAM Policy Generator
Compose an IAM policy statement by statement — actions, resources and conditions — with the JSON structure checked as you build.
The picker is a curated subset — 30 common services. Every other service works through this field and is included verbatim; the authoritative action lists live in the AWS Service Authorization Reference.
Shape check only: this page can tell an ARN is well-formed, never whether it exists.
Optional — every condition in a statement must hold for it to apply.
Build a statement on the left — the policy JSON appears here, checked against the documented structure as you go.
Structure checks are not permission checks — only AWS policy evaluation decides what a policy grants. Composed on this device. No request is made to AWS or anywhere else.
Press ? for shortcuts
Do it offline:$ aws iam create-policy --policy-name MyPolicy --policy-document file://policy.json
How to use it
- Set the statement's effect — Allow, or Deny, which always overrides any Allow that also matches.
- Add actions from the service picker, or type any service:ActionName directly; both land as chips you can remove one by one.
- List resource ARNs one per line, or * for every resource. The shape arn:partition:service:region:account-id:resource is checked as you type — region and account-id may legitimately stay empty.
- Add condition rows when the statement should apply only sometimes, then copy the JSON — pretty for files and reviews, compact for inline CLI arguments.
An IAM policy is a JSON document with strict shape rules, and most of them bite only at upload time. Compose it here statement by statement — effect, actions, resource ARNs, condition rows — and read the canonical JSON as it forms, with every element checked against the documented grammar. Structure checks are not permission checks: only AWS evaluates what a policy grants. Nothing you type is sent anywhere, and no call to AWS exists.
Examples
Read-only access to one bucket: allow s3:GetObject and s3:ListBucket on example-bucket{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::example-bucket",
"arn:aws:s3:::example-bucket/*"
]
}
]
}Adapted from the AWS read-and-write bucket example, narrowed to the two read actions. Both ARN forms matter: the bare bucket ARN is what ListBucket authorizes against, while GetObject needs the /* object form — S3 treats bucket and objects as different resources.
Deny everything outside two EU regions, using a StringNotEquals condition{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": [
"*"
],
"Resource": [
"*"
],
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": [
"eu-central-1",
"eu-west-1"
]
}
}
}
]
}Adapted from the AWS deny-outside-requested-regions example. The original carves out global services such as IAM and Route 53 with NotAction; this simpler build denies them too, so keep that difference in mind before attaching it.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
A well-formed policy is not a safe policy
This page proves shape, never meaning. Whether the statement reaches the objects you intend, collides with another policy, or opens more than it should is decided by AWS policy evaluation at request time — no browser tool can know it. Treat the output as a draft for review, not a verdict.
The picker is 30 services; IAM is far more
The action picker covers 30 common services, each verified against its page in the AWS Service Authorization Reference — a curated subset, deliberately not a claim of completeness. Any other service works through the free-entry field, where only the documented service:ActionName grammar is enforced and the text is otherwise included verbatim.
The 6,144-character quota counts no whitespace
Customer managed policies cap at 6,144 characters, and IAM excludes whitespace when it counts — the status line here counts the same way, so pretty and compact views score identically. Past the quota the tool warns but still builds; trim actions or split the document before uploading it with aws iam create-policy, which requires the AWS CLI and your own credentials.
Common errors
Statement 1: Effect is "allow" — it must be exactly Allow or Deny (the value is case-sensitive).- The two Effect values are case-sensitive by specification, so a lowercase paste from a blog post or a YAML template fails at upload. The builder's Effect control only emits the exact spellings; this refusal appears when a shared link or restored state carries the lowercase form.
Statement 1: "s3GetObject" is not an action — actions are written service:ActionName (s3:GetObject), with * and ? wildcards allowed in the action name.- The colon between service prefix and action name is structural, not cosmetic — without it IAM cannot resolve the operation. Wildcards are allowed in the name part, so s3:Get* and even a bare * are accepted; a missing colon never is.
Statement 1: "arn:aws:s3" is not shaped like an ARN — the documented shape is arn:partition:service:region:account-id:resource (region and account-id may be empty), or * alone.- An ARN carries six colon-separated blocks, and S3 ARNs simply leave the region and account blocks empty rather than dropping them — arn:aws:s3:::example-bucket keeps all five colons. This check is shape-only: a perfectly formed ARN can still point at nothing.
FAQ
Which Version string should an IAM policy use?
Use 2012-10-17 — the current policy language, and the value this builder always emits. The only other documented value is 2008-10-17, which IAM also assumes when the element is missing; that older language ignores policy variables like ${aws:username}, so omitting Version is a quiet downgrade.
Can this tool tell me whether my policy is safe?
No. It verifies structure — element names, effect spelling, action grammar, ARN shape, condition operators — and nothing else. What the policy actually permits is determined by AWS policy evaluation, where explicit denies, other attached policies and permission boundaries all take part. For a meaning-level reading — wildcard reach, risky statement shapes — paste the finished JSON into the companion AWS IAM Policy Explainer, listed with the related tools on this page. Read the output before you attach it, ideally with a second pair of eyes.
Does my policy leave the browser?
No. Statements are composed and checked entirely on this device; the page makes zero requests with your input, and no code path calls AWS. Share links encode the statements in the URL fragment itself, and a confirmation interrupts sharing anything credential-shaped.
Keyboard shortcuts
- /
- Focus the action picker.
- ⌘/Ctrl + C
- Copy the policy JSON while no text is selected.
- ⌘/Ctrl + Shift + C
- Copy the whole policy JSON even mid-selection.
- t
- Advance the theme.
- ?
- Open the shortcut help overlay.
- Esc
- Dismiss the topmost overlay.