All Tools View Categories About Contact Privacy

Least-Privilege IAM Policy Generator

A minimal starting policy scaffold, scoped to a specific resource ARN — a curated starting point, not a usage-based analysis.

Runs entirely in your browser — nothing you enter is uploaded.
0
actions
-
level
-
resource scoped
-
structurally valid

  

About Least-Privilege IAM Policy Generator

Most people writing a first-draft IAM policy start from one of two bad places: a full-access managed policy they intend to "trim down later" (and rarely do), or a blank statement they build up action-by-action from documentation while genuinely unsure which permissions are actually required. Least-Privilege Policy Generator gives you a third, better starting point — a short, curated action list for a specific service and access level, always scoped to a real resource ARN you provide, never to a bare wildcard.

Pick one of six commonly-used services — S3, Lambda, DynamoDB, EC2, SQS, or SNS — and a level: read-only or read-write. Each combination maps to a small, hand-curated action list reflecting the operations that access pattern typically needs: for S3 read-only, that is s3:GetObject and s3:ListBucket; read-write adds s3:PutObject and s3:DeleteObject on top. The read-write list for every service is always a strict superset of the read-only list for that same service — nothing is silently swapped out, only added. Supply the resource ARN this policy should apply to — a specific bucket, table, queue, topic, function, or instance — and the tool builds one Allow statement with that action list and that exact resource.

The resource ARN is not optional and not decorative. This tool is built around a specific, enforced constraint: it will not produce a statement with Resource: "*". The ARN you provide is validated with the same structural ARN checker used across this site's other tools — a correct partition, a recognized service prefix, an account-id that is either empty or exactly 12 digits, and a region that looks like a real AWS region code — and if it does not validate, the tool refuses to build a statement rather than quietly falling back to a wildcard. That refusal is the entire value proposition: a policy that always grants against one named resource cannot silently become an account-wide grant just because a field was left blank.

It is important to be precise about what "least privilege" means here, because the phrase gets used loosely. This tool does not look at your account, does not read CloudTrail event history, and is not a substitute for a usage-based generator like AWS Access Analyzer's policy generation feature, which observes real API calls over a time window and builds a policy from what actually happened. What this tool does instead is pattern-match: given a service and a coarse access level, it returns the small set of actions that pattern commonly requires, curated by hand rather than derived from your specific application's behavior. That is a genuinely useful starting scaffold — far tighter than a managed full-access policy, and far faster than building an action list from scratch — but it is a starting point for review and trimming, not a finished least-privilege policy for your exact use case. The tool's own copy says this plainly rather than overselling what a curated table can know about your application.

One service-specific caveat is surfaced directly rather than glossed over: EC2's Describe* family of actions, including ec2:DescribeInstances in the read-only list here, does not support IAM resource-level permissions at all for most of that family. Scoping the statement's Resource to one instance ARN does not actually restrict which instances the caller can describe — the permission still applies account-wide for that action, regardless of what Resource value is present. ec2:StartInstances and ec2:StopInstances in the read-write list do respect resource-level scoping correctly. This is an AWS platform limitation, not a bug in this generator, and it is called out in the output so the resource-scoping guarantee this tool otherwise makes is not misread as applying uniformly to every action on every service.

Once built, the statement is wrapped in a full policy document and run through the same structural validator used across this category — confirming Version, a non-empty Statement array, and the required Effect/Action/Resource fields are present — before you copy or download it. Nothing you enter is sent anywhere; the action lookup, ARN validation, and JSON assembly all run in your browser.

Features

  • Six curated services — S3, Lambda, DynamoDB, EC2, SQS, SNS.
  • Read-only and read-write action levels, with read-write always a strict superset of read-only.
  • Resource ARN is required and validated — the tool refuses to build a statement with a bare "*" or a malformed ARN.
  • Honest scaffolding, not usage analysis — clearly distinguished from CloudTrail-based or Access Analyzer-style generators.
  • EC2 resource-level-permission caveat surfaced directly in the output, not just in the FAQ.
  • Structural policy validation before you copy the result.
  • Sample scaffold preloads a realistic S3 read-only example.
  • Copy as JSON and Download .json.
  • One-click clear.
  • 100% client-side — nothing you type is uploaded.

How to Use

  1. Pick a service — S3, Lambda, DynamoDB, EC2, SQS, or SNS.
  2. Pick an access level — read-only or read-write.
  3. Enter the resource ARN this policy should apply to.
  4. Click Build scaffold.
  5. Review the action list — remove anything your application does not actually call.
  6. Check the resource-level-permission note if you picked EC2.
  7. Copy or download the JSON as your starting draft.

Examples

Example 1 — S3 read-only for an app bucket. Service S3, level Read-only, resource arn:aws:s3:::my-app-bucket — produces an Allow statement with s3:GetObject and s3:ListBucket scoped to that bucket.

Example 2 — DynamoDB read-write for one table. Service DynamoDB, level Read-write, resource arn:aws:dynamodb:us-east-1:123456789012:table/Orders — produces dynamodb:GetItem, Query, Scan, PutItem, UpdateItem, DeleteItem scoped to that table.

Example 3 — Lambda read-write for a function. Service Lambda, level Read-write, resource arn:aws:lambda:us-east-1:123456789012:function:process-orders — includes lambda:InvokeFunction and lambda:UpdateFunctionCode scoped to that function.

Example 4 — SQS read-only for a queue. Service SQS, level Read-only, resource arn:aws:sqs:us-east-1:123456789012:order-events — produces sqs:ReceiveMessage and sqs:GetQueueAttributes.

Example 5 — invalid ARN is rejected. Entering my-bucket (not a real ARN) instead of arn:aws:s3:::my-bucket produces a validation error and no statement, rather than a silent wildcard.

Benefits

  • Never produces a bare "*" Resource — the core guarantee of this tool, enforced by validation, not just described.
  • Much tighter starting point than a full-access managed policy.
  • Faster than building an action list from documentation for the common S3/Lambda/DynamoDB/EC2/SQS/SNS patterns.
  • Honest about its own limits — clearly not a CloudTrail-based or usage-analysis generator.
  • Surfaces the EC2 resource-level-permission caveat instead of implying uniform scoping.
  • Structurally validated output before you attach it.
  • Private — nothing typed here leaves your browser.

Frequently Asked Questions

Does this tool analyze my actual usage or CloudTrail logs to figure out real least privilege?
No. This is honest scaffolding, not usage analysis: it maps a service and an access level (read-only or read-write) to a short, curated list of the actions most commonly needed for that pattern, and scopes them to the resource ARN you provide. It has no access to your account, your CloudTrail history, or Access Analyzer's policy-generation feature (which does look at real usage). Treat the output as a reasonable starting point to trim further, not a guarantee that every action listed is one your specific application actually calls.
Why does it require a specific resource ARN instead of letting me use "*"?
Because a Resource of "*" is the opposite of least privilege — it grants the listed actions against every resource of that type in the account. This tool is specifically built to never produce that: the resource ARN field is required and validated, and the statement builder throws rather than falling back to a wildcard if the ARN does not parse.
What counts as "read-only" vs "read-write" here?
Read-only is the minimum set of actions to fetch or list the resource's data (e.g. s3:GetObject + s3:ListBucket). Read-write adds the mutating actions on top of the same read set (e.g. s3:PutObject + s3:DeleteObject) — it is always a strict superset of read-only for the same service, never a different, disjoint list.
Which services are covered?
Six: S3, Lambda, DynamoDB, EC2, SQS and SNS, each with a curated read and read-write action list. This is not an exhaustive service catalog — it covers the services and access patterns that come up most often when someone needs a quick, sane starting policy.
Why does the EC2 read-only list include ec2:DescribeInstances even though the resource is scoped to one instance?
Because that is an honest reflection of an AWS limitation, not a mistake in this tool: many EC2 Describe* actions do not support resource-level permissions at all, so scoping their Resource to a specific instance ARN does not actually restrict which instances can be described — the call still succeeds for any instance in the account. ec2:StartInstances and ec2:StopInstances, included in the read-write set, do support resource-level scoping properly. This caveat is called out directly in the tool's output area, not buried.
Should I attach the generated policy as-is?
Treat it as a starting draft. Review the action list against what your application genuinely calls, remove anything unused, and consider narrowing further (for example, scoping S3 permissions to a prefix instead of the whole bucket) before attaching it to a real role.
Does it validate the resource ARN?
Yes — it runs the same ARN validator used elsewhere in this tool category (partition, service, account-id and region shape checks) before it will build a statement, so a malformed ARN is rejected with a specific error instead of silently producing a broken policy.
Can I add more than one service to the same policy?
This generator builds one statement for one service and one resource ARN per run. To combine services, generate each statement separately and merge the resulting Statement array entries into one policy document by hand.
Is anything I type sent anywhere?
No — the action-list lookup, ARN validation, and statement building all run locally in your browser.
Can I export the result?
Yes, Copy as JSON and Download .json appear once a scaffold is built.