Vault

Vault is a secrets store created by HashiCorp.

It's convenient to store credentials for a servers/services infrastructure.


DcK I'm currently working on a Vault TCL client, probably to integrate to tcllib when more features are added: vault.tcl

Currently allows to login through AppRole with roleID and secretID and fetch a credential from KV v2.

::vault::readKV returns a dictionary with your credentials data ("data"), the Vault metadata ("metadata"). Since Vault 1.9 it's possible to store custom metadata, it's available in metadata under the custom_metadata key.

For oneshot configuration, the workflow is straighforward:

  1. connect using ::vault::init and ::vault::appRoleLogin
  2. fetch credentials with ::vault::readKV

If you need to do so during the application lifecycle, the token can expire and you need to relogin:

package require vault

proc vault_login {} {
    global vault

    ::vault::init $vault(host)
    ::vault::appRoleLogin $vault(roleID) $vault(secretID)
}

proc vault_get {property {key {}}} {
    if {[catch {set credential [::vault::readKV secrets/$property $key]} err]} {
        if {[string match "*403 Forbidden*" $err]} {
            # Token expired?
            vault_login
            return [::vault::readKV secrets/$property $key]
        }
    }

    return $credential
}

In your software config, build a vault array then call vault_login:

set vault(host) localhost:8200
set vault(roleID) 00000000-0000-0000-0000-000000000000
set vault(secretID) 00000000-0000-0000-0000-000000000000

vault_login

And each time you need a credential, call vault_get to read the secret:

set sql_credentials [dict get [vault_get mysql] data]
sql connect somehost [dict get $sql_credentials username] [dict get $sql_credentials password]