user11928577
user11928577

Reputation:

Setting up AWS Secrets Manager .Net Core

I have a .Net Core application that is running on an EC2 Instance. I want to use the Secrets Manager to contain my secrets for the web application such as "connection string" etc. The AWS Secrets Manager documentation isn't very useful, I can't seem to find a tutorial that will show / explain how to use the secrets manager on EC2.

I have successfully been able to extract "Secret" using postman and using the following code: However the Access Key and Secrets Key are both hard coded in.

I don't want this to be the case. I have installed the SDK and loaded the access key and secret key into this profile.

Essentially my question is how do I pull the access key and secret key down from SDK to sign the request?

if (secretsDetail == null)
        {
            return "Please provide SecretsDetails.";
        }
        string secretName = "";
        string secret = "";

        MemoryStream memoryStream = new MemoryStream();
        AmazonSecretsManagerConfig amazonSecretsManagerConfig = new AmazonSecretsManagerConfig();
        amazonSecretsManagerConfig.ServiceURL = secretsDetail.ServiceURL;

        IAmazonSecretsManager client = new AmazonSecretsManagerClient(RegionEndpoint.GetBySystemName("eu-west-2"));

        GetSecretValueRequest request = new GetSecretValueRequest();
        request.SecretId = secretName;
        request.VersionStage = secretsDetail.VersionStage == null ? "AWSCURRENT" : secretsDetail.VersionStage; // VersionStage defaults to AWSCURRENT if unspecified.

        GetSecretValueResponse response = null;


        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;
        }
        catch (InternalServiceErrorException)
        {
            // An error occurred on the server side.
            // Deal with the exception here, and/or rethrow at your discretion
            throw;
        }
        catch (InvalidParameterException)
        {
            // You provided an invalid value for a parameter.
            // Deal with the exception here, and/or rethrow at your discretion
            throw;
        }
        catch (InvalidRequestException)
        {
            // You provided a parameter value that is not valid for the current state of the resource.
            // Deal with the exception here, and/or rethrow at your discretion.
            throw;
        }
        catch (ResourceNotFoundException)
        {
            // We can't find the resource that you asked for.
            // Deal with the exception here, and/or rethrow at your discretion.
            throw;
        }
        catch (System.AggregateException)
        {
            // More than one of the above exceptions were triggered.
            // Deal with the exception here, and/or rethrow at your discretion.
            throw;
        }
        // Decrypts secret using the associated KMS CMK.
        // Depending on whether the secret is a string or binary, one of these fields will be populated.
        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;
        }

Upvotes: 4

Views: 9044

Answers (3)

dthrasher
dthrasher

Reputation: 41782

The other answers to this question are accurate, but might not cover all the use cases you have. For connections to AWS services, you can rely on IAM settings as described in the other answers. There's no need to bother with credentials or connection strings at all!

But suppose you need to connect with 3rd-party services outside of AWS?

If you want to store connection strings or API keys for these 3rd party services in AWS Secrets Manager, you have a few options:

  1. Inject these secrets as environment variables into your hosting process during deployment.
  2. Modify your .NET Core code to access the secrets.

For approach #2, the best article I've found is this one: http://blog.travisgosselin.com/net-core-and-aws-secrets/

It discusses in depth how to extend .NET Core's configuration manager to incorporate AWS Secrets Manager secrets.

It refers to this NuGet package, which is the basis for several solutions. https://www.nuget.org/packages/Kralizek.Extensions.Configuration.AWSSecretsManager

And Amazon has a 1st party package for getting secrets using C#, announced here: https://aws.amazon.com/blogs/security/how-to-use-aws-secrets-manager-client-side-caching-in-dotnet/

You'll likely have to play with a few approaches to find what works best for you -- there isn't yet a complete "out-of-the-box" solution for this, as of September 2021.

Upvotes: 1

Alisson Reinaldo Silva
Alisson Reinaldo Silva

Reputation: 10695

You don't have to provide access/secret key when using SDK within EC2/Lambda. For accessing services like Secrets Manager inside an EC2 or Lambda, you attach a role to the resource (EC2, Lambda), and attach policies to it.

1 - First create a role

You can skip this step if you already have a role for your EC2/Lambda.

Create a role

Selected the type (EC2):

Select type

2 - Attach the SecretsManagerReadWrite policy:

SecretsManagerReadWrite


3 - Attach Role to EC2 instance

For new instance, you can select the IAM role you created as below.

new instance IAM

For existing instance, select the instance and change the IAM Role as below:

Existing instance IAM Role


By doing these steps, your instance will be able to use SDK without explicitly providing the access/secret keys. You can later attach new policies to the role as you need to use new resources, like SQS for example.

Upvotes: 2

Jason Wadsworth
Jason Wadsworth

Reputation: 8887

The short answer to your question is that you don't. The SDK will automatically get credentials for you. Using Credentials in an Application. You can use any of the methods described here, but #4 is the preferred, most secure option.

For applications running on an Amazon EC2 instance, credentials stored in an instance profile.

Upvotes: 1

Related Questions