How to implement mTLS on your workloads in AWS

Damiano Fisicaro
Storm Reply
Published in
7 min readMar 8, 2024

In the dynamic landscape of cloud computing, security is paramount, especially when it comes to communication between various components of your architecture. Transport Layer Security (TLS) plays a pivotal role in safeguarding data in transit, and mutual TLS (mTLS) further elevates the security posture by ensuring both parties authenticate each other. This article delves into the implementation of mTLS on your workloads within the Amazon Web Services (AWS) environment, providing a detailed exploration of three distinct scenarios.

Back-end To Back-end Communication with AWS Application Load Balancer

When working with AWS, a standard practice for facilitating back-end exposure to other back-ends entails the utilization of Application Load Balancers (ALBs).

As of the 26th of November 2023, Amazon introduced the new powerful capability of ALBs to handle mTLS completely independent of the underlying applications or servers, decoupling security and authorization layers from your applications, here is how to setup it up for your back-end to back-end communication.

Example Scenario

To start, create or modify your ALB HTTPS listener, and enable mutual authentication:

mTLS setting on ALB Listener

I recommend you choose to not allow expired certificates.

For the trust store, you can either create a new one in the same page, or re-use a previously created one. For the sake of this guide, I will create a new one, but first you will need to upload your certificate authority bundle in .pem format to s3 for a one-time read:

Certificate Authority Bundle Upload

Go to the trust store management page and create a new trust store:

The go back to the ALB creation page and select it for the listener:

Wait for the Application Load Balancer to be provisioned, create a CNAME or an A-Alias DNS entry using the native domain of the ALB as the value, then try reaching the Application Load Balancer with an HTTP call.
You will notice that it rejects the connection, unless you sign your TLS packets with the registered certificate’s private key.

Now you can transparently secure and authorize your Lambda, ECS, EKS, and many more types of workloads.

Front-end To Back-end Communication with AWS API Gateway

On another note, to expose back-end RESTful APIs to front-ends one of the best tools on the market is AWS API Gateway, which can streamline communication between several back-end services and multiple front-end clients.

AWS API Gateway supports several types of authorizations for RESTful APIs, such as AWS Cognito User Pools, AWS SIGv4, and AWS Lambda Authorizers, but one feature that often goes unnoticed, is that it also supports mTLS if you have an AWS API Gateway Custom Domain.

In the following section I will guide you through the steps needed to create a publicly exposed AWS API Gateway Custom Domain with mTLS enabled.

Sample AWS API Gateway App Architecture

I will assume you already have an API Definition in place already, if not, you can create a sample API Definition with a mock endpoint and come back to this afterwards.

As earlier, you will need your trust store in .pem format uploaded to s3.

Certificate Authority Bundle Upload

Go to Amazon Certificate Manager and request your TLS certificate, choose DNS Validation, leave the rest to default values.

Sample Certificate Request

Validate your certificate by inserting the required entries in your DNS service, such as AWS Route53.

Certificate Validated

After certificate validation, go to AWS API Gateway and create your Custom Domain:

Now go to the API Mappings tab and associate your API Stage

As the warning tells, if you don’t disable the default API endpoint, traffic will still be able to go through it, bypassing mTLS, so let’s disable it.

Finally register the CNAME entry for your custom domain using the API Gateway domain name as value:

API Gateway Custom Domain Details
Example DNS Record, I used AWS Route53

Now you can test the flow with curl using a key whose certificate is present in the trust store:

Internal To External Services Communication through AWS API Gateway as Proxy

Let’s assume now that you have your web application, container service, AWS Lambda Function, or whatever REST API client in your private network, and you need to interact with an external service on the internet which requires mTLS encryption. Do you need to modify your software to comply with this new requirement? Not necessarily!

In this section I will show you how you can configure an API Definition in AWS API Gateway to serve as a proxy towards an external service, so that you can use a different type of authorization and authentication in your internal network, and not lose the high level of security that mTLS grants on the public network.

In order to reach a private API you will need to have a VPC Endpoint for AWS API Gateway (service name com.amazonaws.<<region>>.execute-api) somewhere in your network, if you don’t have one already go create one and come back afterwards.

Sample Scenario

Now let’s create a private API in the console, remember to insert the VPC Endpoint id in the box and to create the resource policy allowing only your desired incoming traffic.

We will assume that you know how to setup a different type of authorization on AWS API Gateway, such as Cognito authorizer or Lambda authorizer. So we will use no authorization on the API for the sake of this guide.

To use a client certificate in AWS API Gateway we first need to create it. Let’s go to the Client Certificates section and click on “Generate certificate”.
Give it a description to better recognize this later on, and click again on “Generate certificate”.

After creating the certificate, open its details and send the certificate body to your counterpart to trust it.

Now we need to create a method to integrate with a third party service that needs us to sign our requests with mTLS, e.g.: https://certauth.idrix.fr/json/
This service will trust anyone with a mTLS certificate, and reject non-signed requests with a 403, or you can use the endpoint created in the previous section.

Testing the endpoint will give us a 403 Forbidden

Now let’s deploy this configuration to a new API Stage, we’ll call it “mtls”

Now we need to edit the stage details, and insert the client certificate in the additional settings

If we try now to test the method again, setting the certificate in the test screen, the service will respond successfully, and in our case, will give us the details of the signer certificate.

Now you are free to set your internal authorization method and API Gateway will automatically unwrap it, and insert mTLS for you in your API calls towards public services!

In conclusion, implementing mutual TLS (mTLS) within AWS for both back-end to back-end communication with Application Load Balancer and front-end to back-end communication with API Gateway enhances the security posture of your workloads. Leveraging the new capabilities of ALBs for mTLS and utilizing API Gateway’s support for mTLS with custom domains, this guide provides a comprehensive approach. Furthermore, by configuring API Gateway as a proxy for internal to external services, you can seamlessly integrate mTLS without modifying existing software, ensuring a robust security layer for interactions with external services.

--

--