These tools allow for simple interactions with the vault API, allowing configuration to be done in a separate step using a YAML configuration file.
This is especially interesting if you interact with Hashicorp Vault from automated deployment tools.
Installation
pip install
vault-cli
Vault-cli only works with Python 3.6 and later.
Usage Usage
: vault [OPTIONS] COMMAND [ARGS]… Interact with a vault. See the subcommands for more information. All arguments can be passed by environment variables: VAULT_CLI_UPPERCASE_NAME (including VAULT_CLI_PASSWORD and VAULT_CLI_TOKEN). Options: -U, -url TEXT Store instance URL -verify / -no-verify Verify HTTPS certificate -ca-bundle PATH The location of the package that contains the server certificate to verify against. -login-cert PATH A path to a public client certificate that will be used to connect to the store. -login-cert-key PATH A path to a private client certificate that will be used to connect to the store. -T, -token-file PATH File that contains the token to connect to the Vault. The configuration file can also contain a “token” key. -u, -username TEXT Username used for userpass authentication -w, -password-file PATH It can read from stdin if “-” is used as a parameter. The configuration file may also contain a “password” key. -b, -base-path TEXT Base path for requests -s, -safe-write / -unsafe-write When enabled, you cannot overwrite a secret without passing “-force” (in the “set”, “mv”, etc. commands) -render / -no-render Render template values -v, -verbose Use multiple times to increase verbosity -config-file PATH configuration file to use. Use ‘no’ to disable the configuration file. Default: ./vault.yml first, ~/.vault.yml, /etc/vault.yml -V, -version -h, -help Show this message and exit. Commands: delete Delete a single secret. delete-all Delete multiple secrets. dump-config Display the configuration in the format of a configuration file. env Launch a command, loading secrets into the environment. get Return a single secret value. get-all Returns multiple secrets. List List all the secrets in the given path. lookup-token Returns information about the current mv token Move secrets recursively from the source path to the destination path. set Set a secret. template Renders the given template and inserts secrets into it.
Authentication
There are three ways to authenticate
to the vault: User name and password file
- : Provide a user name and a file to read the password. The file can be – for stdin.
- Client certificate: Provides the path to a certificate file.
- Token: Skip the authentication step if you already have a valid token.
Showcase
Connect to https://vault.mydomain:8200/project and list the secrets
$ vault -url=https://vault.mydomain:8200 -certificate=/etc/vault/certificate.key -base-path=project/ list [‘my_secret’]
In the following examples, we will consider that we have a complete configuration file.
Read a secret in plain text (default) $ vault get my_secret qwerty value
Read a secret in
yaml format $ vault get –
yaml
my_secret value – qwerty …
Write
a secret value from $ vault set my_other_secret value=supersecret Done ##
# Read/write a secret outside the base path If a base path is defined, it will be prepended to all paths used by vault-cli, except when the paths start with a forward slash (/), those are absolute paths.
$ export VAULT_CLI_BASE_PATH=secretkvv1/myapp/ $ vault set mysecret value=sharedsecret Done $ vault get mysecret value sharedsecret $ vault get /secretkvv1/myapp/mysecret value sharedsecret $ unset VAULT_ CLI_BASE_PATH Write a secret
via stdin.
You can use this when the secret has multiple lines or starts with a vault set
“-” $ third_secret certificate=- -BEGIN SECRET KEY- … < press ctrl + d to end stdin> Vault done get third_secret -BEGIN SECRET KEY- …
Identically, the pipeline allows you to write the contents of a file to the vault:
$ cat my_certificate.key | vault set third_secret certificate=- Done
You can also upload a key/value mapping
in yaml or JSON format from a file: $ vault set third_secret -file=secret.yaml Done A special value of “-
” for -file means that the file is read from stdin
. Write a secret
using an invisible input message
This will prevent your secrets from being displayed in plain text in your shell history.
$ vault set mypath -prompt mykey Enter a value for the ‘mykey’ key of ‘mypath’: Donate Anything following “-”
won’t look like a flag, even if it starts with a
vault set $”-” – -secret-name -oh-so-secret=xxx Done $vault get – -secret-name – -oh-so-secret: xxx
Protect yourself from overwriting a secret by mistake
vault set a value=b Done $ vault -safe-write set a value=c Error: The secret already exists in a. Use -f to force overwrite. $ vault -safe-write set -f a value=c Done (
safe-write can be set in your configuration file, see details below
) Get all vault
values in one command (yaml format) $ vault get-all
– -secret-name: -oh-so-secret: xxx a: value: c my_other_secret: value: supersecret third_secret: certificate: ‘-BEGIN SECRET KEY- … ‘ get a
nested secret based on a path
$ vault set test/my_folder_secret secret=yay Done $ vault get-all test/my_folder_secret – test: my_folder_secret: secret: yay $ vault get-all -flat test/my_folder_secret – test/my_folder_secret: secret: yay
Get all values recursively from multiple folders in a single command (yaml format)
$ vault get-all test my_secret – my_secret: Value: QWERTY Test: my_folder_secret: Secret: Yay $ vault get-all -flat test my_secret – my_secret: Value: qwerty test/my_folder_secret: secret: yay
Delete a
secret vault from $ delete my_other_secret Done Move
secrets and folders
$ vault mv my_secret test/my_secret Move ‘my_secret’ to ‘test/my_secret’ $ vault get-all -flat -secret-name: -oh-so-secret: xxx to: value: c test/my_folder_secret: secret: yay test/my_secret: value: qwerty third_secret: certificate: ‘-BEGIN SECRET KEY- … ‘
Launch a process by loading secrets via environment variables
$ vault env -path test/my_secret – env … MY_SECRET_VALUE=qwerty … $ vault set foo/bar/service/instance/main dsn=proto://xxx $ vault env -path test/my_secret:value=MYVAL -path foo/bar/service/instance/main=my – env … MYVAL=qwerty MY_DSN=proto://xxx …
Render a
template file with vault values $ vault set my_secret username=John password=qwerty Done $ vault template mytemplate.j2 > /etc/conf # mytemplate.j2: User={{ vault(“my_secret”).username }} Password={{ vault(“my_secret”).password }} # /etc/conf: User=John Password=qwerty
(Use – for stdin and -o <file or -> to specify the file to write to, or stdout).
(Re)create a configuration file based on the current configuration
$ vault -url https://something -token mytoken dump-config > vault.yaml Delete all under blob-secret $ vault delete-all
blob-secret Delete
all
, no confirmation
$ vault delete-all -force
Create a value with
template $ vault set path/to/my/service password=foo $ vault set shortcut dsn=’!template!proto://username:{{ vault(“path/to/my/service”).password }}@host/’ $ vault get shortcut dsn proto://username:foo@host/$ vault -no-render get shortcut dsn !template!proto://username:{{ vault(“path/to/my/service”).password }}@host/
The vault function does not render variables recursively
.
Learn about your current
token $vault lookup-token
Use the test client in tests
$ pip install vault-cli[testing] # conftest.py (for pytest) from vault_cli.testing import vault __all__ = [“vault”] # test_something.py def test_bla(vault): vault.db = {“a/b”: “c”} assert vault.get_secret(“a/b”) == “c”
Settings
The
first file found in the following location is read, analyzed, and used:
/etc/vault.yml ~/.vault.yml .
- /vault.yml
Any option passed as a command line prompt will be used over the corresponding option in the documentation (use – or _).
The expected format of the configuration is a mapping, with option names and their corresponding values
: – username: my_username password file: ~/.vault-password # or token-file: ~/.vault-token url: https://vault.mydomain:8200 verify: no base-path: project/ …
Make sure that secret files have their permissions set accordingly.
For simple cases, you can directly define your token or password in the file
: – username: my_username password: secret-password # or token: secret-token url: https://vault.mydomain:8200 verify: no base-path: project/ …
If you do, make sure that the permissions in the configuration file itself are not too broad.
Just note that the -verify
/-no-verify flag becomes verify: yes or verify: no
All parameters can be defined from environment variables:
$ VAULT_CLI_URL=https://myvault.com list of vaults
The name is always the uppercase underlined name of the equivalent command-line option. The token and password can also be passed as environment variables such as VAULT_CLI_TOKEN and VAULT_CLI_PASSWORD.
Update
1.0
This release includes some important changes to managing key-value assignments. In previous versions of vault-cli, there was an implicit key value that was used everywhere. The goal was to provide a path < > value abstraction. But I was hiding the path < > reality of Vault’s kv engine key/value mapping.
In this release we removed the implicit key ̀value to expose a key/value mapping instead of a single value. Most commands have been updated to add the key parameter.
Added a new -omit-single-key option to vault env to ignore the key when variable names are created and there is only one key in the mapping. This option scenario simplifies the migration because an additional _VALUE suffix will not be added to the names of the environment variables.
The following list shows how to update the commands
: (old) vault set path/to/creds xxx (new) vault set path/to/creds value=xxx (old) vault get path/to/creds (new) vault get path/to/creds value (old) vault env -path path/to/creds=FOO – env # FOO=xxx (new) vault env -path path/to/creds=FOO – env # FOO_VALUE=xxx (new) vault env -path path/to/creds: value=FOO – env # FOO=xxx The default result of vault get-all
has also changed and is now flat by default (this behavior is controlled by the
-flat/-no-flat flags). $ vault set a/b secret=xxx $ vault set a/c secret=xxx $ vault get-all a – a/b: secret: xxx a/c: secret: xxx $ vault get-all -no-flat a – a: b: secret: xxx c: secret: xxx
SystemD integration
See the dedicated document
.
Troubleshooting
syntax
issuesError: Invalid syntax
You are most likely using Python 3.5 or earlier (including Python 2)
Status
The tool is currently in beta mode. It lacks documents and other things. Be careful.
Contributing
We appreciate any help 🙂 See CONTRIBUTING.md for details.
License Copyright 2018-2019 PeopleDoc
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of
the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, the software distributed under the License is distributed “AS IS” WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Please refer to the License for the specific language governing the permissions and limitations of the License.