Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS Lambda: How to store secret to external API?

I'm building a monitoring tool based on AWS Lambda. Given a set of metrics, the Lambdas should be able to send SMS using Twilio API. To be able to use the API, Twilio provide an account SID and an auth token.

How and where should I store these secrets?

I'm currently thinking to use AWS KMS but there might be other better solutions.

like image 325
JonathanGailliez Avatar asked Mar 31 '15 15:03

JonathanGailliez


People also ask

Where do you store Lambda secrets?

You can store secrets in Vault and access them from a Lambda function to access a database, for example. The Vault Agent for AWS helps you authenticate with Vault, retrieve the database credentials, and then perform the queries. You can also use the Vault AWS Lambda extension to manage connectivity to Vault.

Can Lambda function call external API?

Now that you have a safe way to store secrets and credentials with your Lambda functions, you can use that to call any public APIs that you can think of. You need to store the credentials safely using AWS KMS and use the public API SDKs in your functions.

Can AWS Lambda connect to external database?

Yes. AWS Lambda can connect to an AWS hosted databases such as RDS or DynamoDB. AWS Lambda can also connect to external databases which are public or grant network access. Dependent on the database you're using (or intending to use) there are some considerations you should address.


2 Answers

Here is what I've come up with. I'm using AWS KMS to encrypt my secrets into a file that I upload with the code to AWS Lambda. I then decrypt it when I need to use them.

Here are the steps to follow.

First create a KMS key. You can find documentation here: http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html

Then encrypt your secret and put the result into a file. This can be achieved from the CLI with:

aws kms encrypt --key-id some_key_id --plaintext "This is the scret you want to encrypt" --query CiphertextBlob --output text | base64 -D > ./encrypted-secret 

You then need to upload this file as part of the Lambda. You can decrypt and use the secret in the Lambda as follow.

var fs = require('fs'); var AWS = require('aws-sdk'); var kms = new AWS.KMS({region:'eu-west-1'});  var secretPath = './encrypted-secret'; var encryptedSecret = fs.readFileSync(secretPath);  var params = {   CiphertextBlob: encryptedSecret };  kms.decrypt(params, function(err, data) {   if (err) console.log(err, err.stack);   else {     var decryptedSecret = data['Plaintext'].toString();     console.log(decryptedSecret);   } }); 

I hope you'll find this useful.

like image 88
JonathanGailliez Avatar answered Sep 20 '22 07:09

JonathanGailliez


As of AWS Lambda support for NodeJS 4.3, the correct answer is to use Environment Variables to store sensitive information. This feature integrates with AWS KMS, so you can use your own master keys to encrypt the secrets if the default is not enough.

like image 24
Jamey Avatar answered Sep 23 '22 07:09

Jamey