Using AWS Secret Manager to Secure Java Microservice Passwords

Hussein Moghnieh, Ph.D.
4 min readJan 3, 2019

--

This blog introduces AWS Secret Manager service by Amazon and proposes a simple solution to migrate exiting Java code to use this service without significant code modification.

Introduction

On April 2018, Amazon introduced AWS Secret Manager service that is PCI-DSS compliant (Payment Card Industry Data Security Standard). This service enables application developers to store application properties containing sensitive information such as database passwords, third party API keys, etc… in a key-value store to be loaded by applications at runtime.

1 . Storing Passwords in Properties Files

Loading Passwords using Spring Boot Property Injection

In a typical Spring Boot Java Application, different configuration files are provided for each deployment environment. In the below project structure, local, QA, and production env. files are shown.

Properties are loaded depending on the environment the application is running on, for instance to load QA properties, Java Options would be something like:

JAVA_OPTIONS=--Dspring.config.location=src/main/config/qa/project.properties

Of course, it is a major security vulnerability to store properties containing passwords in plain text in property files and commit them to a version control system such as GitHub. Furthermore, developers should not have access to production passwords.

One solution followed by most companies is to store sensitive properties on a file on the server for an application to load them, however, this solution is not PCI-DSS Compliant.

2. Storing Secrets in AWS Secret Manager

Instead of saving the properties containing passwords on a file on the server (non PCI-DSS compliant), AWS Secret Manager makes it possible to store properties in a key/value store. The EC2 instance hosting your application accesses secrets in Secret Manager using its IAM role. For instance, the snapshots below show 2 secrets stored on AWS where each secret can save many key-value properties — as long the over secret size is less than 4096 characters. An IAM role can access these secrets by attaching the secrets’ ARN to an IAM policy.

  • qa_third_party_api_key
  • prod_third_party_api_key

3. Retrieving Secrets from AWS Secret Manager

Key-Value pairs in secrets can be retrieved using AWS’s SDK in any of the following programming languages: Java, Javascript, C#, Python3, and Ruby. The question is how to inject properties stored on AWS Secret Manager into a Java application?

3.1 — Non Recommended Solution: Loading Passwords from AWS Secret Manager from within the Application

One compelling solution and probably an obvious one is to use AWS’s JAVA SDK to load secrets from within a running JAVA application. This solution has two drawbacks:

1 — It requires code change in a way that the properties to be set from AWS Secret Manager cannot use Spring Boot Property Injection and instead have to be set programmatically.

2 —Developers will not have the option not to use Secret Manager when running the application on their local computer and using default passwords that don’t need to be secured on AWS Secret Manager.

3.2- Proposed Solution: Externalizing Properties Injection

The proposed solution is to externalize secrets injection into a Spring Boot Application by using SPRING_APPLICATION_JSON environment variable. Instead of loading secrets from within your application, it is enough to load the secrets prior to running your application into SPRING_APPLICATION_JSON. Spring boot will take any values in this environment variable and override any property your application may need from SPRING_APPLICATION_JSON.

In our case we used Python to load secrets from AWS Secret Manager and set SPRING_APPLICATION_JSON as shown below:

export SPRING_APPLICATION_JSON = python load_secrets.py

If you are running your Java application in a docker container, the script to load secrets can be executed before running your Java application by writing your own docker entrypoint.sh as shown below:

--

--