Introduction

IAM condition keys such as aws:SourceIp look straightforward until the request path changes. A role or user can have all the right permissions and still get AccessDenied because the request now originates through a NAT gateway, VPC endpoint path, or different egress address than the policy expected. These failures often appear suddenly after infrastructure changes rather than IAM changes.

Symptoms

  • AWS API calls fail with AccessDenied even though the principal otherwise has the right action permission
  • Access works from one network path but fails from another
  • A recent NAT, proxy, VPN, or VPC endpoint change preceded the failure
  • IAM policy simulation shows a condition mismatch rather than a missing allow

Common Causes

  • The real source IP changed after NAT or egress architecture changes
  • The policy CIDR range is too narrow or stale
  • IPv6 or alternate egress paths are not covered by the condition
  • The wrong condition key is used for the network model in question

Step-by-Step Fix

  1. 1.Identify the real source IP path
  2. 2.Do not assume you know the request origin. Confirm whether traffic exits through a NAT gateway, public IP, VPN, or endpoint path.
  3. 3.Simulate the policy with the actual source IP
  4. 4.IAM simulation can quickly show whether the deny is caused by the IP condition rather than a missing permission.
bash
aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::123456789012:user/my-user \
  --action-names s3:GetObject
  1. 1.Check NAT and egress infrastructure
  2. 2.If the caller runs in AWS, verify the current outbound IPs rather than relying on documentation from before the last networking change.
  3. 3.Update the policy or adopt a more stable access control model
  4. 4.IP conditions can work, but VPC endpoints, endpoint policies, or other network-aware controls may be more robust than brittle public IP matching.

Prevention

  • Revalidate IAM IP conditions after NAT, VPN, or endpoint changes
  • Keep policy IP ranges documented and version-controlled
  • Prefer more stable network-scoped controls where possible
  • Use IAM simulation before and after changing restrictive condition logic