hashicorp/envconsul

Support for getting a subset of a secret's key

stephenash opened this issue · 5 comments

My team has some key/value secrets that look something like this:

services
  /app-a
    /mysql-database
      username=...
      password=...
      secret-contact=...
      update-instructions=...
      comment=...

Many of those keys are not required for the runtime to function, but are there for the benefit of the humans interacting with the secrets. Would it possible to only get some of the keys for a path set into the environment?

I don't really expect the below config example to work with v0.9.2. The #key-name syntax comes from https://github.com/channable/vaultenv instead of what is documented by this project.

Envconsul version

envconsul -v
 v0.9.2 ()

Configuration

secret {
  no_prefix = true
  path = "services/app-a/mysql-database#username"
  format = "MYSQL_DATABASE_USERNAME"
}

secret {
  no_prefix = true
  path = "services/app-a/mysql-database#password"
  format = "MYSQL_DATABASE_PASSWORD"
}

upcase = true

Command

envconsul -config config.hcl env
MYSQL_DATABASE_USERNAME=<value of #update-instructions key>
MYSQL_DATABASE_PASSWORD=<value of #update-instructions key>

hi @stephenash,
the services/app-a/mysql-database#username syntax is not quite possible, since the code that parses this path resides in consul-template codebase.

I have implemented quick PoC to support this syntax:

secret {
  no_prefix = true
  path = "secret/app-a/mysql-database"
  format = "MYSQL_DATABASE_SERVER"
  field = "host"
}

secret {
  no_prefix = true
  path = "secret/app-a/mysql-database"
  format = "MYSQL_DATABASE_USER"
  field = "user"
}

the issue is that only MYSQL_DATABASE_USER variable will be in the final env map because format is applied to all keys in the list of secrets and they got overridden by the last one.

@eikenb I am wondering if it is good idea to extend secrets syntax so it could look like:

secret {
  no_prefix = true
  path = "secret/app-a/mysql-database"
  format = "MYSQL_DATABASE_{{ key }}"
  fields = ["host", "user"]
}

or with per-field format support:

secret {
  no_prefix = true
  path = "secret/app-a/mysql-database"
  format = "MYSQL_DATABASE_{{ key }}"
  fields = ["host", "user", "password"]
  fieldFormats {
      host = MYSQL_DATABASE_SERVER
      user = MYSQL_DATABASE_USERNAME
  }
}
cpl commented

Is there any fork/pr/repo/.. where this can be tracked and contributed to?

I find this useful for services/app-a/prod services/app-a/dev type configurations. Where the values live as HCL/JSON inside the prod or dev keys. Or any clustering by "concern" in general.

@stephenash @cpl just added a #259 with basic functionality.

I would love to hear a feedback from you if it solves the issue.

cpl commented

I'll give it a try today or tommrow and will come back with feedback. Thank you!

I'm looking forward to seeing your feedback as well @cpl. Thanks!