Skip to content
intermediate Phase 6 · Identity & Access Management

IAM Policy Management

Write IAM policies with least-privilege principles, use policy variables, and evaluate permissions with IAM Access Analyzer.

55m
0 problems
Topic Progress 0%

JSON Policy Structure

IAM policies are JSON documents with a standard structure. Understanding each element is essential for writing correct and secure policies.

A policy contains a Version (always 2012-10-17), an optional Id, a Statement array with one or more statements, and each statement contains:

  • Effect: Either Allow or Deny. There is no implicit allow; unmentioned actions are implicitly denied.
  • Action: Specifies the API actions allowed or denied. Use service:Action format like s3:GetObject or wildcards like s3:*.
  • Resource: The ARN(s) of the affected resources. Use * for all resources, but prefer specific ARNs for least privilege.
  • Condition (optional): Conditions that must be true for the statement to apply, based on request context.

Example policy granting read access to a specific S3 bucket:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": ["s3:GetObject", "s3:ListBucket"],
    "Resource": [
      "arn:aws:s3:::my-bucket",
      "arn:aws:s3:::my-bucket/*"
    ]
  }]
}

Note that s3:GetObject requires the object ARN (with /*), while s3:ListBucket requires the bucket ARN. Different actions require different resource ARNs.

Policy Evaluation Logic

When an API call is made, IAM evaluates all applicable policies to determine whether to allow or deny the request. The evaluation follows specific rules.

Default Deny: By default, all requests are denied. An explicit policy must allow an action for it to succeed.

Explicit Deny Overrides Allow: If any policy contains an explicit Deny for the requested action, the request is denied regardless of any Allow statements. This is the most important rule: explicit deny always wins.

Multiple Policies: When multiple policies apply, IAM evaluates all of them. If any policy denies, the request is denied. If at least one policy allows and none deny, the request is allowed.

Policy Evaluation Flow:

  1. Start with implicit deny
  2. Evaluate all identity-based policies (attached to user/group/role)
  3. Evaluate all resource-based policies (attached to resource)
  4. Evaluate permission boundaries
  5. Evaluate session policies (for assumed roles)

For example, if a user's group policy allows s3:GetObject but an inline policy denies s3:GetObject on a specific bucket, the user cannot access that bucket even though the group allows it.

Cross-Account Access: For cross-account scenarios, both the trusting account (resource owner) and the trusted account (requestor) must have policies that allow the action. The request must pass both accounts' policy evaluations.

Policy Variables and Condition Keys

Policy variables and condition keys make policies dynamic and context-aware, reducing the number of policies needed.

Policy Variables use ${variable-name} syntax to reference dynamic values at request time. The aws:username variable allows a policy to reference the requesting user:

{
  "Effect": "Allow",
  "Action": "s3:PutObject",
  "Resource": "arn:aws:s3:::my-bucket/home/${aws:username}/*"
}

This lets each user write objects only to their own folder. Without variables, you would need a separate policy for each user.

Condition Keys are pre-request or post-request context values. Common keys include:

  • aws:SourceIp: Restrict access by IP address
  • aws:CurrentTime: Restrict by time of day
  • aws:PrincipalTag: Use tags on the calling principal
  • s3:prefix: Control which S3 prefixes a user can list

Example: Restrict access to business hours:

"Condition": {
  "DateGreaterThan": {"aws:CurrentTime": "2024-01-01T08:00:00Z"},
  "DateLessThan": {"aws:CurrentTime": "2024-01-01T18:00:00Z"}
}

IAM Access Analyzer helps validate policies by identifying resources shared with external entities and detecting overly permissive policies. It runs against a sample of your CloudTrail logs to find the actual permissions required.

Wildcard Restrictions and Security

Wildcard usage in IAM policies is a common source of security vulnerabilities. Controlling wildcards is essential for maintaining least privilege.

Dangerous Wildcards:

  • Action: "*" allows every API action, equivalent to administrator access
  • Resource: "*" applies the policy to all resources
  • Resource: "arn:aws:s3:::*" allows access to every S3 bucket

Safer Alternatives:

  • Use specific actions: s3:GetObject instead of s3:*
  • Use specific ARNs: arn:aws:s3:::my-bucket/* instead of *
  • Use wildcards only for variable parts: arn:aws:s3:::app-logs-${aws:region}/*

IAM Access Analyzer flags overly permissive policies by detecting:

  • Policies granting access to external principals
  • Policies with wildcards on resources
  • Unused permissions based on CloudTrail logs

A practical approach is to use IAM Access Analyzer to generate a policy based on CloudTrail logs. Start with broad permissions, run the analyzer, and it generates a refined policy with only the actions and resources actually used.

Policy Conditions as Guards: When wildcards are necessary, use conditions to add guardrails. For example, allow s3:* on a bucket but restrict by s3:prefix to limit which paths are accessible, or use aws:SourceIp to restrict access to corporate networks.

Quiz

1. What happens when an Allow and a Deny statement conflict in IAM?

Question 1 options

2. What is the default behavior for unmentioned actions in IAM?

Question 2 options

3. What does the policy variable ${aws:username} represent?

Question 3 options

4. Why should you use specific resource ARNs instead of wildcards?

Question 4 options

5. What does IAM Access Analyzer help you identify?

Question 5 options

Flashcards

Question

Policy Effect

Answer

Either Allow or Deny. Default behavior is implicit deny. Explicit Deny always overrides Allow.

Question

Policy Evaluation Order

Answer

1. Implicit deny. 2. Identity-based policies. 3. Resource-based policies. 4. Permission boundaries. 5. Session policies.

Question

Policy Variables

Answer

Dynamic values using ${variable-name} syntax, like ${aws:username}. Resolved at request time to personalize policies.

Question

Condition Keys

Answer

Context-based conditions that must be true for a policy statement to apply. Include SourceIp, CurrentTime, and PrincipalTag.

Question

IAM Access Analyzer

Answer

Tool that validates policies, identifies overly permissive permissions, finds unused permissions, and detects external resource sharing.

Revision Notes

Key Takeaways

  • 1. Policy structure: Version, Statement array with Effect, Action, Resource, Condition
  • 2. Explicit Deny always overrides Allow; default is implicit Deny
  • 3. Use policy variables like ${aws:username} for dynamic personalization
  • 4. Condition keys enable context-aware policies (IP, time, tags)
  • 5. IAM Access Analyzer validates policies and detects overly permissive access
  • 6. Use specific ARNs and actions; wildcards should be avoided or guarded with conditions

Interview Tips

  • Walk through the policy evaluation flow step by step
  • Explain why explicit Deny overrides Allow with an example
  • Describe how policy variables reduce the number of policies needed
  • Discuss how IAM Access Analyzer helps with least privilege

Cheat Sheet

Policy = Version + Statement[] (Effect, Action, Resource, Condition). Default = implicit Deny. Explicit Deny > Allow. Variables: ${aws:username}, ${aws:region}. Conditions: SourceIp, CurrentTime, PrincipalTag. IAM Access Analyzer = validate policies + find external sharing. Use specific ARNs, avoid wildcards.