How To Effectively Manage Sensitive Information in AWS Lambda: Powertools Parameters
Tags: dotnet, aws, lambda
Published: 2024-02-16 02:04:22

When building Lambda Functions, we often need to store configuration and sensitive information.

AWS Provides different services like Parameter Store, Secrets Manager, etc., to store sensitive information.

The AWS Lambda Powertools library makes it easy to work with these different services and retrieve one of their multiple parameter values.

{% embed https://www.youtube.com/watch?v=3Mdbaf4ox78&ab_channel=RahulNath %}

In this blog post, let’s learn how to get started using the Lambda Powertools Parameters NuGet package, use it when building Lambda Functions, and connect quickly to Parameter Store and Secrets Manager using the library package.

## AWS Powertools Parameters Package

Powertools Parameters utility is available as a NuGet package. To get started using it from the application, install [AWS.Lambda.Powertools.Parameters](https://www.nuget.org/packages?q=AWS.Lambda.Powertools.Parameters) NuGet package.

Once installed, we can use it to integrate with the various AWS Services to manage secrets and configuration.

## AWS Lambda & Parameters Store

AWS Parameter Store is a centralized, secure store for your application configuration.

Parameter Store, a part of AWS Systems Manager, provides secure storage for application configuration and secret data. As parameter values, you can store passwords, database strings, Amazon Machine Image (AMI) IDs, API Keys, etc.

{% embed https://www.rahulpnath.com/blog/aws-parameter-store/ %}

Parameter Store makes decoupling your code from configuration easy and acts as version control for your configuration data.

### Retrieving Secrets From Parameter Store

You can either retrieve one or multiple secrets at a time from the Parameter Store.

The Powertools Parameter utility provides the `ParametersManager.SsmProvider` utility class to interact with the Parameter Store.

```csharp
    var value = await ParametersManager.SsmProvider.GetAsync("/Value1");
    var multiple = await ParametersManager.SsmProvider
         .GetMultipleAsync("/weather-app/");
```

Use `GetAsync` method to retrieve one value and the `GetMultipleAsync` method to return multiple values given a key prefix.

In the example about, `value` represents the value of the key '*/Value*', and multiple has all the parameter key values that start with '*/weather-app*'.

### Lambda Permissions for Parameter Store

For the Lambda Function to retrieve values from the Parameter Store, it needs appropriate permissions.

Let's update the IAM permission of our Lambda function and add the below policy to give it permission to retrieve the required keys.

To retrieve one parameter, we need the `ssm:GetParameter` and for multiple `ssm:GetParametersByPath` Action permissions. The below policy provides all actions starting with 'ssm:GetParameter', which is denoted by the '\*' at the end.

```json
{
  "PolicyName": "OrderApiParametersStorePolicy",
  "PolicyDocument": {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Action": "ssm:GetParameter*",
        "Resource": [
          "arn:aws:ssm:ap-southeast-2:189107071895:parameter/Value1",
          "arn:aws:ssm:ap-southeast-2:189107071895:parameter/weather-app/*"
        ]
      }
    ]
  }
}
```

### Transforming Parameter Store Values

The Parameters utility supports transforming of values stored in Parameter Store.

For e.g., the parameter '/my-configuration' is stored as JSON in the Parameter Store.

When retrieving the value, we can use the `WithTransformation` and specify to use JSON Transformation. This allows us to automatically deserialize the configuration to a custom type that we specify (in this case `MyConfiguration`)

```csharp
var myConfiguration = await ParametersManager.SsmProvider.WithTransformation(Transformation.Json)
     .GetAsync<MyConfiguration>("/my-configuration");
...
public class MyConfiguration
{
    public string Secret { get; set; }
    public string Url { get; set; }
}
```

The utility also supports [Base64 transformation](https://docs.powertools.aws.dev/lambda/dotnet/utilities/parameters/#transform-values).

## AWS Lambda & Secrets Manager

AWS Secrets Manager provides a centralized store to manage your application secrets.

Secrets can be information like passwords, credentials, connection strings, API keys, etc. Secrets Manager helps you protect access to your IT resources and data by enabling you to rotate and manage access to your secrets.

{% embed https://www.rahulpnath.com/blog/aws-secrets-manager/ %}

### Retrieving Secrets From Secrets Manager

The Parameters utility provides `ParametersManager.SecretsProvider` to retrieve secrets from the Secrets Manager.

Secrets Manager currently supports only retrieving one secret value at a time. Trying to use the `GetMultipleAsync` method will throw an exception at runtime.

```csharp
var secret1 = await ParametersManager.SecretsProvider
       .GetAsync("weather-app/secret1");
```

### Lambda Permissions for Secrets Manager

The Lambda Function requires `secretsmanager:GetSecretValue` permission on the Secret Values to return them successfully.

Let's update the IAM Permission also to include the required permission to retrieve the Secret from Secrets Manager, as shown below.

```json
{
  "PolicyName": "OrderApiSecretsStorePolicy",
  "PolicyDocument": {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Action": "secretsmanager:GetSecretValue",
        "Resource": [
          "arn:aws:secretsmanager:ap-southeast-2:189107071895:secret:weather-app/secret1*"
        ]
      }
    ]
  }
}
```

## DynamoDB Provider

The Parameters utility also supports using the DynamoDB table as a source of Parameter key values.

You can use the `ParametersManager.DynamoDBProvider` to interact with the configurated DynamoDB table to return key-value pair.

I'll leave that exercise to you to explore and use. You can read more about it [here in the documentation](https://docs.powertools.aws.dev/lambda/dotnet/utilities/parameters/#dynamodb-provider)key-value.