I want to restrict access to AWS API calls to specific IP addresses. How can I use AWS Identity and Access Management (IAM) roles and the AWS Command Line Interface (AWS CLI) to limit access from API calls?

You can use the aws:SourceIp global condition key in the condition element of an IAM policy to restrict API calls from specific IP addresses, but this denies access to AWS services such as AWS CloudFormation that make calls on your behalf.

For example, assume that you have an AWS service role that allows AWS CloudFormation to call Amazon Elastic Compute Cloud (Amazon EC2) to stop an instance. The request is denied, because the target service (Amazon EC2) sees the IP address of the calling service (AWS CloudFormation) instead of the IP address of the originating user. You can't pass the originating IP address through a calling service to the target service for evaluation in an IAM policy.

Note: It's a best practice not to use the aws:SourceIp condition key.

Create an IAM role that has the same set of permissions attached to it as the IAM policy attached to the IAM user. The IAM user will have permissions only to assume the role sts:AssumeRole API if the request is coming from the specified IP address. This is because the aws:SourceIp restriction check performs when the user tries to assume the role. When the user assumes the IAM role, they acquire the permissions of the IAM policy attached to it. Because the IAM policy attached to the role does not use the aws:SourceIp condition key, access to AWS services is allowed.

Create this IAM policy, and then attach it to an IAM user who has programmatic access. This IAM policy allows the user to AssumeRole with role name "RoleA". The user won't need additional permissions. All other necessary permissions are acquired when the user successfully assumes the "RoleA".

Sample IAM User Policy

 {
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:role/RoleA"
}
}

Create the IAM "RoleA" to delegate permissions to the IAM user. Follow the instructions for Creating an IAM Role (Console). You can also use the AWS CLI or API.

Note: When using the console to create the role, modify the role's trust policy similar to this example for the "RoleA" trust policy. By using the CLI create-role or API CreateRole, you can pass the trust relationship policy document as a value in the --assume-role-policy document parameter.

IAM “RoleA” access policy: This policy has permissions to perform API calls on the resources in the account.

IAM “RoleA” Trust Policy: This sample trust policy allows the user to assume the role if the request is coming from the IP address range "103.15.250.0/24" or "12.148.72.0/23".

Note: The request must come from the specified IP address range "103.15.250.0/24" or "12.148.72.0/23", or the user won't be able to assume the role and make API calls.

Sample IAM Role Trust Policy 

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::account-id:user/<username>"
      },
      "Action": "sts:AssumeRole"
    },
    {
      "Effect": "Deny",
      "Principal": {
        "AWS": "arn:aws:iam::account-id:user/<username>"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "NotIpAddress": {
          "aws:SourceIp": [
            "103.15.250.0/24",
            "12.148.72.0/23"
          ]
        }
      }
    }
  ]
}

Note: This workaround will disrupt the CloudTrail logs. This is because actions aren't executed by the IAM user, but by the role the user assumed.


Did this page help you? Yes | No

Back to the AWS Support Knowledge Center

Need help? Visit the AWS Support Center

Published: 2018-08-20