Skip to main content
Version: 13.x (Current)

Secrets Resolution in Config Maps

In general, services may have secrets or sensitive data inside their configuration files (Config Maps), such as connection strings or credentials. This usually performed for grouping a set of configuration properties together and reduce the clutter generated by a large number of environment variables.
Since these configuration are stored in plain text (differently from Secrets), anybody with the access to them can read their content.

Therefore, to prevent unauthorized access to those details, the initial approach for solving this issue was to interpolate variables within config maps, using the {{<env_var_name>}} syntax. For example, assuming the client identifier for our application is stored within the environment variable APP_CLIENT_ID and we wanted to add such value to a config map using the interpolation feature of mlp, we would write a config map as follows:

{
"cool-config": {
"app": {
"client-id": "{{APP_CLIENT_ID}}"
}
}
}

Although this solution avoids writing secrets in plain text while config maps are stored in a repository (for versioning them), it does not prevent users with access to K8s config maps to read those secrets once configurations are deployed.

To address this pitfall and provide an agnostic solution that works with any deploy tool, we introduced within our service a logic of secrets resolution, which allows injecting secrets within configuration files only within the service at runtime (after a config maps is mounted and read by the service).

Secrets can be injected via secret resolution within a config map as:

  • plain text, that is providing the real or interpolated value
  • reference to an environment variable
  • reference to a file, either its full content or the internal key of a .ini file

These are the services versions that support this feature in their config maps:

ServiceVersion
Projection Storer>=1.2.0
Real-Time Updaterplanned
Single View Trigger Generator>=3.3.1
Single View Creatorplanned
Control Plane>=1.1.0
Fabric BFF>=1.0.0
tip

Please, verify in the documentation and in the service configuration schema which config properties support secret resolution mechanism.

Plain Text

The field is set to be a string and it is loaded directly from the Config Map itself.

{
"some-entry": {
// ...,
"some-secret-field": {
"url": "{{CONNECTION_STRING}}"
}
}
}
danger

Remember to use external environment variables, to avoid store them in plain in your Console configuration!

info

This mode provides backward compatibility with any of your existing configuration, so that

  • you may upgrade your services with confidence without the need to change your config maps
  • you may try out the secret resolution method and potentially revert your changes without breaking your services

Environment Variable

The field is populated by a microservice environment variable.

{
"some-entry": {
// ...,
"some-secret-field": {
"url": {
"type": "env",
"key": "<ENVIRONMENT VARIABLE NAME>"
}
}
}
}
tip

By default the value contained in the environment variable that is referenced within the secret is expected to be a plain text. However, the secret definition allows to define the encoding property to base64, so that the value contained in the environment variable can be written in base64 format.

{
"some-entry": {
// ...,
"some-secret-field": {
"url": {
"type": "env",
"key": "<ENVIRONMENT VARIABLE NAME>",
"encoding": "base64"
}
}
}
}

File Reference

The field is populated by the content of a file mounted inside the microservice, such as file a K8s secret.

To help in creating K8s secrets it is available mpl tool which automate secrets creation of the ones configured in the mlp.yaml file that can be found within your Console Project repository.

Full Content

{
"some-entry": {
// ...
"some-secret-field": {
"url": {
"type": "file",
"path": "/path/to/file"
}
}
}
}

Using the above configuration the service will load the whole file content within the configuration property (in this case some-secret-field).

Single key from .ini file

Secret resolution of files supports also the .ini format, that is a file with key-value pair values. Consequently, it is possible to specify which key within the selected file should be loaded in the microservice configmap's property.

{
"some-entry": {
// ...
"some-secret-field": {
"url": {
"type": "file",
"path": "/path/to/file.ini",
"key": "KEY_NAME"
}
}
}
}

For example, let's consider the above configuration and the following .ini file:

KEY_NAME=cool-secret
OTHER_KEY=uninteresting-secret

which is mounted as secret in the microservice at the path /path/to/file.ini. As a result, the value that the microservice will read when accessing the config property some-secret-field is cool-secret associated to KEY_NAME key.