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.
Looking for a Microsoft Azure-specific solution to store & read your passwords? Check out this article: “How to securely store and retrieve sensitive info in .NET Core apps with Azure Key Vault”
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
back-end, and 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 AWSSDK.SecretsManager
NuGet package. To do that, in your terminal of choice navigate to your project folder and run the
following command:
Next, the following code will connect to AWS and retrieve the secret:
Some critical moments to call out here:
accessKeyId
and secretAccessKey
are meant to contain valid access credentials. Generally, your
EC2 instance will have environment variables AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
containing those. You can skip these parameters, and it will force the
AmazonSecretsManagerClient
to use the environment variables.AmazonSecretsManagerClient
call 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
them using AmazonSecretsManagerClient
from AWSSDK.SecretsManager
package and how to troubleshoot
any issues you may have.
Leave a comment below if you have any issues or questions!
Download fully tested and 100% working Visual Studio solution with the source code used in this article for FREE – just enter your name and email in the form below, and I’ll send you the download link right away.
You will also get access to all the source code for all existing and new articles on the site, and access to my mailing list, which receives handy timesaving tips on .NET Core programming.