How to Securely Retrieve Secret Data in Lambda

wqwq
2 min readJun 15, 2024

--

Introduction

We manage AWS ECS fargate, Lambda, and so on. To ensure robust management, it is imperative to handle all resources securely. Let’s say ECS Fargate can get secrets easily and securely from the Parameter Store like below. However, Lambda can’t do the same thing securely. This means that we can see the value itself in the AWS Console. In this article, I will introduce methods to securely define and manage secret data in Lambda.

secrets = [
{
name = "SOME_SECRET",
valueFrom = "arn:aws:ssm:somewhere:1111111:parameter/SOME_SSM"
},
]

Use Environment & KMS

When we implement the lambda environment by Terraform, the code will look like this: Of course, we can see secret data from the AWS Console. To avoid this situation, we usually use encryption by AWS KMS. Therefore, it is safe to view it in the AWS Console.


// lambda envrionment
data "aws_secretsmanager_secret" "some_secret" {
arn = "arn:aws:secretsmanager:somewhere:111111111:secret:some-secret"
}

data "aws_secretsmanager_secret_version" "some_secret" {
secret_id = data.aws_secretsmanager_secret.some_secret.id
}

// lambda envrionment
environment_variables = {
ENV = "hoge"
USER = "${jsondecode(data.aws_secretsmanager_secret_version.some_secret.secret_string)["username"]}"
}

Use SDK

We can also get secrets from the Parameter Store or Secrets Manager directly using the AWS SDK. A sample implementation obtained from the Secrets Manager is shown below. So we define a secret arn in the environment and then retrieve the data in this scenario. However, the drawback of this option is that it can sometimes be costly. For instance, we call that Lambda many times, it costs us much and gets unnecessary latency as well.

sess := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
}))
svc := secretsmanager.New(sess)

result, err := svc.GetSecretValueWithContext(
context.Background(),
&secretsmanager.GetSecretValueInput{
SecretId: aws.String(secretID),
VersionStage: aws.String("AWSCURRENT"),
},
)
if err != nil {
return err
}

var secretData secret // can get secret
if err := json.Unmarshal([]byte(*result.SecretString), &secretData); err != nil {
return err
}

Use Secrets Lambda extension

We can use a Secrets Lambda extension to avoid calling Lambda functions many times. The SDK solution problem is cost and latency.

To alleviate the cost and latency issues associated with frequent SDK calls, AWS provides a Secrets Lambda extension. This extension allows Lambda functions to securely and efficiently retrieve secrets by leveraging a local cache, thereby reducing the number of calls to AWS Secret Manager or Parameter Store.

In an article by https://aws.amazon.com/blogs/compute/using-the-aws-parameter-and-secrets-lambda-extension-to-cache-parameters-and-secrets/

--

--