Intro
One of the authorization methods that AWS supports for the API Gateway endpoints is
IAM authorization.
Two things are required to use IAM auth:
- signed request using Signature Version 4
 - 
execute-apipermission set up for the client for invoked endpoint 
There are other authorization methods available like: Lambda authorizers or JWT authorizers you can read more about them
here.
In today's blog post, I will show you how to request a microservice that is protected by IAM auth.
The problem
For the blog post purpose, let's imagine we have two microservices: Microservice A and Microservice B.
Both of them were built using AWS lambda and API Gateway.
We own Microservice A, and some other team owns Microservice B.
We want to call Microservice B to get the response, it exposes the endpoint GET /items, and this endpoint is protected by IAM auth.
Solution
import os
from urllib.parse import urlparse
from logging import Logger
import requests
from aws_requests_auth.boto_utils import BotoAWSRequestsAuth
from requests.exceptions import RequestException
class MicroserviceBClientClientError(Exception):
    pass
class MicroserviceBClient:
    def __init__(self, base_url: str, logger: Logger) -> None:
        self._base_url = base_url
        self._logger = logger
    @property
    def auth(self) -> BotoAWSRequestsAuth:
        return BotoAWSRequestsAuth(
            aws_host=urlparse(self._base_url).hostname, aws_region=os.environ["AWS_REGION"], aws_service="execute-api"
        )
    def get_items(self) -> None:
        try:
            self._logger.info("Getting items from MicroserviceB!")
            response = requests.post(
                f"{self._base_url}/items", auth=self.auth
            )
            response.raise_for_status()
            self._logger.info(f"Successful request! Response = {response.json()}")
        except RequestException as error:
            self._logger.error(f"An error occurred during request to `MicroserviceB` service! Error = {error}")
            raise MicroserviceBClientClientError
The aws-requests-auth does most of the things for us.
We need to provide the hostname of the service we want to call, the AWS region,
and the service - in our case it is execute-api as we are working in a serverless lambda environment.
BotoAWSRequestsAuth generates the appropriate headers and adds them to the requests object.
All we need to do is to add it as a auth param to the requests method.
Summary
It is as simple as that 😉 I hope you enjoyed it.
There are other methods that you can use to make such a request.
The one I showed you is simple and easy.
I have tested it on production, it is working 😉.
    
Top comments (0)