AWS Secrets Manager. Maintain your sensitive data securely

Yuri Fenyuk
7 min readNov 19, 2018

This year AWS released service to keep sensitive data in safe place and refresh it periodically in automatic way if needed. The plan for this article is to give a brief introduction to above and show how simple is to use it.

Self descriptive service name perfectly reflects what it does: handling with care secrets inside AWS clouds. The killing feature of AWS Secrets Manager is secret’s rotation. With help of built-in Lambda function for AWS RDS, ‘other’ databases which AWS hosts, or by writing custom Lambda function you can schedule the secret rotation using the number of different strategies.

Secrets in most cases mean database credentials, i.e. login and password. In broader way, it could be anything we would like to hide from spare pair of eyes on one side (for example, hashing salt or API key), but have easy access to, on another.

Periodical password rotation is one of must-have security best practices. AWS Secrets Manager implements this in easiest possible way for Databases while providing ‘do-it-yourself’ option via Amazon’s favorite FaaS — Lambda.

In fact, Secrets Manager is handy existing AWS managed services mixture, which can even be cooked yourself with help of Systems Manager Parameter Store for secrets maintaining, CloudWatch events for scheduling the secret rotation, Step Functions for rotation implementation and Lambda as custom code container. Obviously that using one service is the shortest way.

The best way to get a brief impression of secrets type is to run AWS Console UI wizard and read information about three secret types (in fact two, because RDS and other databases are quite close by nature and two tabs here might be only explained by AWS promoting RDS databases)

Database / RDS
Database / other
DIY type

First two types are about database logins and out of scope of this article. Please use an official documentation or search for dedicated articles (
like this or that). Most fascinating thing for me here was the secret rotating procedure stages, when master-secret creates working-secrets in pending state, than promotes it to current and later retire previous.

The last one, which is “Other type of secrets” is the most interesting for majority developers, since allows to use AWS Secrets Manger to save anything.

Let’s do practicing. And practice sample a tiny utility our startup needed to have a secure communication between microservices. In most cases we prefer to pass customer’s JWT token between microservices, as customer’s data can be extracted and used for authorization in every microservice, regardless how deep invocation chain is (passing same JWT from one to another microservice). At the same time, every individual microservice can be used independently as the very same customer’s JWT token can be passed in. Since not all actions are initiated by customer, there will be inter microservice calls for different purposes. To keep same authentication code, it’s would be nice to send some impersonate JWT, so called “service” JWT. After receiving any JWT, microservice can validate it, extract JWT body and if body has customer information, authorize customer and, id allowed, execute action. Or execute different code, if received JWT is “service” JWT.

The plan is to store “service” JWT in AWS Secrets Service, where it will be crypted with AWS KMS key and access to it can be limited with AWS IAM and use AWS SDK to access active JWT value. In addition, we will use use custom Lambda to refresh JWT on daily bases as current valid JWT will expire next day.

To save efforts, test account on https://auth0.com will be used. In test account please create new API instance (mine named “Auth0 Management API”).

Auth0 / API

All reasonable defaults are ok for my humble example. Make sure that Token expiration value is 90000 secs, which is 25 hours, because JWT rotation logic I am going implement, will issue new token on daily basis leaving extra hour token validity to let long running calls to finish.

Auth0 / token expiration

The plan is to use AWS Secrets Manager to keep fresh JWT (rotating it daily).

As a final step from Auth0 site, need to copy Client ID/Client Secret which will be used in Lambda. On Application tab both can be found

Auth 0 / client credentials

Time to run sample and see dive into code.

Deployed solution in AWS Secrets Manager creates two secrets shown below:

AWS Secrets Manager / list

Opening ‘auth0-secrets-demo’ details and clicking on ‘Retrieve secret value’ button should reveal same Auth0 Client ID/Secret as seen Auth0 console.

AWS Secrets Manager / Auth0 entity

The plan is to keep Auth0 secrets here and use it in token rotation Lambda to generate new token. This approach is better than use environment variables in Lambda itself from security and maintenance perspective. ‘auth0-secrets-demo’ entity keeps static (non-rotating) secrets and supposed to only be edited manually.

Second entity ‘service-token-demo’ details looks similar to following:

AWS Secrets Manager / Token entity

‘Rotation configuration’ section shows that secret rotation is on and interval is one day. ‘Sample code’ section has sample code to be used in all places where current value of service token is needed.

‘Secret value’ can show current value if ‘Retrieve secret value’ clicked, like below:

It includes ‘Generate at’ column for visualization purpose. And, with ‘Retrieve secret value’ click, active token value shown:

AWS Secrets Manager / Token value

Please get source code from git here. Serverless toolkit used to handle build functionality (in fact, only token rotation Lambda implemented on .NET Core) and deploy on AWS cloud.

Below serverless (sls) command creates a skeleton for project with one ‘hello world’ Lambda and main toolkit configuration file serverless.yml:

Modified serverless.yml looks like:

It specifies that Lambda will be implemented in .NET Core (#22), project is deployed on Ireland region (#23) on stage ‘demo’ (#24), includes couple environment variables (#26, #27) referenced in Lambda. Final part states that it have one Lambda named ‘rotate’ (#38) and entry function location (#39).

It is more than recommended to download whole project, which is fully functional, from git as only the most important pieces will be covered in the rest of current.

Amazon core and SecretsManager packages used in Lambda, as well as JSON serialization and open source DewRestClient to make HTTP calls to Auth0 API to get fresh token.

As specified in serverless.yml main Handle function code (#17…#38) is below:

Class TokenGenerator encapsulates main functionality. At the beginning (#43 … #69) few simple classes to handle to JSON string from JSON string serialization declared. AUTH0_SECRET_NAME (#71) is constant with AWS Secrets Manager entity storing Auth0 credentials which required to generate new JWT. TOKEN_SECRET_NAME (#72) is constant for main AWS Secrets Manager entity always having valid JWT, rotating it daily with help of rotation AWS Lambda.

Class function Generate() reads Auth0 credentials, makes call to Auth0 to get fresh JWT and returns it to function caller. Last class function Store(…) stores in AWS Secrets Manager new JWT value.

One more C# unit with AWS Secrets Manager wrapping AWS SDK corresponding class functionality:

Implementation is reasonably simplified and pretty easy to understand if you look at AWS SDK for Secrets Manager.

To deploy serverless project with Lambda you need to build it first (thanks to sls boilerplate code which creates build.sh and build.cmd) with:

and only that deploy to AWS (in this case stage ‘demo’ and region ‘eu-west-1’)

Last step is to deploy on AWS main players — AWS Secrets Manager entities. I am sure soon it will be easy to do with help of AWS Cloud Formation stack (thus, serverless.yml will be extended with corresponding resource descriptions), but at the writing moment only AWS CLI (command line interface) command is available. This makes no sense to explain command file here, as it will be overkilling soon, just take a quick view:

and run it with following command to finish whole process:

where first two parameter are from Auth0 and last parameter is 10 digits account id from AWS.

AWS Secrets Manager is one of numerous AWS services, which is not bringing revolution in clouds, but addresses needs which almost every project has. It is roughly half of year since release date yet, but it was so easy to built in into our existing eco system on AWS from the initial release and rely on it in production. For this period, there was zero accident with it :).

Like all fans of AWS, I am looking forward to upcoming #reInvent’18 to be surprised one more time with terrific stuff Amazon brings to life!

--

--