How can I use IAM roles to restrict API calls from specific IP addresses to the AWS Management Console?

Last updated: 2019-10-21

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

Short Description

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. However, 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.

Resolution

Create an IAM role that has the same set of permissions attached to it as the IAM policy that's 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 of the aws:SourceIp restriction check that's performed when the user tries to assume the role. When the user assumes the IAM role, they acquire the permissions of the IAM policy that's attached to it. Because the IAM policy attached to the role doesn't use the aws:SourceIp condition key, access to AWS services is allowed.

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

Note: Replace Bob with your IAM role name and EXAMPLEIAMACCOUNTID with your account ID.

Sample IAM User Policy

{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::EXAMPLEIAMACCOUNTID:role/Bob"
}
}

Create the IAM role Bob to delegate permissions to the IAM user. Follow the instructions for Creating an IAM Role (Console). You can also use the AWS Command Line Interface (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 Bob 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 Bob role policy: This policy has permissions to perform API calls on the resources in the account.

IAM Bob 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 IAM user won't be able to assume the role and make API calls.

Sample IAM Role Trust Policy

Note: Replace EXAMPLEIAMUSERNAME with your IAM user name.

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

Note: This workaround disrupts the CloudTrail logs because actions are executed by the IAM role that the user assumed, not the IAM user. The assumeRole API call performed by the IAM user is logged in CloudTrail logs under the IAM user. Any additional API calls performed by the IAM role are logged in CloudTrail logs under the role name.


Did this article help you?

Anything we could improve?


Need more help?