11 Jul 2019
More often than not your application needs to have access to various sensitive information, such as logins & passwords of various sorts (database, network resources etc), API keys, encryption keys and alike.
In one of my earlier articles, I demonstrated how that information can be stored in an encrypted way in the application config file – see How to store login details securely in the application config file. This approach, however, is not fool-proof. In fact, it’s quite easy to decrypt the information stored in such a way, provided the attacker has access to the executable with the decryption key.
In this article, I would like to show you a much more secure way of storing and accessing sensitive information – such as usernames and passwords, encryption keys, API keys etc. This method will come particularly handy if you already rely on AWS for some of your application needs.
Creating a secret is easy:
You can both supply a free-text value for the secret, as well as provide a JSON-formatted data (this will need to be de-serialised by your app later). JSON is preferable if you want to store a complex structure, however, if you have just a password to store, replace everything in that text box with your secret string:
Next step is to name the secret. You may want to use some form of “path emulation” in your secrets
naming. For example,
web-api/passwords/database may store a DB password used by your Web API
worker/password/web-api-key for your worker app, that calls Web API and needs an API
key. Having a simple naming convention helps when you have several secrets to keep the track of.
Unfortunately, secret access control is a big topic that is outside of this article. I am going to assume that you already have a user or a role set up in AWS that has corresponding permissions to access AWS Secrets Manager.
In case you need to get that sorted first, check out this article - “Authentication and Access Control for AWS Secrets Manager”. But in short, you’ll need to:
If this proves to be problematic, leave a comment below, or shoot me an email, and I’ll write a separate article on how to do that.
Finally, the fun part! First of all, your .NET Core app needs to reference
NuGet package. To do that, in your terminal of choice navigate to your project folder and run the
Next, the following code will connect to AWS and retrieve the secret:
Some critical moments to call out here:
secretAccessKeyare meant to contain valid access credentials. Generally, your EC2 instance will have environment variables
AWS_SECRET_ACCESS_KEYcontaining those. You can skip these parameters, and it will force the
AmazonSecretsManagerClientto use the environment variables.
AmazonSecretsManagerClientcall as above or by setting the default region, like so:
AWSConfigs.AWSRegion = RegionEndpoint.APSoutheast2.SystemName;
It’s quite likely that your app won’t retrieve the secret correctly the first time you test it. Don’t despair - security is a tricky area. There are quite a few hoops to jump through:
To troubleshoot any issues, set breakpoints in every
catch clause (there’s a few, see the link
above for all possible exceptions, or download the code below). Run your app in the debugger and see
which error you get. Inspect the exception object in detail, as it will contain details of the
particular issue you’re having. Alternatively, add ample logging.
In this article, I demonstrated how you can store secrets using AWS Secrets Manager, how to retrieve
AWSSDK.SecretsManager package and how to troubleshoot
any issues you may have.
Leave a comment below if you have any issues or questions!