Secrets backend support coming to Juju 3.1

See the docs: Secret backend, How to manage secret backends, List of model configuration keys

The Juju 3.0 release delivered the first tranche of secrets functionality, primarily aimed at allowing charm developers to add secrets to their charms. In this release, the sensitive content of the secrets was stored in the Juju backend database along with the rest of the model artefacts.

In Juju 3.1 (starting with beta1), Juju admins gain the ability to use 2 new secret backends:

  • kubernetes
  • Hashicorp Vault

Here we’ll give a brief introduction to the new feature.

For machine (vm) models, the default backend will continue to be the Juju model database. For container (k8s) models, secrets will default to being stored in the model’s k8s namespace. Using a Vault backend is opt-in for any model type.

Secret backends are configured per model.

Configuring a Vault backend

The minimum information needed to configure a Vault backend is the API address and access token. These can be added to a YAML file and passed to a model.

cat > vault_config.yaml <<EOF
token: s.eujhj

juju add-secret-backend mysecrets vault \
--config=/path/to/vault_config.yaml \

Note: the initial Juju 3.1 release will very likely not initially support token rotation

All possible Vault configuration attributes are (see Vault documentation for more detail):

  • endpoint
  • namespace
  • token
  • ca-cert
  • client-cert
  • client-key
  • tls-server-name

CLI commands

We’ve seen above that the add-secret-backend command is used to add a new backend to the controller for subsequent use by hosted models. The complete set of relevant commands is:

- Add a new secret backend to the controller.
- Update an existing secret backend on the controller.
- Removes a secret backend from the controller.
- Displays the secret backends available for storing secret content.
- Displays the specified secret backend.

See juju help <commandname> for more detail on each command.

Configuring a Juju model

Each Juju Model can be configured to use a specific backend if the default is not suitable. The relevant model config attribute is secret-backend.

The out-of-the-box value for this attribute is auto, meaning that:

  • for machine models, the internal backend is used (Juju model database)
  • for k8s models, the local backend is used (k8s model namespace)

The valid values for secret-backend are:

  • internal
  • auto
  • <backend-name>

To configure a model to use a Vault backend, simply set the secret-backend config to the backend name that was added to the controller.

juju model-config secret-backend myvault

When adding a new model, if a different backend to the configured controller wide default is required:

juju add-model foo --config secret-backend=myothervault

Listing backends

Listing backends will show the backends configured on the controller and some relevant detail. For k8s models using the auto backend, we use the -local suffix with the model name to describe each backend. eg the output below includes “auto” (kubernetes) backends for two k8s models foo and bar.

	juju secret-backends
	Backend           Type        Secrets  Message
	internal          controller      134  
	foo-local         kubernetes       30
	bar-local         kubernetes       30
	myvault           vault            20  sealed

The --reveal option can be use with YAML or JSON output to show sensitive backend config like API token.

To view just a single backend in YAML format, use the show-secretbackend command.

The show-model command is enhance to include info about that model’s secret backend(s).

juju show-model
  name: admin/mymodel
  short-name: mymodel
  model-uuid: deadbeef-0bad-400d-8000-4b1d0d06f00d
  model-type: iaas
  controller-uuid: deadbeef-1bad-500d-9000-4b1d0d06f00d
  controller-name: kontroll
  owner: admin
  cloud: aws
  region: us-east-1
  type: ec2
  life: alive
	current: available
  	display-name: admin
  	access: admin
  	last-connection: just now
  	  cores: 0
  	  cores: 2
  	  status: active
	  secrets: 6
	  secrets: 5

Changing a secret backend

You may notice that the show-model output above has 2 backends shown. Once a secret backend has been configured for a model, we may want to change it to a different one. There’s 2 scenarios:

  • backend is empty or contains only orphaned revisions
  • backend contains revisions which are still being tracked

In either case, the user simply updates the model config.

juju model-config secret-backend=myothersecrets

After the switch, any new secret revisions are stored in the new backend. Existing revisions continue to be read from the old backend.

Migrating models with secrets

If a model has secrets stored in a secret backend like Vault, migrating that model to a new controller requires an extra step. The target controller must be set up to use the same (Vault) backend as is available on the source controller. This is done by running add-secret-backend on the target controller and using the import-id option to use the same internal backend ID as on the source controller.

On the source controller, inspect the backend(s) in use by the model to be migrated. The relevant backends can be discovered by running juju show-model as described earlier. For any in-use backends, use the show-secret-backend command (or just list them all with --format yaml) to see the ID of the relevant backend(s). Before running the migration, add the backend(s) to the target controller, eg

juju switch sourcecontroller
juju show-secret-backend myvault
  backend: vault
  secrets: 0
  status: active
  id: 63c8ad37c906eb278540e942

juju switch targetcontroller
juju add-secret-backend --config /path/to/backendcfg.yaml --import-id 63c8ad37c906eb278540e942

Now a migration can be run as normal and any secrets will be correctly migrated with the model.

Coming to Juju 3.2

If the old backend has secrets that are still being tracked, Juju will start a background worker to migrate current/in-use revisions to the new backend.

1 Like