Discussions¶
Contents
Why not vault, hvac or hvac-cli?¶
We are aware of the following “competitor” products:
The official
vault
executable can be used as avault
clientThe hvac (Hashicorp VAult Client) Python library which is a wrapper around requests implementing the
vault
HTTP APIThe hvac-cli library
envconsul which supports providing configuration values from consul and
vault
into environment variables
At its core, vault-cli
want to provide:
A simple configuration-file workflow
Helps for 12 factors integrations.
We felt that no tool was doing what we wanted and was accepting contribution that lead to what we were looking for, so that why we created our own.
12 factors¶
12-factor applications are centered around having the application process communicate with the outside solely through abstract and decoupled ways, allowing concrete integration choices to vary wildly without impacting the application code. This includes, among very different thing:
Reading all configuration through environment variables
Connect to any external service using exposed configuration
Logging through stdout
…
vault-cli
shines when used as a layer between your process manager (SystemD,
Docker, …) and your application, to make your secrets accessible by your
application in a reasonably decoupled way.
Environment variables¶
Environment variables are a set of variables provided to a process at launch time, with the following properties:
Environment variables names are usually uppercase ascii with underscores. Other characters can be supported by some operating systems, but
vault-cli
limits to this setEnvironment variables are inherited from the parent process, who has complete control on whether values are transmitted from its own process, removed, or if new values are added. By default, subprocesses inherit their parent process’ whole environment.
Environment variables are text only. Any other type must be parsed from text. There is no standard way to represent boolean values.
Environment and the command-line string are the two main decoupled ways of providing context to a process. Any other way involves agreeing on a less standard method, including reading the file at a specific path, etc.
Because they are a standard way to give parameters to a process, environment variables can be used by that process with zero knowledge of the deployment specifics.
That being said, there is a debate on whether using secrets for environment variables is safe or not. Here are a few common arguments from both sides:
Pros¶
Simple, standard
Avoid writing secrets on disk
OS naturally ensures that only the process user and root can read the environment of a running process
When following good practice, it doesn’t increase the attack surface. The risks are the same as with any other secret strategy
Cons¶
Because environment variables are automatically transmitted to children processes, and sometimes dumped for debug purposes, putting secrets in there raises the risk of leaking secrets
The information of whether the value from an environment variable is secret or not can be implicit in the app, leading to mishandling
Environment can be read on Linux at
/proc/[pid]/environ
.
Good practice to address the “Cons”¶
Once a secret value is read from the environment variable, it should be removed from the in-memory environment. This will keep the value from being transmitted to children processes, dumped or sent. This does nothing to
/proc/[pid]/environ
though, because this file contains the initial process. But if an attacker can access that file, they can also access the process’ memory pages and read the secrets in the process memory directly.It’s the application source code’s role to very explicitely point our what values are secret. This is true when secrets are read from the environment, as well as from anywhere. You can tie together explicitating the secret nature of a configuration variable and scrubbing it from the environment.
It’s no surprise that, while recognizing the value of the “Cons” argument, we think the benefits of using secret values in environment outweight the risks.
For more information on how to use environment variables within vault-cli
, see
Launch a process with your secrets as environment variables
Avoid writing secrets to the disk¶
Even in the era of of encrypted drives, we believe it is interesting to set the goal of avoiding to write secrets on the disk, for multiple reasons:
It’s harder to control who reads a file than who access a
vault
. There is no simple audit log allowing you to know who accessed a file.Writing secrets on the disk caches the information, which now exists both in the vault and on the disk. Cache invalidation is no easy task.
This relies on having your disks encrypted, which is often something you can’t control as easily as choosing the right UNIX user, group and mode.
That being said, this does apply to physical disks but not necessarily to any filesystem. As long as proper user management is done to ensure only the right users can access the mount, in-memory filesystems (Ram disks / tmpfs) poses no specific risks.
See Integrate with SystemD for strategies on how to avoid writing on disk when your application must read secrets from a file system.
kv v1
and kv v2
, secret engines¶
vault
offers several secret engines, including 2 iterations (v1 and v2) of a general
purpose key/value (kv) store.
vault-cli
supports v1
for now, but plans to support v2
in the future.
kv v2 adds a few interesting features:
Versionned secrets (which help solve the rotation problem)
Time to live, forcing you to rotate secrets regularily
vault
also offers a variety of secret engines, allowing
you to generate secrets in you vault
directly. vault-cli
currently doesn’t
include specific integrations for those engines, but this is envisionned.
Secret objects and the implicit value
key¶
In vault
and especially kv v1
, a secret is a JSON object (or mapping). Its
content can be any JSON value (strings, arrays, objects, …). On the early days of
vault-cli
before 1.0.0
, because most secrets were strings, a design decision had
been made to not expose the whole secret object, but only its value
key. This proved
simpler for basic use-cases, but quickly turned very problematic and confusing when
working with non-kv v1
secret engines or with users of other vault clients.
We backed off this decision on 1.0.0
and made the key explicit on every subcommand.
vault-cli env/ssh
& UNIX signals¶
When using vault-cli env
or vault-cli ssh
, vault-cli
is responsible for
launching your process. You may wonder if there is a risk that vault-cli
would not
forward signals correctly, which might be the case if your process was a child process
of vault-cli
.
Actually, vault-cli
will prepare everything it needs and then use exec, which
replace vault-cli
’s own process with your process, removing vault-cli
from the
equation entirely. The risk is then far lower to have vault-cli
cause a problem to
your process.
Thanks PeopleDoc¶
This project was almost entirely created by PeopleDoc employees on their working time. Let’s take this opportunity to thank PeopleDoc for funding an Open Source project like this!
If this makes you want to know more about this company, check our website or our job offerings !