config files

How to inject secrets into config files

Secrets are often a small part of a bigger configuration file that is consumed on startup of an application.

For instance, your app could have a config file that looks something like this:

database:
    host: localhost
    port: 5432
    username: myapp
    password: piG1rX5P1QMF6J5k7u7sNb

The database password is secret, so now the entire file has become secret. This means you cannot check it into source control. However, it still needs to be kept in sync throughout developer workstations, CI and production servers, which is manual and error-prone work.

What we’d want is to solely extract the secret part out of it, lock it away safely, and put the non-sensitive part in source control.

This guide will show how you can remove only the secrets from the config file, so that it can be safely checked into source control and shipped with your application.

Before you begin

Before you start using SecretHub with config files, make sure you have completed the following steps:

  1. Install the SecretHub CLI for your OS.
  2. Sign up for a SecretHub account.

Step 1: Template the config file

You can use SecretHub’s template syntax to replace the plaintext secret values with a reference to the paths on which they are stored in SecretHub:

database:
    host: localhost
    port: 5432
    username: {{ your-username/start/db/user }}
    password: {{ your-username/start/db/password }}

Everything between {{ and }} is treated as a path to a secret.

Step 2: Store your secrets on SecretHub

To store your secrets on SecretHub, you can use write:

secrethub write your-username/start/db/user &&
secrethub write your-username/start/db/password

Step 3: Inject secrets in the template

Now you can use the inject command to inject secrets on the fly:

secrethub inject -i config.yml.tpl -o config.yml
Diagram showing how to inject config files with secrets using SecretHub
Inject secrets into config files using SecretHub

You have now successfully removed the secrets from the config file and automatically provisioned them at runtime! The config file template is stored together with the code in source control, so that every developer can see the structure of the file.

Step 4: Differentiate between environments

SecretHub templates are built for supporting multiple environments. We highly recommend you structure your SecretHub secrets in the same way across all your environments: e.g. app/dev/db/password and app/prod/db/password.

If you do so, you can easily switch to a different set of secrets through the use of variables in your template file. You could have variables for your environment, stage, region, tenant, or anything else you see fit:

database:
    host: localhost
    port: 5432
    username: {{ your-company/$env/db/user }}
    password: {{ your-company/$env/db/password }}

Now you can set the variable when injecting the template with secrets:

SECRETHUB_VAR_ENV=prod secrethub inject -i config.yml.tpl -o config.yml

You can use an environment variable (SECRETHUB_VAR_KEY=VALUE) or flag (--var key=value).

You can now use the same template file, that is stored in source control next to your application, for all your deployments!

See also