Managing secrets which contain user-provided data

Some components may need a way to create an arbitrary number of secrets containing user-supplied data. See component openshift4-authentication PR#32 for an example.

It’s considered best practice that components provide a parameter secrets with value of type object. The component should render each field of the parameter as a secret in the resulting manifests.

The implementation should adhere to the following best practices:

  • The field names ("keys") of the parameter value are used as secret names.

  • The values of each field should be partial Secret resources which can be used as-is.


The component’s defaults would have an empty object secrets:

    namespace: syn-my-component
    secrets: {}

The implementation iterates over the fields of parameter secrets and merges the provided values with an empty Secret resource:

// We assume that
// * the component's parameters are available as local variable `params`.
// * kube-libsonnet is available as local variable `kube`.
// * commodore.libjsonnet is available as local variable `com`.
// We use `com.makeMergeable()` to ensure that user-provided secret values
// don't accidentally remove ``.
// To allow users to remove secrets configured higher-up in the hierarchy, we
// only generate `Secret` resources for elements of `params.secrets` which are
// non-null. Therefore the variable `secrets` will contain a mix of `Secret`
// resources and `null` entries.
local secrets = [
  if params.secrets[s] != null then
    kube.Secret(s) {
      metadata+: {
        namespace: params.namespace,
    } + com.makeMergeable(params.secrets[s])
  for s in std.objectFields(params.secrets)

  // We use Jsonnet's `std.filter()` to filter out null entries from the
  // `secrets` variable to have a clean output file.
  secrets: std.filter(function(it) it != null, secrets),

An example use of the parameter:

          verysecret: verysecretvalue (1)
1 Users are free to use Commodore secret references as values for their secrets.