Skip to content

Instantly share code, notes, and snippets.

@elasticdog
Created July 27, 2018 18:32
Show Gist options
  • Save elasticdog/e82f0b8e63407cbb6af69341cb9d0336 to your computer and use it in GitHub Desktop.
Save elasticdog/e82f0b8e63407cbb6af69341cb9d0336 to your computer and use it in GitHub Desktop.
A script to copy Vault secrets from one path to another
#!/usr/bin/env bash
# ensure we were given two command line arguments
if [[ $# -ne 2 ]]; then
echo 'usage: vault-cp SOURCE DEST' >&2
exit 1
fi
source=$1
dest=$2
# check for dependencies
if ! command -v jq > /dev/null; then
echo 'vault-cp: required command "jq" was not found' >&2
exit 1
fi
# check for existing values; this is ugly, but
# the `vault read` command always exits with 0
source_json=$(vault read -format=json "$source" 2>&1)
if [[ $source_json == "No value found at $source" ]]; then
echo "$source_json" >&2
exit 1
fi
source_data=$(echo "$source_json" | jq '.data')
[[ -n $DEBUG ]] && printf '%s\n' "$source_data"
dest_check=$(vault read "$dest" 2>&1 1> /dev/null)
if [[ $dest_check != "No value found at $dest" ]]; then
overwrite='n'
printf 'Destination "%s" already exists...overwrite? [y/N] ' "$dest"
read -r overwrite
# only overwrite if user explicitly confirms
if [[ ! $overwrite =~ ^[Yy]$ ]]; then
echo 'vault-cp: copying has been aborted' >&2
exit 1
fi
fi
echo "$source_data" | vault write "$dest" -
@pbatey
Copy link

pbatey commented May 1, 2020

I've refactored it to work with Vault 1.1.2 here: https://gist.github.com/pbatey/48f3dbf0d9f0695f09920f7291a6ec3d

@thomas-maurice
Copy link

FYI you can achieve the exact same result doing something like that:

vault kv get -format=json some/path/to/secret | jq .data.data > secret.json
vault kv put some/path/to/copy @secret.json

@fernando-villalba
Copy link

Awesome, this avoids having to delete the file on disk afterwards:

vault kv put kv/destination/path @<(vault kv get -format=json kv/origin/path | jq .data.data)

@blane-nelson
Copy link

You can use the -field option to extract just the data field, so you don't need jq. I'm using vault cli version 1.4.3

vault kv put kv/destination/path @<(vault kv get -format=json -field=data kv/origin/path)

@glehmann
Copy link

and you can use - to tell vault to read the data from stdin, so you can use a simple pipe:

vault kv get -format=json -field=data kv/origin/path | vault kv put kv/destination/path -

@pbchekin
Copy link

JFYI, working on a "poor man's" secrets replication for Vault: https://github.com/pbchekin/vault-sync

@alexanderankin
Copy link

preserving versions:

for i in $(vault kv metadata get -format=json $old_location | jq '.data.versions|keys|join("\n")' -r) ; do
    vault kv get -version=$i -format=json -field=data $old_location | vault kv put $new_location -; done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment