Skip to content

Module 2 EXT 1 - API Gateway Authorization with AWS IAM

Time: 15 minutes

In this optional extension, you will update your serverless backend for your Wild Rydes application leveraging Amazon API Gateway and AWS Lambda to use request signing with IAM-based authorization as a more secure authentication option.

This section updates your Serverless backend built earlier using Amazon API Gateway and AWS Lambda to use IAM-based authorization. This extends your authorization capability to offer fine-grained access control authorizing differently per API operation and enhancing security via request signing. By enabling IAM-based authorization, you will use the same type of authentication, authorization, and request signing used by all AWS services and SDKs.

Request signing is a more secure implementation of API request authentication where each API request made is signed with a signature unique to the request itself. Hence, no static API keys or bearer tokens are directly sent to the backend service and any man-in-the-middle attacks would not be able to use such API keys or bearer tokens to impersonate a valid user with the backend resources. AWS APIs and SDKs use a request signing algorithm named Signature V4 (Sigv4) which is what you will enable your API to use in this module.

For production APIs, you should use either the token-based authorization OR request signing authorization via IAM demonstrated in this module, but not use both for the same API.

Module 2 architecture

Attach an IAM policy to your Cognito authenticated users' role

For you to be able to use request signing and IAM-based fine-grained access control, we'll first need to associate an IAM policy that provides permissions to invoke API operations for your API Gateway deployment. For further details, you can review controlling access to an API with IAM permissions documentation.

  1. Open the AWS IAM console.

  2. Choose Policies.

  3. Search for WildRydes to see the WildRydesAPI-StandardUserPolicy which was created by the Serverless Backed CloudFormation template.

    WildRydes API IAM Policy Search

  4. Click the WildRydesAPI-StandardUserPolicy policy name.

  5. Review the policy which was created by CloudFormation to authorize requests to your API Gateway deployment.

    WildRydesAPI Policy Details

    This policy allows access to invoke any method on the /ride path for any API stage of your API gateway backend. For more details about authoring IAM policies for API Gateway, visit the controlling access to an API with IAM permissions documentation.

  6. Choose Roles.

  7. Search for WildRydes to find the two roles which were created by Cognito Identity Pools when you created the Identity Pool in module one.

    Should you not be able to find the roles here, you can alternatively go to the Cognito Federated Identities console, find the correct identity pool, then click Edit Identity Pool in the top-right corner to see the roles listed. Each identity pool has both an Unauthenticated user role and an Authenticated user role.

  8. Select the Auth* role for your authenticated users.

    If the full name of the role is hidden from view due to column width, you can hover over the partially visible name of the role to see the full name of the role as a tool tip.

    IAM WildRydes Auth Role Selction

  9. Choose Attach policies.

  10. Search for WildRydes and check the box next to the policy named WildRydesAPI-StandardUserPolicy.

    Attach API Gateway IAM Policy

  11. Choose Attach policy.

  12. You should now see the WildRydesAPI-StandardUserPolicy policy associated with your Cognito IAM auth role.

    Permissions after adding IAM policy

Enable API Gateway authorization with AWS IAM

In addition to using JSON Web Tokens (JWTs) for authentication, API Gateway can leverage AWS request signing and parse the request signature to determine the requesting user. In this step, you'll update your authorization type to IAM for your API which will then use AWS's Identity and Access Management (IAM) capabilities to authorize requests via IAM policies.

In the Amazon API Gateway console, update the authorization type to AWS_IAM for the POST method on the /ride resource. Next, re-deploy the API to make your change take effect.

  1. Open the Amazon API Gateway console.

  2. Choose the API named WildRydes.

  3. Browse to Resources while within your Wild Rydes API in the API Gateway console.

  4. Select the POST method under the /ride resource path.

  5. Choose Method Request

    Method Request Selection

  6. Choose the pencil icon next to Authorization to edit the setting.

  7. Select AWS_IAM from the list of authorization options presented.

API Gateway Authorizer Selection

  1. Save your selection by clicking the checkmark icon next to the drop down.

API Gateway Authorizer Confirmation

  1. Next, choose the Actions button at the top of the resources list.

  2. Choose Deploy API from the list of options presented.

  3. For deployment stage, select prod then click Deploy.

  4. You've now successfully deployed your new authentication integration to your API's production environment.

Configure your app to authenticate API requests

Now that you've deployed the new authorizer configuration to production, all API requests must be authenticated to be processed.

  1. Return to your Wild Rydes app, sign in at /signin if necessary, and attempt to request a ride.

  2. You should receive an Error finding unicorn. If you open the developer console, you will see that we received a HTTP 403 error, which means it was an forbidden request.

    If at first your requests go through without any errors, try requesting a ride again in 30-60 seconds to allow time for the API Gateway changes to fully propagate.

  3. Go back to Cloud9 and open the /website/src/pages/MainApp.js files.

  4. Update your current getData method to the following method, which removes the Authorization header and adds debugging information to show us the request signature as requests are sent.

    The default behavior of the AWS Amplify library is the sign all requests with SigV4 signing when no authorization header is specified, so this will automatically sign all requests using this algorithm without extra development effort.

  5. Save your changes after making this update.

    async getData(pin) {
        Amplify.Logger.LOG_LEVEL = 'DEBUG';
        const apiRequest = {
            body: {
            PickupLocation: {
                Longitude: pin.longitude,
                Latitude: pin.latitude
            }
            },
            headers: {
            'Content-Type': 'application/json'
            }
        };
        console.log('API Request:', apiRequest);
        return await API.post(apiName, apiPath, apiRequest);
    }

Allow the application to refresh, sign-in again, and request a ride.

The unicorn ride request should be fulfilled as before now. To see the full request headers which were sent, look at the developer console for an message which includes the API Request details, including the full signature and headers of the request.

This message starts with POST /prod/ride then shows the headers of the request made.

You may notice that there were both x-amz-date and x-amz-security-token headers sent among other headers. These two headers are part of the overall request signature, along with the Authorization header.

Back to Module 2