AWS IAM Policy Generator

Build an AWS IAM policy as clean JSON. Pick a service, tick the exact actions you want to allow or deny, set the resource ARNs, and optionally add a condition such as SSL-only, a source-IP allow-list, or required MFA. The tool writes a valid policy document scoped to just those actions and resources — least-privilege by default. Everything is generated in your browser; no credentials are involved.

IAM policy (JSON)

How to use the AWS IAM Policy Generator

Choose whether the statement allows or denies, then pick a service to load its common actions. Tick only the actions you actually need — the whole point of an IAM policy is to grant the minimum. Set the resource ARNs the statement applies to, one per line; use the service-specific template as a starting point and replace the account ID, region, and resource name with yours, or use * only when a scope is genuinely global. Add a condition if you want to require encrypted transport, lock access to an IP range, or demand MFA.

Copy the JSON into a customer-managed policy in the IAM console, a Terraform aws_iam_policy, or a CloudFormation template. The generator produces a single statement; a real policy often combines several, so paste this as one element of a larger Statement array when you need different actions on different resources. Always validate the result with the IAM policy simulator before attaching it to a role in production.

How IAM policies work

An IAM policy is a JSON document that defines permissions in AWS. Every policy has a Version (always 2012-10-17 for the current language) and a list of statements, each combining four ideas: an Effect (Allow or Deny), one or more Actions (service operations like s3:GetObject), one or more Resources (the ARNs the actions apply to), and optional Conditions that gate when the statement is in force.

AWS evaluates access by collecting every policy that applies to the request — identity policies, resource policies, permission boundaries — and applying a simple rule: an explicit Deny always wins, otherwise access requires at least one explicit Allow, and anything not allowed is denied by default. This is why least-privilege policies list specific actions and narrow ARNs rather than reaching for "Action": "*" on "Resource": "*", which grants far more than almost any workload needs.

Conditions are where a lot of real-world security lives. A Bool condition on aws:SecureTransport can deny any request not made over TLS; an IpAddress condition on aws:SourceIp restricts access to known networks; a check on aws:MultiFactorAuthPresent requires MFA for sensitive operations. Because conditions attach to a statement, you can grant broad actions but only under safe circumstances. This generator scopes actions and resources tightly and lets you attach these common guard conditions, producing a policy that follows AWS's own least-privilege guidance.

Common use cases

  • Scoped service access. Grant an app exactly the S3 or DynamoDB actions it needs and nothing more.
  • Hardening. Add SSL-only or MFA conditions to an existing permission set.
  • IaC snippets. Generate the policy JSON for a Terraform or CloudFormation resource.
  • Learning IAM. See how effect, action, resource, and condition fit together in valid syntax.

Frequently asked questions

How does AWS decide whether a request is allowed?

It gathers all applicable policies and applies precedence: an explicit Deny anywhere overrides everything, otherwise the request needs at least one explicit Allow, and anything not explicitly allowed is implicitly denied. So adding an Allow grants access only if no Deny and no boundary blocks it.

Why scope actions and resources instead of using *?

A policy of Action: * on Resource: * grants every operation on every resource — far more than a workload needs and a serious risk if the credentials leak. Least privilege means listing the specific actions and narrowing the ARNs, so a compromise is contained. This generator defaults to specific actions for that reason.

What goes in the Resource ARNs?

The Amazon Resource Names the statement applies to, like arn:aws:s3:::my-bucket/* for objects in a bucket. Replace the account ID, region, and resource name in the templates with your own. Some actions (such as s3:ListAllMyBuckets) only support *, because they are account-wide rather than per-resource.

When should I use a Deny statement?

Use Deny as a guardrail that cannot be overridden by an Allow — for example denying all actions when aws:SecureTransport is false, or fencing off a sensitive resource. Because Deny always wins, a small explicit Deny is a strong way to enforce a rule across broader Allow grants.

Is this policy ready to attach as-is?

Treat it as a well-formed starting point. You must replace the placeholder ARNs with real values, and you should run it through the IAM policy simulator and review it against your needs before attaching it to a role. The tool generates one statement; combine several for a complete policy.