1

I'm having difficulty decrypting multiple environment variables in nodejs for an AWS lambda. I've looked at the code sample supplied in the console and the following two related questions:

Question 1, Question 2

I have been able to successfully decrypt a single environment variable through their code sample, however, when I try to apply a cleaner approach through the use of promises (methods outlined in the questions above), I get this error when testing the lambda function in the console:

TypeError: First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.

I was wondering if anyone has had this issue before and how I could go about resolving it?

Edit: I've added some samples from my code below

const AWS = require('aws-sdk');
const mysql = require('mysql');
let connection;

const encrypted = {
    username: process.env.username,
    password: process.env.password,
    database: process.env.database,
    host: process.env.host
};

let decrypted = {};

const encryptedEnvVars = [process.env.username, process.env.password, process.env.database, process.env.host ];


exports.handler = (event, context, callback) => {
    if (isEnvVarsDecrypted()) {
        processEvent(event, context);
    } else {  
        Promise.all(encryptedEnvVars.map(decryptKMS))
        .then(decryptEnvVars)
        .catch(console.log);
    }
};

function decryptKMS(key) {
    return new Promise((resolve, reject) => {
      const kms = new AWS.KMS()

      kms.decrypt({ CiphertextBlob: new Buffer(key, 'base64') }, (err, data) => {
        if(err) { reject(err); }
        else { resolve(data.Plaintext.toString('ascii')); }
      });
    });
  }

var decryptEnvVars = data =>  {
    return new Promise((resolve, reject) => {
        console.log(data);
        decrypted.username = data[0].Plaintext.toString('ascii');
        decrypted.password = data[1].Plaintext.toString('ascii');
        decrypted.database = data[2].Plaintext.toString('ascii');
        decrypted.host = data[3].Plaintext.toString('ascii');
        resolve();
    });
};

var isEnvVarsDecrypted = () => {
    return decrypted.username && decrypted.password && decrypted.database && decrypted.host;
}
2
  • Please post a sample of your breaking code. Can you inspect the type of the "first argument" and confirm that it is in fact one of the requested types (string, Buffer, etc...)? Commented Apr 5, 2018 at 4:55
  • I've added some of my sample code.. The argument passed in is "... new Buffer(..." Commented Apr 6, 2018 at 1:41

1 Answer 1

0

If key is null, then new Buffer(key, 'base64') will fail with the error you describe.

When I ran your code myself:

  • If any environment variable was missing, the error occurred
  • When all environment variables were declared, the error ceased

So, you should confirm that the environment variables you reference are actually defined.

A couple of other pointers:

  • Make sure you are always calling the lambda callback, regardless of success/failure; this is how you signal to the lambda environment that execution has ended.
  • After calling decryptEnvVars, you should call your processEvent function
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.