Package: vault-fix
Vault-fixvault-fix is a CLI utility and python package that helps exporting and importing secrets to and fromVaultinstances.
You can use this either to load fixture files for local development (it's original purpose). Or to migrate data from
Vault instance to another, while secrets may beencryptedand/orpiped to another vault-fix instanceso the data is not persisted.Historical contextvault-fix was created to address an issue with the default mode ofVault instances in dev mode, for local development.
Vault will start with ephemeral storage, i.e. in-memory, mounting a volume will not make it persistent. If you want to
have persistent data, you'd have to provision a mount and a volume. However, this will make your local test environment
more stateful, which is not always desirable. Plus a normal Vault instance will can "seal" itself to protect itself
from attackers, which is not something you normally want to deal with during development.Instead you may want to load a known fixture, containing a curated set of secrets that you don't want to manually set
every time you restarted vault. In other words, a fixture. This allows you to start from a clean slate every time you
test or debug. You canautomate the loadingor dumping of secrets, and/or use
the CLI.Installationpipinstallvault-fixUsageFinding out how this works:vault-fix--helpUsage:vault-fix[OPTIONS]COMMAND[ARGS]...Loadordumpdata?

╭─Options───────────────────────────────────────────────────────────────────────────────────────────────────────╮
│--install-completionInstallcompletionforthecurrentshell.│
│--show-completionShowcompletionforthecurrentshell,tocopyitorcustomizetheinstallation.│
│--helpShowthismessageandexit.│
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─Commands──────────────────────────────────────────────────────────────────────────────────────────────────────╮
│dumpLoadup,anddumpsecretstoandfromVault.│
│loadLoadup,anddumpsecretstoandfromVault.│
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯Specific to dumping fixtures:vault-fixdump--helpUsage:vault-fixdump[OPTIONS]MOUNTPATHLoadup,anddumpsecretstoandfromVault.

╭─Arguments─────────────────────────────────────────────────────────────────────────────────────────────────────╮
│*mountTEXTVaultmount[default:None][required]│
│*pathTEXTVaultpathwithinthemount[default:None][required]│
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─Options───────────────────────────────────────────────────────────────────────────────────────────────────────╮
│*--token-tTEXTVaultaccesstoken.[default:None][required]│
│--host-HTEXTVaulthostname[default:localhost]│
│--port-PINTEGERVaultnetworkport.[default:8200]│
│--tls--no-tlsEnableordisableTLS[default:tls]│
│--verbose-vINTEGERSpecifyverbositylevelbypassingmore1ormore-v-vv│
│-vvv's│
│[default:0]│
│--file-fTEXTOutputfile,stdoutifnotspecified[default:-]│
│--password-pTEXTPasswordtoencryptthedumpedfixture,ornoneforplaintext│
│output.│
│--pretty--no-prettyPrettyprinttheoutput(ifJSONformatted[default:pretty]│
│--serializer[json|yaml]Whichserializerdoyouprefer?[default=yaml][default:yaml]│
│--helpShowthismessageandexit.│
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯Specific to loading fixtures:vault-fixload--helpUsage:vault-fixload[OPTIONS]MOUNTPATHLoadup,anddumpsecretstoandfromVault.

╭─Arguments─────────────────────────────────────────────────────────────────────────────────────────────────────╮
│*mountTEXTVaultmount[default:None][required]│
│*pathTEXTVaultpathwithinthemount[default:None][required]│
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─Options───────────────────────────────────────────────────────────────────────────────────────────────────────╮
│*--token-tTEXTVaultaccesstoken.[default:None][required]│
│--host-HTEXTVaulthostname[default:localhost]│
│--port-PINTEGERVaultnetworkport.[default:8200]│
│--tls--no-tlsEnableordisableTLS[default:tls]│
│--verbose-vINTEGERSpecifyverbositylevelbypassingmore1ormore-v-vv│
│-vvv's│
│[default:0]│
│--file-fTEXTInputfile,assumesstdinifnotspecified[default:-]│
│--password-pTEXTPasswordtodecryptthedumpedfixture,ornoneforplain│
│textinput.│
│--deserializer[json|yaml|auto]Whichdeserializerdoesthefixturefilerequire?│
│[default:auto]│
│--helpShowthismessageandexit.│
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ExamplesSimple dumpDump secrets from a locally running vault instance:vault-fixdumpsecret/--no-tlsDirecting outputOutput will be printed to stdout, you can specify-f FILEor direct output to a file, like:vault-fixdumpsecret/--no-tls>my-fixture.yamlEncrypting outputIf you want your secrets encrypted, pass-pto get a password prompt, or pass the password on the command line (not safe).vault-fixdumpsecret/--no-tls-pOnly secrets will be encrypted, the paths will be in plain text.JSON instead of YAMLIf you want your secrets dumped in JSON format instead of the default YAML format, pass--serializer jsonvault-fixdumpsecret/--no-tls--serializerjsonSimple loadLoad secrets from a file to a locally running vault instance:vault-fixloadsecret/--no-tls-fmy-fixture.jsonIf the fixture is encrypted, you need to pass the-pparameter, or you will get a runtime error.Directing data to the load commandLoad secrets from a file to a locally running vault instance:catmy-fixture.json|vault-fixloadsecret/--no-tls--deserializerjsonWhich brings us to this command, that allow you to migrate secrets between vault instances:vault-fixdumpsecret/-Hvault.dev.yourdomain.com|vault-fixloadsecret/--no-tlsUsing vault-fix as a Python packageOne of the best things about this utility is that you can automatically load fixtures to a local vault dev server, e.g.
during application startup.fromhvacimportClientfromvault_fix.loadimportload_fixture_from_filefromvault_fix.serializers.yamlimportyaml_deserializer# Vault docker container running on your local machine in dev mode, with ephemeral storage.# Assuming the following defaultsVAULT_ADDR="http://vault:8200"VAULT_TOKEN="root"VAULT_TLS_ENABLED=FalseVAULT_MOUNT="secret"FIXTURE_PATH="../vault_fixture_local_dev.yaml"defload_vault_secrets()->None:print(f"Attempting to import vault fixture from{FIXTURE_PATH}")client=Client(url=VAULT_ADDR,token=VAULT_TOKEN,verify=VAULT_TLS_ENABLED)try:withopen(FIXTURE_PATH,"rt")asfixture_fh:load_fixture_from_file(hvac=client,fixture=fixture_fh,mount_point=VAULT_MOUNT,deserializer=yaml_deserializer)print(f"Imported vault fixture from{FIXTURE_PATH}")exceptOSError:print(f"Can't read fixture file from{FIXTURE_PATH}")Other good to knowsThe path parameter specifies the path in the vault server you want to dump.
Or the path you would like to load to a server from the fixture file. Meaning you can select a subset of secrets to
dump or load from servers or fixtures respectively.vault-fix does not dump or import metadata, including previous versions of secrets.Hacking on this utilityCheckout the project, make a virtual env with hatch and install dependencies.gitcheckoutgit@github.com:SnijderC/vault-fix.gitcdvault-fix
pre-commitinstall
pipinstallhatch
hatchshellRunning testsIf you're in a hatch shell, exit it first, then:hatchruntest:pytestThis will test vault-fix against Python 3.9 - 3.11. If you don't have all of those, they will be skipped. You can
install them withpyenv:pyenvinstall3.93.103.11