AWS Cloud Operations Blog

Configuring machine to machine Authentication with Amazon Cognito and Amazon API Gateway – Part 1

Introduction

When we think about modernization, we’re used to think about the process of breaking down a monolithic application, or moving to a microservices architecture. But let’s think for a moment on the business side. For example, think about the challenges and risks involved in moving information over phone calls or emails. We want to achieve the same outcome but in more reliable and secure manners, and if possible, automatically.

This is where the use of an API (Application Programming Interface) comes into the picture. An API is a definition for a way to how one application can communicate and interact with another application or service. In this context, achieving secure integration without human intervention, is a good example of modernizing your business processes.

In our 2-part blog series, we will show you how to secure your Amazon API Gateway with Amazon Cognito, in machine to machine (M2M) communication use cases. This will contribute towards a secure integration, and accelerate your business modernization journey.
On May 9th, 2024, we also announced tiered pricing for using Amazon Cognito to securing M2M communication.

Let’s start, Security Concepts

We start by understanding security terminology, and why we choose certain configurations. We want to ensure that our API is securely accessible only by legitimate machines and applications running on them. Furthermore, that applications communicating with our API must be entitled to consume or send information.

M2M authentication begins with credential-based authentication. In credential-based authentication, the user or entity presents their credentials (e.g., username and password, API key, access token, etc.) to the system or service they want to access. The system then verifies the provided credentials against the stored or known valid credentials for that user or entity, resulting in approval or rejection of the request.

To facilitate this, we need to inform Amazon Cognito who is the application that is going to authenticate against it. That is where Amazon Cognito app client applies. An Amazon Cognito app client is a configuration that is specific to a particular application. When an app client is created, Amazon Cognito assigns it a unique identifier known as the client ID. The app client defines how an application asks for tokens, and proves its identity to the Amazon Cognito authorization server.

When setting up an Amazon Cognito app client, we use client secret – a unique, sensitive value, serving as an additional security layer, that is used to authenticate the application when it requests access to the Amazon Cognito authorization server.

OAuth2.0 Concepts in M2M

OAuth 2.0 is a standard that allows users to share their private resources (like photos, files, etc.) with an application, without having to share their username and password. It does this by introducing different “grant types” that handle different use cases.

For reference, a grant type in the context of OAuth 2.0 is a specific way that an application can obtain an access token from an authorization server, acting as a passport for the application.

The different grant types defined in the OAuth 2.0 specification are:

  • Authorization Code Grant
  • Implicit Grant
  • Resource Owner Password Credentials Grant
  • Client Credentials Grant
  • Refresh Token Grant

Each grant type is designed to handle a different use case and has different security properties.

In our scenario, we are going to look at “client credentials grant”. This is useful when you have a backend application (like a service or a CLI tool) that needs to access other services, without human interaction involved. In this case, the application can authenticate itself directly with the Cognito authorization server using its own credentials, without needing any user interaction.

Also, in OAuth 2.0, applications are classified as either “confidential” or “public”. Confidential applications can safely store a “client secret”. These confidential applications must use the client credentials grant, as the client secret is crucial for proving the application’s identity.

For more information on Client Credentials Grant flow please refer to this blog.

AWS Services and Features involved

Amazon Cognito User Pools

By definition, an Amazon Cognito user pool is a user directory for web and mobile app authentication and authorization. In our context, this is where we are going to create the Amazon Cognito app client and enable the “client secret”.

Introduction to Amazon API Gateway

In the context of M2M authentication, the application makes requests to the Amazon API Gateway, which would then validate the access token provided by the application against Amazon Cognito to validate the request.

Cool, how do I mix everything?

Now we’ll show how the different authentication protocols and AWS services and features interact. The application starts an authentication and authorization process with Amazon Cognito. This begins by authenticating the application itself with the Amazon Cognito authorization server. To do this, the application will need to provide the Client ID and Client Secret associated with the Cognito App Client.

If the authentication is successful, the Amazon Cognito authorization server will issue an access token to the application. This access token represents the identity and permissions of your application, and it will be the key to accessing the protected resources. Your application should securely store this access token and include it in the headers of any requests it makes to the protected resources, typically in the “Authorization” header.

When your application attempts to access the protected resources, the resource server (such as your API) will validate the access token provided in the request. The resource server will check the token’s validity, the client’s identity, and the client’s permissions, to determine whether to grant access to the requested resource. If the access token is valid and the client has the necessary permissions, the resource server will grant access and may return the requested data, or perform the requested operation on behalf of the authenticated client.

In some cases, the access token may have a limited lifetime, so your application may need to renew the token when it expires. Depending on your implementation, you can either request a new access token using the client credentials grant flow or use a refresh token (if available) to obtain a new access token from the Amazon Cognito authorization server.

The example architecture depicted in Fig-1 demonstrates the workflow of securing an API endpoint using Amazon API Gateway and Amazon Cognito, underpinned by the OAuth 2.0 protocol.

 

Fig-1: Example architecture with API Gateway

Fig-1: Example architecture with API Gateway

 

What Next?

In our next blog in this 2-part series, we show you how to implement this solution in your own AWS Account.

 

About the authors:

Keerthana Ganesh

Keerthana Ganesh is a Security and Compliance Solutions Architect at AWS based in the UK, where she advises EMEA customers on building secure cloud architectures. In this role, she helps customers to build robust, resilient, and secure cloud environments that meet their evolving business and regulatory requirements.

Jorge Alvarez

Jorge Alvarez is a Solutions Architect Specialist in Migration and Modernization at AWS. In his role, he provides guidance to customers in their Migration and Modernization journey in EMEA. Prior to becoming a solutions architect at AWS, Jorge was leading teams in the cloud space, helping customers in their journey and modernization efforts.