1001Ferramentas
☁️Generators

AWS IAM Policy Generator

Generate AWS IAM policy JSON (2012-10-17) from Effect, Actions and Resources.


  

AWS IAM Policies in depth: structure, conditions, and least-privilege patterns

An IAM policy is a JSON document that tells AWS who is allowed (or denied) to do what, on which resources, under which conditions. Every API call against AWS — from s3:GetObject to ec2:RunInstances — is authorised by the IAM policy engine, which evaluates the union of all policies attached to the calling principal and any resource policy on the target.

The mental model: everything is denied by default. An Allow grants permission; an explicit Deny always wins, even against an Allow elsewhere. This makes Deny powerful for guardrails (e.g., "no one outside corporate IPs can disable CloudTrail") but also makes troubleshooting tricky — a missing permission and an explicit deny look identical from the client side.

Anatomy of a policy

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ReadOnlyS3",
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:ListBucket"],
      "Resource": [
        "arn:aws:s3:::my-bucket",
        "arn:aws:s3:::my-bucket/*"
      ],
      "Condition": {
        "IpAddress": { "aws:SourceIp": "203.0.113.0/24" },
        "Bool":      { "aws:MultiFactorAuthPresent": "true" }
      }
    }
  ]
}

Version must always be "2012-10-17" (the date the current evaluation logic shipped — there is no newer version). Sid is an optional human label. Effect is Allow or Deny. Action, Resource, and Condition describe what, on what, and when.

Actions and resource ARNs

Actions follow service:Operation (case-sensitive). Wildcards are supported: s3:* means every S3 action, s3:Get* means every read. Be deliberate — iam:* on a policy is effectively root.

Resource ARNs follow arn:aws:service:region:account-id:resource-type/resource-id. Some services omit region and account (e.g., S3: arn:aws:s3:::bucket-name/*). Wildcards work in ARNs too — arn:aws:s3:::my-bucket/* matches every object in the bucket but not the bucket itself, which is why bucket-level actions like s3:ListBucket need a separate ARN without the trailing /*.

Conditions: the real power

  • Operators: StringEquals / StringLike (wildcard), NumericLessThan, DateGreaterThan, IpAddress, ArnLike, Bool — each has a ...IfExists variant for optional conditions.
  • Global keys: aws:SourceIp, aws:CurrentTime, aws:PrincipalOrgID, aws:MultiFactorAuthPresent, aws:MultiFactorAuthAge, aws:RequestTag/Env, aws:ResourceTag/Owner.
  • Service-specific keys: s3:prefix, ec2:InstanceType, kms:ViaService, etc. — see each service's IAM page.

A favourite pattern: "aws:MultiFactorAuthPresent": "true" to require MFA on sensitive operations; "aws:PrincipalOrgID": "o-abcd1234" to scope a resource policy to your AWS Organization only.

Policy types — know which one to use

  • Identity-based: attached to a user, group, or role. The most common kind.
  • Resource-based: attached directly to S3 buckets, SQS queues, SNS topics, Lambda functions, KMS keys. Include a Principal field that identity-based policies do not have.
  • Permissions Boundary: a ceiling on what an identity-based policy can grant. The effective permission is the intersection.
  • SCP (Service Control Policy): applied at AWS Organizations level. Pure deny-list — cannot grant, only restrict, even for the account root user.
  • Session policy: passed to sts:AssumeRole to further narrow a temporary session. Used by tools like aws-vault and CI federation.

Common pitfalls

  • NotAction and NotResource mean "everything except". They are rarely what you want — easy to over-grant by accident.
  • Explicit Deny always overrides Allow. Use this in SCPs and resource policies as guardrails, not for normal access control.
  • StringLike is case-sensitive — "s3:prefix": "Pictures/*" will not match pictures/foo.jpg.
  • Bucket-level vs object-level actions need different ARNs (with and without trailing /*).
  • Wildcards inside an ARN's account-id or resource-id work; wildcards in the partition or service segment do not.

Best practices and tooling

  • Start with AWS managed policies for common patterns (AmazonS3ReadOnlyAccess, AWSLambdaBasicExecutionRole) — they are maintained for you.
  • Run IAM Access Analyzer to detect unused permissions and unintended external access.
  • Use Policy Simulator to validate "can this principal do this action?" before deploying.
  • Open-source audit: Cloudsplaining, Parliament, iamlive to capture the actually-used permissions.
  • Cross-account access: prefer sts:AssumeRole over IAM users with long-lived keys. In EKS, use IRSA (IAM Roles for Service Accounts).
  • Enforce MFA on dangerous actions via aws:MultiFactorAuthAge < 3600.

FAQ

Identity-based vs resource-based policy? The difference is where it lives. Identity-based hangs off a user/role/group ("Alice can read this bucket"). Resource-based hangs off the resource ("This bucket lets Alice read it") and adds a Principal field. Both are evaluated together for cross-account access.

Does an explicit Deny always override Allow? Yes, in all contexts. This is the entire premise of SCPs and permissions boundaries — they cannot grant, only stop.

How many policies can one user have? 10 managed policies (attached by ARN) plus 10 inline policies by default. The combined size limit is 10,240 characters for users/roles. Hit it? Consolidate, or move logic into a resource policy.

What's the safest way to start writing a new policy? Begin with the minimal set of actions you know you need, deploy with Access Analyzer enabled, and let it tell you what is unused. The iamlive tool can also intercept SDK calls during a test run and emit the exact policy that satisfied them.

Can I have wildcards in the Principal field? Yes, "Principal": "*" makes a resource public — extremely dangerous for S3 buckets. Combine with "Condition": {"StringEquals": {"aws:PrincipalOrgID": "o-..."}} to scope to your org.

Related Tools