AWS API Gateway MTLS authentication - with SmallStep & Pulumi
Tags: aws, pulumi, smallstep, mtls
Published: 2023-02-17 07:32:53

## Introduction

During the 2022 Christmas holidays, I got (re-)introduced to [**Smallstep**](https://smallstep.com/) and believe me it is a very promising tech in **PKI** space, It eases a good number of complex problems that occur if you were self managing the **PKI** all by yourself from scratch.

This blog post's main focus is going to be about - Securing the APIs deployed on AWS API gateway using **MTLS**.

The second focus is on how we can leverage [**Smallstep**](https://smallstep.com/) for the **PKI** part.

Third most important part being the infra provisioning using [**Pulumi**](https://www.pulumi.com/)

---

## Prerequisites

- basic knowledge of mtls & PKI.
- above average knowledge of AWS.
- must own a domain. buy it from AWS route 53, or buy it from somewhere else and configure in AWS route 53 using NS entries.
- AWS CLI installed.
- configure AWS credentials on local, profile based.
- some knowledge of [**Pulumi**](https://www.pulumi.com/) IAC.
- Pulumi CLI on local machine.
- account at [**Pulumi**](https://www.pulumi.com/)
- account at [**Smallstep**](https://smallstep.com/)
- step CLI on the developer machine. (OPTIONAL)

---

## Stack Diagram & Details

![The stack diagram](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f2d07tvgo3ab4trhx7z4.png)

**The following are the important stacks which are part of this POC:-**

1. **infra** stack (REQUIRED)
  - manages the Certificates required for the API gateway custom domains, using the AWS certificate Manager.
  - holds the s3 bucket that is required for the trust store certificate chain.

2. **functions** stack (REQUIRED)
  - manages the lambda function(s), presently a very basic single lambda function, and related permissions, etc.

3. **mtls-apis** stack (REQUIRED)
  - manages the API gateway related configuration, routes, integration, etc.
  - it refers the **infra** stack to pull certificate ARNs etc.
  - it refers the **infra** stack to pull s3 bucket & the ca.pem reference for the API gateway.
  - it refers the **functions** stack to pull lambda function ARNs etc.

4. **non-mtls-apis** stack (OPTIONAL)
  - manages the API gateway related configuration, routes, integration, etc.
  - it refers the infra stack to pull certificate ARNs etc.
  - it refers the functions stack to pull lambda function ARNs etc.

---

## Code details

The code repository for the successful POC is [here](https://github.com/krnbr/aws-api-gateway-mtls)

The folder structure is same as per the above stack diagram.

**Important points:-**

1. The Public DNS zone in AWS route 53 was created manually. That is not part of the stack provisioning.
2. The order of executing the stack is [infra](https://github.com/krnbr/aws-api-gateway-mtls/tree/main/mtls-infra), [functions](https://github.com/krnbr/aws-api-gateway-mtls/tree/main/functions) & then [mtls-apis](https://github.com/krnbr/aws-api-gateway-mtls/tree/main/mtls-apis)
3. Change the config in the pulumi yaml files in respective folders of all stack, for **AWS credentials**, **region**, and **DNS domain** related changes
4. The **ca.pem** in the [infra](https://github.com/krnbr/aws-api-gateway-mtls/tree/main/mtls-infra) stack needs to be replaced based on the own set of smallstep account. It is currently related to my own smallstep account.

---

### create the ca trust store file.

1. Make sure you have a SmallStep Account & you are logged in to same.
2. By default intermediate and root are created for your account. Click on view details by clicking three dots against the entries of root and intermediate certificates and copy both of certificates into a single file.
![List of certificates](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/821sspmy8aoqd61x7f82.png)

3. Place the **ca.pem** in the infra stack's folder.

---

### create client certificate

1. In the smallstep dashboard goto -> **Authorities** -> Click on the **authority** -> **create certificate using UI**, fill subject & expiration, as shown below:-
![Create Certificate](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8z4jgc5502mz9n1igx2f.png)
2. **Authorize**.
![Authorize](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e3bk1o4frc6lhyze64x9.png)
3. **Download key and certificate**, key is only downloadable at this time, later on it will not be available, keep it safe, otherwise the MTLS protected API endpoint might be compromised
![Download key and certificate](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x55xpwb2z0wx9djx51jr.png)

---

### Testing the API endpoint using POSTMAN

1. Configure the client cert and key in the certificates section in the settings of POSTMAN

2. If client cert not provided, the we will get -** Error: read ECONNRESET**

3. If the client cert and key combo is not correct we will get **403**

4. If all successful, the API will response back as below:-

the path is going to be https://domain.com/v1/ping

```
{
    "ping": "pong",
    "success": true,
    "timestamp": 1676617772241
}
```

---

Please feel free to reach out to me over Linkedin [here](https://www.linkedin.com/in/krnbr/) for further questions, doubts or suggestions.