Securing Your Secret Using AWS Systems Manager (Parameter Store)
Tags: aws, secrets, dotnet, security
Published: 2022-10-23 09:15:49

Hello, everyone! I hope you are doing fine. I'm going to share how to secure your secret using AWS Systems Manager (Parameter Store).

I break this post into two parts.

1. Setup IAM User for retrieving secret from Parameter Store
2. Retrieving code

## Set up IAM User

We will set up IAM User. We use this user to get our secret from Parameter Store.

1. Go to IAM Pages -> Access Management -> Users -> Add users. Please check the Access key - Programmatic access and fill the user name. You can use `parameter-store-user` as the name. After that, click `Next`.

    ![Name + Programatic](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gzpb084mzq5gg7zq4r54.png)

2. In the step 2, click `Attach existing policies directly` and after that click `Create Policy`. We will use custom policy.

    ![Policy Create](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/66lv3pt4vr9w3s4qqt9x.png)

    Note: If you want to learn more how to set up the policy, please navigate [here](https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-paramstore-access.html)

3. You just need set up the policy like this image. Select the Service is `System Manager`, Access Level are `Read` -> `GetParameter` and `GetParameters`, and Resources is `All Resources` (usually, you will need to define specific parameters or use regex to give access to particular resources only).

    ![Policy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dn6pau0sn6h39z6p7s9u.png)

4. Give the policy name `ReadParameterStore`.

    ![Name](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/20ud8j3kznobfiei3dob.png)

5. Select our previously created policy.

    ![Policy Set](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fv9k8s8j9ppbjlt5m8er.png)

6. Save your credentials. We will use that later.

    ![Created](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/96v0wjpvp7vyt0y06h9i.png)

## Adding Dummy Values in Parameter Store

Navigate to AWS Systems Manager > Parameter Store. After that create a parameter. On my side, I created `/app/db` with type `SecureString` and use any values.

![Create Parameter](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xipzhbdo5j1ikdpkvx2h.png)



## Set up Project

Time to code. We will start to use the small projects to get our secret using AWS SDK. In this case, I will use .NET and AWS SDK for .NET. Let's go!

1. Prepare `.gitignore`. Command: `dotnet new gitignore`
2. Prepare the solution file. Command: `dotnet new sln`
3. Prepare the project using template. Command: `dotnet new webapi -o ParameterStore`
4. Add the project to solution. Command: `dotnet sln add ParameterStore`
5. Install the AWS SDK, especially for Systems Manager. Command: `dotnet add ParameterStore package Amazon.Extensions.Configuration.SystemsManager --version 4.0.0`.

If you want to visit my repository, please navigate to the link below.

{% github bervProject/ParamStore %}

OK, let's continue to code.

1. Update the `Program.cs` file. You need to add these lines.

    ```csharp
    var builder = WebApplication.CreateBuilder(args);
    
    // Add services to the container.

    // BEGIN: ADD THESE LINES
    builder.WebHost.ConfigureAppConfiguration(b => {
        b.AddSystemsManager("/app");
    });
    
    builder.Services.AddAWSService<IAmazonSimpleSystemsManagement>();
    // END: ADD THESE LINES
    
    builder.Services.AddControllers();
    ```

2. Add `ParamStoreController.cs` in `Controllers` directory.

    ```csharp
    using Amazon.SimpleSystemsManagement;
    using Amazon.SimpleSystemsManagement.Model;
    using Microsoft.AspNetCore.Mvc;
    
    namespace ParameterStore.Controllers;
    
    [ApiController]
    [Route("[controller]")]
    public class ParamStoreController : ControllerBase
    {
        private readonly ILogger<ParamStoreController> _logger;
        private readonly IAmazonSimpleSystemsManagement _ssmClient;
    
        public ParamStoreController(IAmazonSimpleSystemsManagement ssmClient, ILogger<ParamStoreController> logger)
        {
            _ssmClient = ssmClient;
            _logger = logger;
        }
    
        [HttpGet(Name = "GetParameterStore")]
        public async Task<string> GetAsync([FromQuery] string parameterName)
        {
            var request = new GetParameterRequest() {
                Name = parameterName
            };
            var param = await _ssmClient.GetParameterAsync(request);
            return param.Parameter.Value;
        }
    }
    ```
3. It's easy, right? You can use `IAmazonSimpleSystemsManagement` to access the parameter. Please make sure you've set up the credentials. On my side, I use this `appsettings.json`.

    ```json
    "AWS": {
        "Profile": "paramstore",
        "Region": "ap-southeast-1"
    }
    ```

4. Run our project. Command: `dotnet run --project ParameterStore`

    ![Run project](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/czlzi65w6pm8s3in41q3.png)

5. Testing our project. You can use Postman or curl or other tools. You will get the encrypted data.

    ![Secrets get](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wtlqg52znu26jc9my2oh.png)

6. If you want to take the decrypted value, you will need update the request like this.

    ```csharp
    var request = new GetParameterRequest() {
        Name = parameterName,
        WithDecryption = true,
    };
    ```

7. Please check the different.

    ![decrypted](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aor2ub9rcgi5s3xb4wrs.png)

## Thank you

Thank you for reading. I hope it will be useful. If you have any feedback, please add it in the comment.

![Yes GIF](https://media.giphy.com/media/VxNjQl2FO0vZsJn9I2/giphy.gif)