vutbao
vutbao

Reputation: 133

How to use AWS KMS in AWS lambda

I've just started to work with AWS services, particularly AWS Lambda. Is there a way to use AWS KMS service from within Lambda code (Java). I'd like to use KMS to decrypt an encrypted externalized (read from a property) secret. My Lambda code is in java. Thanks in advance.

Upvotes: 6

Views: 12048

Answers (4)

Jha Nitesh
Jha Nitesh

Reputation: 388

I am going to use the JavaScript adk to access the KMS secret key. We need to create a lambda function assign policy[read, put, list, roate]. Use aws-adk to access the secret key.

Phase 1: Create a lambda function with appropriate policy. Sam policy template list for AWS secret key management(POLICY_TEMPLATE)

---
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: Lambda function to show demo

Parameters:
  OutputPrefix:
    Type: String
    Description: Prefix for variables exported from templates.

Globals:
  Function:
    Runtime: nodejs12.x
    Handler: index.handler
    Environment:
      Variables:
        STORE_TABLE_NAME:
          Fn::ImportValue: !Sub "${OutputPrefix}-StoreTable"

Resources:
  StoreItemInsertHandlerFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: StoreItemInsertHandler
      CodeUri: ../../../src/handlers/dist
      Policies:
        - AWSSecretsManagerGetSecretValuePolicy:
            SecretArn: "*"

Phase 2: Access the key using aws-sdk

import AWS from 'aws-sdk';
 const getSecretKey = async (key) => {
  const client = new AWS.SecretsManager({
    region: env('AWS_REGION'),
  });
  let result = '';
  try {
    result = await client.getSecretValue({ SecretId: key }).promise();
  } catch (e) {
    throw new Error(`Secret key [${key}] is not set.`);
  }
  return result;
};

Upvotes: 0

TantrixRobotBoy
TantrixRobotBoy

Reputation: 629

I have an implementation in Node.js 10.x (async/await fashion) it can be useful to you. First of all, as previously said, you must be sure to provide the Lambda function with a role with permissions to KMS service.

In Javascript:

const AWS = require('aws-sdk');
const fs  = require('fs');
const kms = new AWS.KMS();
const { promisify } = require('util');
const readFileAsync = promisify(fs.readFile);

const decrypt = async (kms) => {
  let secret = null;
  try {
    const secretPath = `./your.encrypted.file.json`;
    const encryptedSecret = await readFileAsync(secretPath);
    let params = {
      CiphertextBlob: encryptedSecret
    };

    const decrypted = await kms.decrypt(params).promise();
    secret = decrypted.Plaintext.toString('utf-8');
  } catch (exception) {
    console.error(exception);
    throw new Error(exception);
  }

  return JSON.parse(secret);
}

Upvotes: 1

rr3tt
rr3tt

Reputation: 756

In Python:

with open('encrypted_pem.txt', 'r') as encrypted_pem:
    pem_file = encrypted_pem.read()

kms = boto3.client('kms', region_name=REGION)
return kms.decrypt(CiphertextBlob=b64decode(pem_file))['Plaintext']

Taken from AWS Labs Chef cleanup source.

The README of that repo explains how to encrypt the PEM file in the first place using the AWS KMS CLI.

Upvotes: 5

Michael Goin
Michael Goin

Reputation: 416

Yes, it should work fine.

I recently ported a Node.js RESTful API over to Lambda and didn't have to change any KMS code.

You'll just need to make sure the role your Lambda function runs under has permissions to the key you setup through AWS to use with the encrypt/decrypt calls.

Upvotes: 4

Related Questions