How can I provide cross-account IAM authorization for API Gateway HTTP APIs?

Last updated: 2022-08-31

I want to activate AWS Identity and Access Management (IAM) authentication for cross-account access to my Amazon API Gateway HTTP API. How do I set that up?

Short description

For API Gateway REST APIs, you can use resource policies to provide IAM authentication for cross-accounts. However, this option isn't available for API Gateway HTTP APIs.

You can use the sts:AssumeRole API action to assume a role for the HTTP API account. The assumed role provides temporary security credentials that can be used to invoke the HTTP API in another account.

Resolution

Create the IAM temporary credentials

Note: If you receive errors when running AWS Command Line Interface (AWS CLI) commands, make sure that you’re using the most recent AWS CLI version.

1.    Create an IAM policy for Account A that hosts the HTTP API. This policy provides invoke permission for the HTTP API execute-api ARN.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "execute-api:Invoke",
            ],
            "Resource": [
                "arn:aws:execute-api:us-east-1:<AccountA-id>:<Api-id>/$default/*/*"
            ]
        }
    ]
}

2.    Create an IAM role in Account A, add "Trusted Entity Type" as "AWS Account", and enter the ID for Account B.

3.    Attach the IAM policy created in step 1 to the IAM role created in step 2.

4.    Create an IAM policy for Account B to allow the sts:AssumeRole API action:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "VisualEditor0",
      "Effect": "Allow",
      "Action": "sts:AssumeRole",
      "Resource": "arn:aws:iam::<AccountA-id>:role/<AssumedRoleName>"
    }
  ]
}

5.    Attach the IAM policy to the user in Account B.

6.    Run the AWS CLI command assume-role similar to the following:

$ aws sts assume-role --role-arn arn:aws:iam::<account-id>:role/<AssumedRoleName> --role-session-name role_session

Example output:

{
    "Credentials": {
        "AccessKeyId": "A1B2C3D4E5E6G7H8J9K0",
        "SecretAccessKey": "abcdefghijk123456789",
       
 "SessionToken": 
"11111111111122222222223333333333344444444455555566666667777777777778888888999999999aaaaaaaaaabbbbbbbbbcccccccc==",
        "Expiration": "2022-07-11T15:55:25+00:00"
    },
    "AssumedRoleUser": {
        "AssumedRoleId": "AAAAAAABBBBBBBBBBB:role_session",
        "Arn": "arn:aws:sts::<account-id>:assumed-role/<AssumedRoleName>/role_session"
    }
}

Check the credentials object for the AccessKeyId, SecretAccessKey, and SessionToken. These temporary credentials provided by the assumed role can be used to invoke the HTTP API.

Test the IAM authentication

Use the Postman app to send a request to your API resource using the method that you activated IAM authentication for.

Note: To manually authenticate requests that are sent to API Gateway using another tool or environment, use the Signature Version 4 (SigV4) signing process. For more information, see Signing AWS API requests.

1.    In Postman, choose the Authorization tab and do the following:
For Type, choose AWS Signature.
For AccessKey, SecretKey, and SessionToken, enter the values from the assume-role API call.

2.    For Enter request URL, enter your API's invoke URL similar to the following:

https://<Api-id>.execute-api.<region>.amazonaws.com/<stagename>/<resourcepath>

An authenticated request returns a 200 OK response code. An unauthorized request returns the message Missing Authentication Token and a 403 Forbidden response code.


Did this article help?


Do you need billing or technical support?