title: How to use encrypted environment variables in AWS Lambda?
body: <p>I am trying to use encrypted environment variables in an AWS Lambda function running in Node.js 4.3, but the code hangs when trying to decrypt the variables. I don't get any error messages, it just times out. Here is what I have tried:</p>
  
  <p>I created the encryption key in the same region as the Lambda, and ensured that the role the Lambda runs as has access to the key. (I've even tried giving the role full control of the key.)</p>
  
  <p>When creating the Lambda, I enable encryption helpers, select my encryption key, and encrypt the environment variable:</p>
  
  <p><a href="https://i.stack.imgur.com/rtoWz.png" rel="noreferrer"><img src="https://i.stack.imgur.com/rtoWz.png" alt="enter image description here"></a></p>
  
  <p>Next I click the "Code" button which gives me javascript code that's supposed to handle the decryption at runtime. Here is the code--the only change I have made is to add <code>console.log</code> statements and I added a try/catch:</p>
  
  <pre><code>"use strict";
  
  const AWS = require('aws-sdk');
  
  const encrypted = process.env['DBPASS'];
  let decrypted;
  
  
  function processEvent(event, context, callback) {
      console.log("Decrypted: " + decrypted);
      callback();
  }
  
  exports.handler = (event, context, callback) =&gt; {
      if (decrypted) {
          console.log('data is already decrypted');
          processEvent(event, context, callback);
      } else {
          console.log('data is NOT already decrypted: ' + encrypted);
          // Decrypt code should run once and variables stored outside of the function
          // handler so that these are decrypted once per container
          const kms = new AWS.KMS();
          console.log('got kms object');
          try {
          var myblob = new Buffer(encrypted, 'base64');
          console.log('got blob');
          kms.decrypt({ CiphertextBlob: myblob }, (err, data) =&gt; {
              console.log('inside decrypt callback');
              if (err) {
                  console.log('Decrypt error:', err);
                  return callback(err);
              }
              console.log('try to get plaintext');
              decrypted = data.Plaintext.toString('ascii');
              console.log('decrypted: ' + decrypted);
              processEvent(event, context, callback);
          });
          }
          catch(e) {
              console.log("exception: " + e);
              callback('error!');
          }
      }
  };
  </code></pre>
  
  <p>Here is what I get when I run the function:</p>
  
  <pre><code>data is NOT already decrypted: AQECAH.....
  got kms object
  got blob
  END RequestId: 9b7af.....
  Task timed out after 30.00 seconds
  </code></pre>
  
  <p>When I run the function, it times out. I see that it prints all log statements up to "got blob" then it just stops. No error message other than timed out. I've tried increasing timeout and memory for the Lambda but it just makes it wait longer before timing out.</p>
  
  <p><strong>How is decryption supposed to work when I never tell the app what decryption key to use?</strong> The <a href="http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/KMS.html#decrypt-property" rel="noreferrer">documentation for <code>decrypt</code></a> does not mention any way to tell it what decryption key to use. And I am not getting any error messages that would tell me it doesn't know what key to use or anything.</p>
  
  <p>I've tried going through <a href="http://docs.aws.amazon.com/lambda/latest/dg/tutorial-env_console.html" rel="noreferrer">this tutorial</a> but it just tells me to do the same thing I've already done. I've also read all of the <a href="http://docs.aws.amazon.com/lambda/latest/dg/env_variables.html" rel="noreferrer">environment variables documentation</a> but it says that what I'm doing should just work.</p>