Keeping secrets of Magnolia CMS

In this article I will show how to store sensible configuration of Magnolia in a Secret manager like Hashicorp Vault or AWS Secrets Manager.

Keeping secrets

A solution to avoid sensible data in the configuration of applications and services is to store it in a Secret manager.

A Secret manager is a service that stores sensible data and exposes an API to retrieve the value, a typical use case is to store database passwords in a secret manager and retrieve the value during the startup of the service that requires it.

Most popular secret managers are Hashicorp Vault, AWS Secrets Manager and Google Secret Manager

Configuration in Magnolia

The configuration of modules in Magnolia is stored in JCR database:

It means that sensible configuration could be exposed.

Solution

The solution to avoid exposing sensible data in Magnolia is to store and retrieve this information from a Secret manager.

Another advantage of using a secret manager is to centralize the configuration of services — as the api key of Google or AWS-

Implementation

Create a client in Magnolia to retrieve secrets from Secret manager

During startup of modules, update the configuration of the module with the properties of the module stored in Secret manager.

Above requirements have been implemented in the module with-secrets.

Usage

  1. Add dependency with the module with-secrets
<dependency>
<groupId>com.formentor</groupId>
<artifactId>with-secrets</artifactId>
<version>${project.version}</version>
</dependency>

2. Extends the module class with ModuleConfigSecrets

3. Configure Hashicorp Vault in the module with-secrets

host: address of the Vault server
prefix: prefix or path of the modules of magnolia in Vault. The prefix is added to the module name to get the configuration.

4. Set the access token of Vault in the environment variable VAULT_TOKEN

$ export VAULT_TOKEN=myroot

Demo with Hashicorp Vault

The project magnolia-with-secrets-bundle provides a docker-compose that starts a Vault Server and a Magnolia instance with the module example-with-secrets whose configuration is stored in Hashicorp Vault.

0. Clone the project magnolia-with-secrets-bundle

$ git clone https://github.com/joaquin-alfaro/magnolia-with-secrets-bundle
  1. Start Hashicorp Vault server and a Magnolia instance using the docker-compose of the project.
# Build the project
$ mvn clean package
# Launch the services
$ docker compose up -d

2. Put the secret “vendorApiKey” of the module example-with-secrets in Vault

a) Using Vault cli

$ docker exec -ti magnolia-with-secrets-bundle_vault_1 sh -c "vault kv put secret/magnolia/example-with-secrets vendorApiKey=i-am-a-secret"

b) Using Vault ui

http://localhost:8200/ui using token “myroot”

3. Restart the module example-with-secrets

a) Restarting the container of Magnolia

$ docker stop magnolia-with-secrets-bundle_magnolia_1
$ docker start magnolia-with-secrets-bundle_magnolia_1

b) Restarting the module in Magnolia

Changing the configuration of the module triggers the starting of the module, you can add a dummy property.

Magnolia is exposed in http://locahost:8080/.magnolia

4. Open the page show-secret

The page show-secret of Magnolia shows the value of the property “vendorApiKey” of the module example-with-secrets.

As you will see the value matches the entry “vendorApiKey” of the secret “secret/magnolia/example-with-secret” in Hashicorp Vault server.

Magnolia is exposed in http://locahost:8080/.magnolia

Insights

How to implement integration with Secrets manager

  1. Create a class implementing the interface SecretsStorage and implement the method readModuleConfig()
import java.util.HashMap;public class SecretsStorageImpl implements SecretsStorage {
@Override
public Map<String, String> readModuleConfig(String module) {
return new HashMap<>();
}
}

2. Create a method in the factory of secret managers to return an instance of the Secret manager.

public class SecretsStorageFactory {
/**
* Returns an instance of SecretsStorage implemented for the secret manager
* @param config
* @param magnoliaConfigurationProperties
* @return
*/
public SecretsStorage getSecretsStorageAWS(SecretSettings config, MagnoliaConfigurationProperties magnoliaConfigurationProperties) {
return new SecretsStorageImpl();
}
}

Resources and references

Github of the project magnolia-with-secrets-bundle

https://github.com/joaquin-alfaro/magnolia-with-secrets-bundle

--

--

--

Solutions Architect at formentor-studio.com

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

what is the average cost of app development

Blackjack Download & Quick Python Install Tutorial. Windows/Mac/Android

Interview Experience with PeopleStrong for Java Developer profile

Take the headache out of authentication error handling with Hosted UI

Mobydick Finance

Sentiment analysis of Russians on Constitutional Amendments

Review of Udacity Machine Learning Engineer Nanodegree with AWS SageMaker

Theoretical modelling of a leaky bucket in Python

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Joaquín Alfaro

Joaquín Alfaro

Solutions Architect at formentor-studio.com

More from Medium

Dependency injection via Constructor, property, and Method injections in swift

APIs let’s start with the basics shall we? Then read this…

Why should you program using TDD

Debugging the debug process