Skip to content

A tool to copy Vault KV v2 secrets from one location to another location, even across Vault instances

Notifications You must be signed in to change notification settings

karuppiah7890/vault-kv-cp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

vault-kv-cp

Building

go build -v

Usage

$ ./vault-kv-cp
usage: vault-kv-cp <source-kv-mount-path> <destination-kv-mount-path>

Demo

Source Vault, secured with HTTPS and a big token. It has some secrets - with one secret having many versions (3 versions)

$ vault secrets list
Path          Type         Accessor              Description
----          ----         --------              -----------
cubbyhole/    cubbyhole    cubbyhole_b8f3ed6a    per-token private secret storage
identity/     identity     identity_e3c8f173     identity store
secret/       kv           kv_86bfa42e           Generic secret storage
sys/          system       system_9a2cc83b       system endpoints used for control, policy and debugging

$ vault kv list
Not enough arguments (expected 1, got 0)

$ vault kv list secret
Keys
----
demosecret/
something/

$ vault kv list secret/demosecret
Keys
----
aws

$ vault kv list secret/demosecret/aws
No value found at secret/metadata/demosecret/aws

$ vault kv get secret/demosecret/aws
======= Secret Path =======
secret/data/demosecret/aws

======= Metadata =======
Key                Value
---                -----
created_time       2024-03-21T15:22:17.814449057Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            3

============ Data ============
Key                      Value
---                      -----
AWS_SECRET_ACCESS_KEY    s3cr3t
PASSWORD                 somePasswordHere
TOKEN                    blah

$ vault kv list secret/
Keys
----
demosecret/
something/

$ vault kv list secret/something
Keys
----
else/

$ vault kv list secret/something/else
Keys
----
wow

$ vault kv list secret/something/else/wow
No value found at secret/metadata/something/else/wow

$ vault kv get secret/something/else/wow
========= Secret Path =========
secret/data/something/else/wow

======= Metadata =======
Key                Value
---                -----
created_time       2024-03-21T15:22:02.034111335Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

============ Data ============
Key                      Value
---                      -----
AWS_SECRET_ACCESS_KEY    lol
PASSWORD                 somePasswordHere
TOKEN                    SECRETIVE_API_TOKEN_HERE

Destination Vault, local dev Vault server, with no HTTPS, with token as root

$ export VAULT_TOKEN="root"

$ export VAULT_ADDR='http://127.0.0.1:8300'

$ vault status
Key             Value
---             -----
Seal Type       shamir
Initialized     true
Sealed          false
Total Shares    1
Threshold       1
Version         1.15.4
Build Date      2023-12-04T17:45:28Z
Storage Type    inmem
Cluster Name    vault-cluster-7bc4c9ee
Cluster ID      fee68bf6-8eff-4cfd-bdab-abd6ef1b3282
HA Enabled      false

$ vault secrets list
Path          Type         Accessor              Description
----          ----         --------              -----------
cubbyhole/    cubbyhole    cubbyhole_e433e0c2    per-token private secret storage
identity/     identity     identity_0e7a4812     identity store
secret/       kv           kv_8e374477           key/value secret storage
sys/          system       system_271e70ee       system endpoints used for control, policy and debugging

$ vault kv list
Not enough arguments (expected 1, got 0)

$ vault kv list secret
No value found at secret/metadata

Now, let's copy from source to destination :) The latest version of the secrets gets copied from the source to the destination. Any secrets in the destination is overwritten

$ export SOURCE_VAULT_ADDR='https://127.0.0.1:8200'

$ export SOURCE_VAULT_CACERT=$PWD/vault-ca.crt

$ export SOURCE_VAULT_TOKEN="big-token-here"

$ export DESTINATION_VAULT_ADDR='http://127.0.0.1:8300'

$ export DESTINATION_VAULT_TOKEN="root"

$ ./vault-kv-cp secret secret
&{RequestID:0c9f6194-fcfb-c332-8f2e-fe70cd80afc1 LeaseID: LeaseDuration:0 Renewable:false Data:map[keys:[demosecret/ something/]] Warnings:[] Auth:<nil> WrapInfo:<nil> MountType:}

&{RequestID:61e18f2b-b471-6c34-28ab-069ecf5cc4a3 LeaseID: LeaseDuration:0 Renewable:false Data:map[keys:[aws]] Warnings:[] Auth:<nil> WrapInfo:<nil> MountType:}

copying secret at `demosecret/aws` in source to `secret` in destination

&{RequestID:5e67e48c-e8ac-c733-b3af-462d8dcd2bb0 LeaseID: LeaseDuration:0 Renewable:false Data:map[keys:[else/]] Warnings:[] Auth:<nil> WrapInfo:<nil> MountType:}

&{RequestID:66144652-3f84-876c-0fc2-bad5dcac6ba5 LeaseID: LeaseDuration:0 Renewable:false Data:map[keys:[wow]] Warnings:[] Auth:<nil> WrapInfo:<nil> MountType:}

copying secret at `something/else/wow` in source to `secret` in destination


$ vault kv list secret
Keys
----
demosecret/
something/

$ vault kv list secret/demosecret
Keys
----
aws

$ vault kv list secret/demosecret/aws
No value found at secret/metadata/demosecret/aws

$ vault kv get secret/demosecret/aws
======= Secret Path =======
secret/data/demosecret/aws

======= Metadata =======
Key                Value
---                -----
created_time       2024-03-21T15:34:02.203551Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

============ Data ============
Key                      Value
---                      -----
AWS_SECRET_ACCESS_KEY    s3cr3t
PASSWORD                 somePasswordHere
TOKEN                    blah

$ vault kv list secret/
Keys
----
demosecret/
something/

$ vault kv list secret/something
Keys
----
else/

$ vault kv list secret/something/else
Keys
----
wow

$ vault kv list secret/something/else/wow
No value found at secret/metadata/something/else/wow

$ vault kv get secret/something/else/wow
========= Secret Path =========
secret/data/something/else/wow

======= Metadata =======
Key                Value
---                -----
created_time       2024-03-21T15:34:02.800351Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

============ Data ============
Key                      Value
---                      -----
AWS_SECRET_ACCESS_KEY    lol
PASSWORD                 somePasswordHere
TOKEN                    SECRETIVE_API_TOKEN_HERE

$ ### Now let's overwrite the secrets in the destination by doing the copy again :)

$ ./vault-kv-cp secret secret
&{RequestID:a5915878-ca1e-2308-3dbe-f589dfaa3e28 LeaseID: LeaseDuration:0 Renewable:false Data:map[keys:[demosecret/ something/]] Warnings:[] Auth:<nil> WrapInfo:<nil> MountType:}

&{RequestID:1fa5911a-bfc2-6d9f-3b1d-df0a9061467d LeaseID: LeaseDuration:0 Renewable:false Data:map[keys:[aws]] Warnings:[] Auth:<nil> WrapInfo:<nil> MountType:}

copying secret at `demosecret/aws` in source to `secret` in destination

&{RequestID:66ab418d-e953-f72f-021b-d1c238ff72af LeaseID: LeaseDuration:0 Renewable:false Data:map[keys:[else/]] Warnings:[] Auth:<nil> WrapInfo:<nil> MountType:}

&{RequestID:2e20953a-a0b2-cea6-4745-3285c3f0a938 LeaseID: LeaseDuration:0 Renewable:false Data:map[keys:[wow]] Warnings:[] Auth:<nil> WrapInfo:<nil> MountType:}

copying secret at `something/else/wow` in source to `secret` in destination


$ vault kv get secret/something/else/wow
========= Secret Path =========
secret/data/something/else/wow

======= Metadata =======
Key                Value
---                -----
created_time       2024-03-21T15:35:39.809718Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            2

============ Data ============
Key                      Value
---                      -----
AWS_SECRET_ACCESS_KEY    lol
PASSWORD                 somePasswordHere
TOKEN                    SECRETIVE_API_TOKEN_HERE

Future Ideas

  • Enable KV v2 Secrets Engine in the destination Vault in the given destination mount path if it doesn't exist
  • Copy KV v2 Secrets Engine configuration from source to destination

About

A tool to copy Vault KV v2 secrets from one location to another location, even across Vault instances

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published