IAM policy action minimizer: wildcards to the required action list
Takes an AWS IAM policy JSON and the exact list of actions a task needs (up to 300), and returns the policy with each Allow statement's Action narrowed to just those actions, plus what the original over-grants: wildcards, unused actions, Allow+NotAction, required actions no statement grants, and required actions an unconditional Deny blocks. For an agent that is about to attach or propose a policy. Wildcards are matched case-insensitively with * and ?, as IAM does. It does not evaluate Resource ARNs, Conditions, permission boundaries, SCPs or session policies, and it ships no AWS action catalog: pass knownActions (from the AWS service reference) to measure how many extra actions a wildcard grants. The minimized policy is only as complete as the required list.
What you get
s3:* where s3:GetObject was needed is the usual over-grant. The minimized policy and the witnesses show the exact difference.
Call it
Send the JSON body below to https://agents.writerslogic.com/api/v1/iam-minimize. An unpaid request answers 402 with the price and how to pay; a request that fails with a 5xx status is not charged.
curl -i -X POST https://agents.writerslogic.com/api/v1/iam-minimize \
-H 'content-type: application/json' \
-d '{"policy":{"Version":"2012-10-17","Statement":[{"Sid":"Read","Effect":"Allow","Action":["s3:Get*","s3:ListBucket","logs:PutLogEvents"],"Resource":"arn:aws:s3:::my-bucket/*"}]},"requiredActions":["s3:GetObject","s3:ListBucket"],"knownActions":["s3:GetObject","s3:GetObjectAcl","s3:GetBucketPolicy","s3:ListBucket","s3:PutObject"]}'
Input
| Field | Type | Required | Description |
|---|---|---|---|
policy | any | yes | The IAM policy document as a JSON object or JSON string. At most 60,000 characters. |
requiredActions | array<string; length 3..128>; max 300 items | yes | Concrete actions the task needs, e.g. s3:GetObject. No wildcards. |
knownActions | array<string; length 0..128>; max 3000 items | no | Optional catalog of real actions (from the AWS service reference JSON), used to count what each wildcard grants. |
Example request body
{
"policy": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Read",
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:ListBucket",
"logs:PutLogEvents"
],
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
},
"requiredActions": [
"s3:GetObject",
"s3:ListBucket"
],
"knownActions": [
"s3:GetObject",
"s3:GetObjectAcl",
"s3:GetBucketPolicy",
"s3:ListBucket",
"s3:PutObject"
]
}
Result
The response is { "data": ..., "_provenance": ... }. data carries these fields; _provenance is a signed W3C Verifiable Credential with a C2PA-style manifest, checked free at POST /api/v1/verify-provenance.
| Field | Type | Required | Description |
|---|---|---|---|
status | string; one of "pass", "fail", "unknown", "unsupported" | no | pass: every rule held. fail: a rule was violated (see witnesses). unknown: the input lacks the evidence to decide. unsupported: outside what this engine covers. Missing evidence is never a pass. |
minimized | any | no | Null when the policy is malformed. The policy with Allow actions narrowed to the required list; Deny statements, Resource, Condition and other elements are unchanged. |
statements | array<object> | no | |
notGranted | array<string> | no | Required actions no Allow statement grants. |
unverified | array<string> | no | Things this check could not evaluate (Resource scope, conditional Deny, empty catalog matches). |
witnesses | array<object> | no | |
versions | object | no | Every semantic dependency of this answer (engine, tables and their as-of dates, tokenizer, calendar, rounding profile). |
limits | array<string> | no | |
deterministic | boolean | no | Always true: pure code, no model. |
Pay and connect
Available through: x402 (USDC on Base), MCP. MCP clients reach it through the infra-preflight-kit package.
Machine-readable
- This agent as JSON (schemas, example, OpenAPI operation)
- Free signed sample response
- OpenAPI 3.1 · Catalog · Index of every agent