top of page
Search

Password-less Authentication Using AWS Secrets Manager and Node.js

  • damiankozlowski
  • Nov 22, 2021
  • 5 min read

Security is one of those subjects that can go on forever and it seems like there is never a perfect outcome. Storing authentication strings is one such topic. Most of the applications must communicate with other systems in one way or another. For example, an API may have to retrieve data from a database or connect to an appliance to retrieve system statistics. The most common way to store such data is using environmental variables. This approach means that sensitive data is stored as a plain text inside a file (e.g. config.env) on a local storage.

In this blog I will show you an alternative way of storing secret strings. I will create a simple API that will authenticate with AudioCodes SBC using an authorisation string stored in Amazon AWS Secrets Manager.


Before you start, you will need:

  • Amazon Web Services Subscription with either full administrator rights or access to the Secret Manager and IAM services.

  • AudioCodes SBC or any other system which you want to authenticate with.

  • EC2 instance with Nodejs and Express - visit Node Base Project for deployment instructions.

  • Port TCP 80 opened from Node application to SBC.

  • Port TCP 3000 opened from a PC running Postman to Node application.

  • Postman application.

Out of Scope:

  • SBC deployment.

  • Encryption of HTTP traffic.

  • Authentication of the client requests.

Overview of the authentication process:

ree

  1. API Request to the Node application on /sbcStatus/:ip path. This leg of the request has no authentication, but the same principle can be applied.

  2. Node application retrieves the authorisation string from the AWS Secret Manager using IAM based authorisation.

  3. API Request is sent to the AudioCodes SBC /api/v1/status with Authorization header set to the value retrieved from the AWS SM.


Implementation


Install AWS Secret Manager Package.

At the root of your Node project run the below command:

npm install @aws-sdk/client-secrets-manager

You should now see new dependency in the package.json file.

ree

More information about client-secrets-manager here.


Create SBC User for API Authentication

Connect to the SBC using the graphical web interface and navigate to Administration -> Local Users menu and create a new user called api_user with Security Administrator privileges and status set to valid. Adjust security settings to meet your requirements.


ree

Because we are using HTTP for communication between Node Server and SBC, make sure that HTTP is allowed.

ree

Create AWS Secret

Login to AWS web console and from the Services dropdown select 'Secrets Manager' under 'Security, Identity, & Compliance' section. Once redirected to the Secrets page, click on 'Store a new secret'. Select 'Other type of secret' and paste your base64 encoded username and password with the prefix 'Basic'.


There are multiple ways of encoding credentials to base64:

  • Postman – simply enter your username and password in the Authorization section, then navigate to Headers and copy the value of the Authorization header.

  • OpenSSL – create txt file input.txt and type in your username and password separated by “:” e.g. 'api_user:tempUserforBlog!'. From the command line run the following:

openssl base64 -A < input.txt

ree

Click Next and give your secret a meaningful name and description.

ree

Click Next, Next and Store.

Open the newly create secret and copy the ARN address.

ree


Create and Attach IAM Role

To allow the EC2 instance (that is hosting the Node application) access to the authorisation secret, we will create a dedicated IAM role and attach to it.

In the AWS web console, navigate to the IAM section, select Roles from the menu and click Create Role. Select EC2 as the "use case" for the new role and click Next:Permissions.


ree

Once redirected to the Policies screen, click Create policy, Select JSON and paste the below object. Remember to replace ARN with the address of your secret.

{

"Version": "2012-10-17",

"Statement": [

{

"Effect": "Allow",

"Action": [

"secretsmanager:GetSecretValue",

"secretsmanager:DescribeSecret"

],

"Resource": [

" arn:aws:secretsmanager:eu-west-1:********:secret:sbcAuth-sTE7jD"

]

}

]

}


Make sure there are no errors showing in the editor.


ree

Click Next until you get to the Review Policy screen. Enter a meaningful name and description and click Create Policy.

Return to Create role screen, click refresh button to make sure the new policy shows on the list and select it, then click Next until you get to the Review screen.


ree

Give the role a meaningful name and description and click Create.

ree

Next, we need to attach the newly created IAM role to the EC2 instance.

In the AWS web console, navigate to the EC2 section and select the instance, then click Actions -> Security -> Modify IAM Role. Select the correct IAM Role and click save.


ree

Summary: We have created a new secret in the Secrets Manager store, we then create a new IAM role with the attached policy that grants access to the secret. Finally, we attached the new IAM role to the EC2 instance that is hosting the Node application.


Install AWS SKD Module

The base node project template does not include the necessary AWS SDK module. To install it, in the command line, navigate to the root folder of you project and run the below command.

npm install @aws-sdk/client-secrets-manager

The client secretes manager client should now be added as a dependency to the package.json file

ree

Create Environmental Variables

In the config.env file, add the below two lines.

AWS_SECRET_NAME=sbcAuth

AWS_SECRETE_REGION=eu-west-1


We will use these values when calling AWS SDK.

ree

Create the API Endpoint

We need to setup a new route for the API. In the blogRoutes.js file add the path for your new API e.g. router.route('/newTenant').get(sbcActionsController.sbcStatus);

ree

In the sbcActionsController.js add the sbcStatus function and import required modules.

ree

fetch – required for the API requests to the SBC.

SecretsManagerClient and GetSecretValueCommand – required for connecting to AWS Secrets Manager.


Writing API Logic

First, we make sure that client request contains a valid IPv4 address.

ree

In this section of the code, we create a getSecret async function which connects to the AWS Secrets Manager store and attempts to get the value of the secret. If successful, it returns the secret string, otherwise it returns an error message from AWS SM to the controller.

ree

Next, we define another async function called getSBCStatus which initiates an API request to the AudioCodes SBC API /api/v1/status using the node-fetch module. The secret string obtained from the secret store is used as an Authorization header for the request. Like the previous function, it either returns a response from the SBC or an error message (client or network).

ree

Once the necessary functions are declared, we are then calling the getSecret function and if successful, the value of the SecretString is stored inside the secret variable. The secret and region names are pulled from the environmental variables. If the function returns status "failure", an error response is sent to the client.

ree

Next, we call the getStatus function and pass the secret string as a parameter along with the IPv4 address of the SBC from the request "params" object. If the function returns status "failure", an error response is sent to the client.

ree

If both functions return status "success", a final response is sent to the client with data received from the SBC.


Testing the API

Make sure the Node application is running and listening on port 3000. To start the application run:

npm run dev

Run Postman request

Method: GET

FQDN: http://<NodeIPaddress>/sbcStatus/<IPv4 address>


A successful response should look as per the below example:

ree

You can clone the final project from my GitHub repository.








 
 
 

Comments


Post: Blog2_Post

Subscribe Form

Thanks for submitting!

COPYRIGHT © 2021 · ALL RIGHTS RESERVED

bottom of page