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.