Python implementation for utilizing IAM roles to access AWS API Gateway

Feedback


Solution 1:

Utilizing the aws-requests-auth tool, you can create a signature for your API Gateway request, specifying “execute-api” as the designated service.

import requests
from aws_requests_auth.aws_auth import AWSRequestsAuth
auth = AWSRequestsAuth(aws_access_key='YOURKEY',
                       aws_secret_access_key='YOURSECRET',
                       aws_host='restapiid.execute-api.us-east-1.amazonaws.com',
                       aws_region='us-east-1',
                       aws_service='execute-api')
headers = {'params': 'ABC'}
response = requests.get('https://restapiid.execute-api.us-east-1.amazonaws.com/stage/resource_path',
                        auth=auth, headers=headers)


Solution 2:


Expanding on Ka Hou Ieong’s answer, there was an additional issue that caused confusion for me. Despite using

aws-requests-auth==0.3.0

, switching to

requests.get(url, auth=auth)

did not resolve the problem of receiving

403

.

In summary, my URL contained a querystring. It appears that

aws-requests-auth

lacks the ability to ensure the querystring parameters are both sorted in ascending order and

%

-encoded.

After ordering my querystring and encoding it with

%

, I was able to obtain

200

, which was not possible previously when my

url

querystring was not in order.

Upon enabling logging for API Gateway, I received the following output.

In [46]: resp = requests.get(url, auth=auth)
In [47]: resp.text
Out[47]: u'{"message":"The request signature we calculated
 does not match the signature you provided. Check your AWS Secret Access Key
 and signing method. Consult the service documentation for details.... 

I have added

...

above by inserting new lines and truncating the original text.

As stated in the Signature Version 4 documentation for Amazon’s Canonical Request.

To form the standard query string, follow these instructions:

Arrange the names of the parameters in ascending order based on the character code point. To explain further, a parameter name that starts with a lowercase letter b comes after a parameter name that commences with an uppercase letter F.

Encode both the parameter name and value using URI encoding, following the subsequent guidelines.

Avoid URI-encoding the unreserved characters as defined in RFC 3986, which includes A-Z, a-z, 0-9, hyphen (-), underscore (_), period (.), and tilde (~).

Encode all characters, except alphanumeric characters, with %XY where X and Y are hexadecimal characters ranging from 0 to 9 and uppercase A to F. To illustrate, the space character is encoded as %20, instead of using the ‘+’ symbol which is used in some encoding techniques. Additionally, extended UTF-8 characters should be encoded in the format %XY%ZA%BC.

The querystring that follows a standard format is utilized for creating both

Authorization Signature

and

Signature Version 4

signatures by AWS. It is important to note that altering

aws-requests-auth

and

Auth

will not affect your

url

; you must make the necessary changes yourself.


Solution 3:


To utilize the IAM role for making a phone call, it is recommended to make use of

BotoAWSRequestsAuth

from the aws-requests-auth library.

import requests
from aws_requests_auth.boto_utils import BotoAWSRequestsAuth
auth = BotoAWSRequestsAuth(
    aws_host="API_ID.execute-api.us-east-1.amazonaws.com",
    aws_region="us-east-1",
    aws_service="execute-api"
)
response = requests.get("https://API_ID.execute-api.us-east-1.amazonaws.com/STAGE/RESOURCE", auth=auth)

The key and secret necessary for retrieval will be obtained from the AWS metadata service through botocore, eliminating the need for you to provide them manually.

Credit goes to Ka Hou Leong for recommending the aws-requests-auth library.

Frequently Asked Questions