Click here to Skip to main content
15,880,427 members
Articles / Hosted Services / AWS

Access AWS Secrets Manager via .NET CORE

Rate me:
Please Sign up or sign in to vote.
5.00/5 (5 votes)
11 Mar 2019CPOL3 min read 25.4K   552   3   4
This article will help you to implement the functionality where you can store your sensitive data in the amazon Secrets Manager and access while bootstrapping the application.

Introduction

I was working on my project to store the secrets in the application.json. But when I saw AWS Secrets Manager, it looked secure and easy to implement in my system.

  • This will help to store secrets like connection string paths at secure location.
  • The values are always encrypted so it is not possible to access those without authorization
  • You don't need to deploy application in case of values modified.
  • Very easy to change values.
  • Implementation is easy and very fast.

This article will help you to implement the basic prototype where you can access the secrets from Secrets Manager for your project. The code will explain to you in a step by step manner what and how we can achieve this.

This article uses .NET Core 2.2 to implement the functionality.

Secure Secrets Storage Management

  1. AWS Secrets Manager encrypts secrets at rest using encryption keys that you own and store in AWS Key Management Service (KMS).
  2. When you retrieve a secret, Secrets Manager decrypts the secret and transmits it securely over TLS to your local environment.
  3. By default, Secrets Manager does not write or cache the secret to persistent storage. And you can control access to the secret using fine-grained AWS Identity and Access Management (IAM) policies.

Audit and Monitor Secrets Usage

  1. The secrets changed or modified are version controlled.
  2. You can track which secret changed and when it is modifed.
  3. We can set a cloud watch logging for secrets whcih will give detail information of the versioning of the secrets.

Automatic Secrets Rotation

  1. With AWS Secrets Manager, you can rotate secrets on a schedule or on demand by using the Secrets Manager console, AWS SDK
  2. You can also extend this functionality to rotate other secrets by modifying sample Lambda functions. For example, you can rotate OAuth refresh tokens used to authorize applications or passwords used for MySQL databases hosted on premises.
  3. All this can be done with the Secrets Manager API provided by AWS.

Using the Code

I created a micro service which will just do one thing to retrieve the data from the AWS and give the secrets in string format. This service contains the complete implementation of requesting the data from Amazon Secrets manager and return in json format

Prerequisites of the Project

Image 1

  1. AWSSD.Core by Amazon Webservice
  2. AWSSDK.SecretsManager by Amazon Seb Services
  3. Microsoft.AspNetCore.App
  4. Microsoft.NETCore.App
  5. Swashbuckle.AspNetCore (This is for swagger)

First for our Core API, we need input via Rest endpoint API. As we are creating this as an API, you can send the details and the secrets. In order to do that, let's create a Model where it can be used to do that.

C#
/// This is a class which will give us all the information for extracting the data 
  public class SecretsDetail
    {
        public string Region { get; set; }       // The region you deployed your secrets 
        public string SecretName { get; set; }   // The secret name to access the secret 
        public string AccessKeyID { get; set; }  // access id created for the secret authorization
        public string SecretKey { get; set; }    // key for authorization
        public string VersionStage { get; set; } // Which version you want to access 
        public string ServiceURL { get; set; }   // the path of the endpoint
    }

Once our model is ready, we can use that model in the controller where it will pass to the GetSecretManager class. When we have all the details for AWS communication, we are good to build objects. In the below code block, we are using AmazaonSecretsManagerConfig to build the endpoint info for the Secrets Manager.

The AmazonSecretManagerClient will take parameters like AccessID SecretKey and config. If you are in the network or working on EC2 instance, then you don't need to provide the config. You can just pass the secretName and access id and secretKey. But outside the Amazon's Network, you need all the details which we are using below:

C#
// Get the Secret name 
string secretName = secretsDetail.SecretName;
//Assign the region. 
string region = secretsDetail.Region;
            string secret = "";

    MemoryStream memoryStream = new MemoryStream();
    AmazonSecretsManagerConfig amazonSecretsManagerConfig = new AmazonSecretsManagerConfig();
    amazonSecretsManagerConfig.ServiceURL = secretsDetail.ServiceURL;
            
   IAmazonSecretsManager client = new AmazonSecretsManagerClient
        (secretsDetail.AccessKeyID, secretsDetail.SecretKey, amazonSecretsManagerConfig);

   GetSecretValueRequest request = new GetSecretValueRequest();
   request.SecretId = secretName;
   request.VersionStage = secretsDetail.VersionStage == null ? 
     "AWSCURRENT" : secretsDetail.VersionStage; // VersionStage defaults to AWSCURRENT if unspecified.
   GetSecretValueResponse response = null;
   This code block will build the client get the response back. 

The AmazonSecretsManagerConfig will get the endpoint information. This will help to get value from the SecretManagerClient. The AccessKeyID and SecretKey will give you the details of the Response.

The below code will extract the data from memory stream and give us the plain string which we can convert in the Json format.

C#
try
   {
       response = client.GetSecretValueAsync(request).Result;
   } catch (DecryptionFailureException)
   {
       // Secrets Manager can't decrypt the protected secret text using the provided KMS key.
       // Deal with the exception here, and/or rethrow at your discretion
       throw;
   }

  if (response.SecretString != null)
   {
       return secret = response.SecretString;
   }
   else
   {
       memoryStream = response.SecretBinary;
       StreamReader reader = new StreamReader(memoryStream);
       string decodedBinarySecret = System.Text.Encoding.UTF8.GetString
                                    (Convert.FromBase64String(reader.ReadToEnd()));
       return decodedBinarySecret;
   }

Swagger Test

Image 2

Result

Image 3

The attached source code will give all the details about how it is built. Please feel free to write comments in case of any more explanation needed.

Notes

  1. The code is up and runing. You just need to pass the correct values and it will give the data.
  2. You can use the configured swagger to test the code.
  3. If you are facing any challanges or any errors, please mention in the comments.

History

  • 11th March, 2019: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionAWS Monitoring Pin
William.Front-end25-Sep-20 3:10
William.Front-end25-Sep-20 3:10 
QuestionKMS Intregration Pin
Member 1458618826-Jul-20 21:03
Member 1458618826-Jul-20 21:03 
QuestionError Pin
Karan Odedra15-Jun-20 23:49
Karan Odedra15-Jun-20 23:49 
QuestionQuestion Pin
Member 147958047-Apr-20 21:56
Member 147958047-Apr-20 21:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.