Secure data source access credentials in application.properties

Hi All,

as never before, customers are increasingly obsessed with safety aspects. Using any silly “security assessment tool”, quickly it turns out that in application.properties datasource username and password are in clear text (e.g. main.datasource.username, main.datasource.password)

Is there any possibility of obfuscating or better yet encrypting at least the password field in application.properties transparently for Jmix Persistence Management API?

In general, it could be useful to have the possibility to define in Jmix interceptor methods that allow you to act on the sensitive fields of application.properties to which you can delegate the application of some decryption algorithm (or other functions) before sending the data to the target API eg. JDBC Connection Pool.

Thanks in advance!

Hi Davide,

first of all: welcome to the community :wink:

Regarding your question:

Generally speaking, you should try to avoid putting your DB credentials into application.properties. First of all to keep it outside of source control, but also to prevent being able to read it.

Jmix puts the credentials in fact in the application.properties though. The main reason for it that for the local development environment this is fine.

For a production scenario, there are multiple options to achieve what you want.

Environment Variables

The first one is to set the values through Environment variables. This is a native Spring Boot feature and a lot of people leverage that to externalise those values:

So instead of putting the values main.datasource.username and main.datasource.password in the application.properties, you set the following environment variables on your server / docker container: MAIN_DATASOURCE_USERNAME and MAIN_DATASOURCE_PASSWORD.

This way the credentials are injected into the application through the external operation systems settings. Here in the docs on how to deploy it to AWS Beanstalk, it is described in a very similar way: Amazon Web Services :: Jmix Documentation. The only difference is that in the application.properties it is explicitly mentioned that it refers to an external environment variable like this: main.datasource.password = ${RDS_PASSWORD}.

Both options will work fine.

Now, there are multiple ways on how you set the environment variables in the operating system. This highly depends on your deployment environment. In Kubernetes you can use something like Secrets to further obfuscate them / store them in a safe place. In an AWS context you can use e.g. Secrets Manager to set the values from secrets manager into your Docker container (in case of ECS).

But all of those approaches share one common pattern: within the container / operating system, everyone who has access to read the environment variables can still read the values.

The second approach goes a little further.

Dynamically Load credentials form Secret Store

In this case, the Jmix / Spring Boot application will at startup ask a secret store to grant them the values. E.g. there are solutions out there for Hashicorp Vault or also AWS Secrets Manager, where basically the application proactively reads the actual DB credentials from those secret stores on application startup.

The difference is that you have not laying around those environment variables anymore. Combining that approach with having short lived credentials will improve the situation even further. Here is an example of such approach for AWS: RDS Database Authentication with Spring Boot: Part 2, IAM Authentication — Chariot Solutions

From what I read from your question, solution number 1. is probably enough for you and also I think what most people are doing.

I hope this helps
Mario

3 Likes

Hi Mario,

Thank you very much for the valuable advice and for the pointers on the network, in our case it is possible we need to integrate a secret store on Azure infrastructure (Azure Key Vault).
Hopefully we will be happy to share the Jmix integration experience with the community.

Best regards

A small correction regarding environment variables: until https://youtrack.jmix.io/issue/JST-2953 is fixed, the placeholders in properties should have default values to be recognized by Studio, for example ${DB_HOST:localhost}.