---
title: How to Encrypt Serverless Environment Variable Secrets with KMS | Metal Toad
description: Your serverless function has a secret... maybe it's a password for a remote API, a private key, or signing certificate.
---

[Blog ](https://www.metaltoad.com/blog)

# [How to Encrypt Serverless Environment Variable Secrets with KMS | Metal Toad](https://www.metaltoad.com/blog/how-to-encrypt-serverless-environment-variable-secrets-with-kms)

 Written by [Metal Toad Staff](https://www.metaltoad.com/blog/author/metal-toad-staff) | Jun 1, 2018 12:00:00 AM

 Filed under:

- [Amazon Web Services (AWS)](https://www.metaltoad.com/help/amazon-web-services)
- [Security](https://www.metaltoad.com/help/security)
- [AWS Lambda](https://www.metaltoad.com/help/aws-lambda)
- [AWS IAM](https://www.metaltoad.com/help/aws-iam)

Your [serverless](https://www.metaltoad.com/blog/what-serverless) function has a secret... maybe it's a password for a remote API, a private key, or signing certificate. These secrets have to be stored *somewhere*, and in the old days that usually meant just a plaintext config file on your server. Sure, you could encrypt it, but then you have to put the key on the server, and you haven't gained anything except a bit of obfuscation. Or you could use more complex schemes, like Hiera-Eyaml, which is a small improvement, but you've really just moved the threat to a different part of your infrastructure.

Using AWS KMS (Key Management Service) with [AWS Lambdas](https://www.metaltoad.com/blog/what-aws-lambda) offers a significant reduction in attack surface area. You get HSM-like functionality, without the high cost (starting at $1/month). In this model, there are only three ways the secret can be accessed:

1. From inside the container running the Lambda function code
2. By an IAM user with admin rights - and you protected these accounts with two-factor auth, right?
3. Amazon screws up catastrophically

I believe (3) is important to acknowledge here - the risk doesn't go away, but is outsourced to an extremely mature, security-focused organization with a stellar track record and a lot at stake.

Here's a short example using the [Serverless framework](https://serverless.com/), and Node.js. Many other language and framework combinations are possible.

Here are the steps. Refer to the quickstart docs for [Serverless](https://serverless.com/framework/docs/providers/aws/guide/quick-start/), [KMS](https://docs.aws.amazon.com/kms/latest/developerguide/getting-started.html), and [aws-cli](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) if any of these are unfamiliar.

1. Create a KMS key in the AWS console, and make a note of its ARN.
2. Generate some ciphertext with the following CLI command:  
   `aws kms encrypt --key-id 'arn:aws:kms...' --plaintext 'secret'`
3. Add the ciphertext as an environment variable
4. Add the ARN to the `awsKmsKeyArn` property in your `serverless.yml` file
5. Update your code with `kms.decrypt()` to access the secret

### index.js

```
'use strict';
const aws = require('aws-sdk');
var kms = new aws.KMS();
 
exports.hello = (event, context, callback) => {
  kms.decrypt({CiphertextBlob:
    new Buffer(process.env.password, 'base64')},
    (err, data) => {
 
    var password = data.Plaintext.toString('ascii');
 
    /*
     * Do stuff with plaintext password
     */
 
    callback(null, {
      statusCode: 200,
      body: JSON.stringify("hello"),
      headers: {
          'Content-Type': 'application/json',
      },
    });
 
  });
};
```

### serverless.yml

```
service: example

provider:
  name: aws
  region: us-west-2

functions:
  hello:
    handler: index.hello
    events:
      - http:
          path: hello
          method: get
    awsKmsKeyArn: 'arn:aws:kms:us-west-2:123456789:key/80abc534-be62-992a-7ba1-e3a44d4271ac'
    environment:
      # password value below is KMS ciphertext
      password: 'AQICAHiNrBUmBQhi496ozpFzP9BrHUALq+NAyE7Xsz6gRsiz0AGsJnI1cyYl57qLnxn1FDSkAAAAbTBrBgkqhkiG9w0BBwagXjBcAgEAMFcGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQM8TW0l6r7UEi1soz9AgEQgCp4Vy6sWq1W7SXXmeaz3jRL/X5ax4E2Uw3N0KGztPwv9kGK8O2Nk56tM4Q='
    runtime: nodejs6.10
```

[View full post](https://www.metaltoad.com/blog/how-to-encrypt-serverless-environment-variable-secrets-with-kms)

```json
{
  "@context" : "http://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Metal Toad Staff"
  },
  "dateModified" : "2023-12-06T23:22:14.602Z",
  "datePublished" : "2018-06-01T00:00:00Z",
  "headline" : "Your Serverless Function has a Secret",
  "image" : {
    "@type" : "ImageObject",
    "height" : 500,
    "url" : "https://6104926.fs1.hubspotusercontent-na1.net/hubfs/6104926/Imported_Blog_Media/shutterstock_654506083.jpg",
    "width" : 870
  },
  "mainEntityOfPage" : "https://www.metaltoad.com/blog/how-to-encrypt-serverless-environment-variable-secrets-with-kms",
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "height" : 60.0,
      "url" : "https://6104926.fs1.hubspotusercontent-na1.net/hubfs/6104926/social-suggested-images/6104926.fs1.hubspotusercontent-na1.nethub6104926hubfsMetal_Toad_Logo_orange_horizontal-50-1.jpg",
      "width" : 240.00002
    },
    "name" : "Blog"
  }
}
```