I have searched the internet far and wide trying to find the best answer to this question. Where is the best place to store website credentials and API keys?
There are a lot of options ou there but none of them have really given me any level of satisfaction that I’m looking for. I could store credentials like usernames and passwords in a web.config but then I would have to consider how I store that in source control as well as the risks of storing it in plain text.
Sure I could encrypt that web.config before deployments but I still have the problem of dealing with source control. That just isn’t going to work.
I could go about storing the credentials and API keys in a database. This is a slightly improved solution but then again… how do I store a database connection string and credentials to that database outside of the database to allow connection to it?
I could use Windows Authentication but what if my stack changes or doesn’t support Windows Auth? I also then still need to consider encrypting my database and the credentials or API keys so they aren’t stored in plain text. And then what if I wanted to check one of those values, I’d have to decrypt it as well…. omg what a pain in the ass this is…
The real truth is there isn’t an easy or best way to store website credentials and API keys… until AWS Secrets Manager came along.
AWS Secrets Manager offers an offsite option for storing all of your credentials, database strings, and API keys. It is quite literally a one stop shop for all your secret storage needs.
The way it works is by allowing you to use your AWS Access Key ID and AWS Secret Access Key (basically your AWS authentication) to create an AWS Secrets Manager client. Using this client you can then request credentials from AWS to be served back to your code repository. It’s actually so easy to implement that I managed to do it in a handful of lines of code:
One of the best things is AWS allows you to handle authentication by creating environment variables for your AWS client and allowing your code base to utilize those to complete the authentication to AWS. This makes it very easy to move your code base through various test environments without having to worry about changes in each environment.
AWS also offers a cache solution for your Secrets Manager Client. You see each time you connect to AWS to retrieve a secret like credentials there is a small cost associated (we’re talking pennies here). This isn’t much until you consider having to grab these credentials on each web request which can easily climb into the thousands and skyrockets costs.
Thankfully AWS offers the cache solution which let’s you pull the secrets once and then cache them on the server side. This avoids having to poll AWS for a the secret every time it’s needed and greatly reduces cost. Thanks AWS! Oh and it’s also very easy to implement:
And when you’re ready to actually pull the secret from AWS:
var secret = await cache.GetSecretString(secretId);
AWS Secrets Manager also offers a handful of other sweet benefits. You’re able to automate password rotation for AWS services like RDS, Redshift, and DocumentDB and of course you get the security that comes with using AWS. There are also some fantastic Auditing features, my favorite being that when a password is deleted it is stored for 7 additional days and managing parties are notified of the delete. No accidents!
All-in-all AWS Secrets Manager is a fantastic solution to the, “How do I manage my credentials for my applications” problem. The cost is very minimal when used in conjunction with the caching feature and the overall complexity to implement the solution is minimal. If you’re looking for a next-gen solution to managing sensitive application data I highly recommend AWS Secrets Manager.