Mutual Authentication in AWS Lambda

Typically an enterprise application interacts with internal and external systems to fulfill the business needs. Such integrations can happen at the UI layer or business layer or at the data layer in a synchronous/ asynchronous way.

Synchronous service integration with external systems happens over a web service, primarily with HTTP as the preferred protocol. Asynchronous integration happens with File transfer, primarily with SFTP (Secure File Transfer Protocol) as the preferred protocol.

Mutual Authentication (two-way SSL) is one of the standard techniques used to secure, encrypt and authenticate web services/ APIs. In 2-way SSL authentication, the client stores server certificates, and the server stores client certificates which are used to authenticate and validate each other’s identities. This is typically done on the server configuration.

“Nearly half of new apps at Amazon were deployed to AWS Lambda in 2020” – Andy Jessy at AWS:reInvent 2020

The announcement by Andy Jessy in AWS:reInvent confirms the rapid growth and interest in Serverless compute.

Implementing 2-way SSL authentication is a challenge in serverless since physical access to servers is not feasible. This blog provides a solution to establish a 2-way SSL communication between a serverless AWS Lambda function (the consumer service) and an external web service (the provider service).

Architecture:

AWS Lambda lets you run code without provisioning or managing servers. Customers pay only for the compute time that they consume. AWS manages the underlying compute needs for customers. AWS Lambda provides continuous scaling, subsecond metering, and consistent performance. AWS Lambda frees the customers from managing, securing, patching servers, and not worrying about spare or unused compute capacity. AWS Lambda is integrated with multiple AWS services like S3, ELB, API gateway, etc to help customers build secure loosely coupled microservices faster with less cost.

The architecture depicted below is a high-level architecture of a chat engine built with Amazon Lex. The focus in this architecture is the integration between AWS Lambda (the consumer service) and Appointment API (the provider service). A secure communication has to be established between these services for secure data transfer.

A Lambda function is built on Java 8 to call the Appointment API via Mulesoft API gateway. Java function authenticates with Mule via two-way SSL.

Tools and Technologies:

Here are the tools and technologies used to build the AWS Lambda function.

  • Java 8
  • AWS Lambda
  • Eclipse Neon
  • Maven 4.0
  • SoapUI 5.5.0 or above

Pre-requisite:

Install SoapUI to test the Appointment API. This is to ensure that the Appointment API that you are planning to call from the AWS Lambda function is accessible over the network. Obtain the Java Key Store (jks) file and password phrase from the Appointment API owner and validate it using SoaPUI.

1. Open SoapUI, Click Preferences on the main toolbar, or select File > Preferences.

2. In the SoapUI Preferences dialog, switch to the SSL Settings tab.

3. Specify the full path to your Keystore file and the Keystore password

4. Create a SOAP project, pass any additional credentials required in the header for authorization and invoke the API with a valid request. You should be able to successfully invoke the API and get results.

Build, Deploy and Test:

Here are the steps to build, deploy and run the Lambda function

Step 1 : Create a Maven Project

Create a new java Maven project in Eclipse for AWS Lambda function. Include AWS Lambda java core (required to run on AWS Lambda) and Apache HTTP client (to establish HTTP connection) libraries into the project. Sample POM.xml file is given below.

Step 2 : Create Lambda function in Java

Create a new AppointmentClient Java class with a handler method. AWS Lambda invokes this method at runtime to process the incoming request.

All the business logic for this function should go in this handler method. This java class gets configuration details from the environment variable and uses the JKS file and password phrase for 2-way authentication. The code is listed below.

Step 3 : Call API

Additional code is added in the myHandler method to accomplish the below.

Build a new request object with request parameters, headers and call the Appointment API. The response can be handled in the Lambda function or can be passed on to the calling interface. In our example, Lambda function sent back the response to AWS Lex for further processing. 

Step 4 : Add the .jks file

The Java Key Store file (AppointmentKey.jks) has to be bundled as part of the binary file so it is added to the resource folder

Step 5 : Test the functional locally

Test the Lambda function by running it locally on Eclipse (Run As -> Run Configurations -> Java Application). Set the environment variables before running the application.

The program should be able to establish the connection, call the API successfully, and display the response in the console.

Step 6 : Build the binary file

Once you successfully test the application, build the binary file (jar file) using maven build commands. To include all the dependent jars in the bundle, use the maven-assembly plugin with the “jar-with-dependencies” descriptor. Add below to pom.xml file.

Step 7 : Create a Lambda Function

Login to your AWS console and select Lambda services. In the Lambda console, click on “Create Function”

On the next page, create the lambda function with “Author from scratch”, providing function name and Java 8 as runtime. Create function by retaining other information with default values.

Step 8 : Upload the binary File

Upload the jar file to AWS Lambda. AWS Lambda code editor does not support Java 8 runtime so you will not be able to make any changes to the code on the Lambda console. For files smaller than 10 MB, you can directly upload from the console. For files larger than 10 MB, you have to first upload the jar file to AWS S3 and then to Lambda.

Step 9 : Add environment configuration

Add environment variables in AWS Lambda and save.

Step 10 : Configure Lambda runtime to invoke your handler method

You can tell the Lambda runtime which handler method to invoke by setting the handler parameter on your function’s configuration.

The following handler formats are supported in Java: package.Class::method

Add the following is the configuration that has to be done for this project and save the function. “com.buildsmartapps.chatbot.Appointment::myHandler” calls the Handler method defined in main java.

Accept the default value for the memory.

Note: You pay for the time that your function code runs multiplied by the amount of memory used. For your production function, test your function with different memory settings to see how it affects performance, and find the right balance between cost and speed for your use case.

Graphical user interface, text, application, email

Description automatically generated

Step 11 : Create a Test event for your Lambda Function

Once you define and configure your Lambda function, you can test the function directly from the Lambda console before integrating it with the consumer application.

To create a test, select “Configure test events” from the drop-down menu and click Test.

Create a new test using the “hello-world” template, provide the event name, and input the function. By default, the input content is in JSON format. Since our function accepts String as input, we are sending the email ad

Step 12 : Test your Lambda Function

Once the test event is created, run the test by selecting the appropriate test even.

The test event calls the Lambda function with the inputs given and displays the results in the console.

Conclusion:

JKS file has been bundled as part of the binary file for simplicity. However, for production use JKS file should be securely stored and made accessible to all Lambda functions. AWS Systems Manager Parameter store is a good option for this. We have used Java to implement Lambda function but the same can be implemented in other programming languages supported by AWS Lambda.

About the author

Madhusudan Gowdra

Software Engineer with 18 years of experience in designing and building internet-scale applications for large enterprises.

View all posts

Leave a Reply

Your email address will not be published. Required fields are marked *