{"id":13575786,"url":"https://github.com/jonasvinther/medusa","last_synced_at":"2025-09-03T10:42:02.697Z","repository":{"id":39089561,"uuid":"314548908","full_name":"jonasvinther/medusa","owner":"jonasvinther","description":"A cli tool for importing and exporting Hashicorp Vault secrets","archived":false,"fork":false,"pushed_at":"2025-02-17T17:12:45.000Z","size":404,"stargazers_count":516,"open_issues_count":22,"forks_count":66,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-04-04T23:33:47.078Z","etag":null,"topics":["cli","go","golang","hashicorp","hashicorp-vault","secrets","vault"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jonasvinther.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"code-of-conduct.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"jonasvinther","patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2020-11-20T12:33:55.000Z","updated_at":"2025-04-03T05:53:20.000Z","dependencies_parsed_at":"2024-06-20T10:18:15.187Z","dependency_job_id":"25d77af4-0cfb-4dc3-82bc-2eb9a9d9a153","html_url":"https://github.com/jonasvinther/medusa","commit_stats":null,"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"purl":"pkg:github/jonasvinther/medusa","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonasvinther%2Fmedusa","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonasvinther%2Fmedusa/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonasvinther%2Fmedusa/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonasvinther%2Fmedusa/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jonasvinther","download_url":"https://codeload.github.com/jonasvinther/medusa/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonasvinther%2Fmedusa/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273431361,"owners_count":25104491,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-03T02:00:09.631Z","response_time":76,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","go","golang","hashicorp","hashicorp-vault","secrets","vault"],"created_at":"2024-08-01T15:01:04.181Z","updated_at":"2025-09-03T10:42:02.659Z","avatar_url":"https://github.com/jonasvinther.png","language":"Go","funding_links":["https://github.com/sponsors/jonasvinther"],"categories":["Vault","Repositories"],"sub_categories":["Tools"],"readme":"![medusa logo](https://raw.githubusercontent.com/jonasvinther/medusa/main/assets/logo/medusa-icon-240.png#gh-light-mode-only)\n![medusa logo](https://raw.githubusercontent.com/jonasvinther/medusa/main/assets/logo/medusa-icon-240-white.png#gh-dark-mode-only)\n\n\n# Medusa\n\n[![GoDoc](https://godoc.org/github.com/jonasvinther/medusa?status.svg)](https://godoc.org/github.com/jonasvinther/medusa)\n[![Go Report Card](https://goreportcard.com/badge/github.com/jonasvinther/medusa)](https://goreportcard.com/report/github.com/jonasvinther/medusa)\n[![Build status](https://github.com/jonasvinther/medusa/workflows/Go/badge.svg)](https://github.com/jonasvinther/medusa/actions)\n[![codecov](https://codecov.io/gh/jonasvinther/medusa/branch/main/graph/badge.svg)](https://codecov.io/gh/jonasvinther/medusa)\n[![CodeQL](https://github.com/jonasvinther/medusa/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/jonasvinther/medusa/actions/workflows/codeql-analysis.yml)\n\n## Table of Contents\n\n- [About](#about)\n- [Supported HashiCorp Vault versions](#supported-hashicorp-vault-versions)\n- [How to use](#how-to-use)\n  * [Setting up Medusa](#setting-up-medusa)\n  * [Importing secrets](#importing-secrets)\n  * [Exporting secrets](#exporting-secrets)\n  * [Deleting secrets](#deleting-secrets)\n  * [Decrypt secrets](#decrypt-secrets)\n  * [Kubernetes examples](docs/examples/kubernetes/cronjob/)\n  * [Docker examples](docs/examples/docker/)\n- [Secure secret management outside Vault](#secure-secret-management-outside-vault)\n- [Help](#help)\n- [How to contribute](docs/CONTRIBUTING.md)\n\n## About\nMedusa is a cli tool currently for importing and exporting a json or yaml file into HashiCorp Vault.  \nMedusa currently supports kv1 and kv2 Vault secret engines.\n\n## Supported HashiCorp Vault versions\nThe minimum required HashiCorp Vault version that is supported by Medusa is Vault version 0.10.0. Medusa has not been tested with earlier verisons than Vault version 0.10.0.\n\n## How to use\nIn this section you can read about how to configure and use Medusa.  \nYou can also watch the [Medusa 101 introduction video](https://youtu.be/ynoe3fs_YHg) to get a quick introduction on how to use Medusa for importing and exporting secrets in HashiCorp Vault.\n\n### Setting up Medusa\n#### Config file\nIt's possible to create a config file for Medusa to read in your homefolder `~/.medusa/config.yaml` that looks like this\n```\nVAULT_ADDR: https://192.168.86.41:8201\nVAULT_SKIP_VERIFY: true\nVAULT_TOKEN: 00000000-0000-0000-0000-000000000000\n```\nIf you haven't set any environment variables, or given any parameters, this file will tell Medusa where to connect, the token to use and to `VAULT_SKIP_VERIFY` should be enabled or not.\n\n#### Environment variables\nIt's also possible configure Medusa via environment variables by setting them like this:\n```\nexport VAULT_ADDR=https://192.168.86.41:8201\nexport VAULT_SKIP_VERIFY=true\nexport VAULT_TOKEN=00000000-0000-0000-0000-000000000000\n```\n\n#### Parameters\n\u003e Get help with `./medusa -h`\nYou can configure Medusa in the commands you run like this :\n```\n  -a, --address string   Address of the Vault server\n  -k, --insecure         Allow insecure server connections when using SSL\n  -t, --token string     Vault authentication token\n```\n\nUse them like this:\n```\n./medusa import secret ./test/data/import-example-1.yaml --address=\"https://0.0.0.0:8201\" --token=\"00000000-0000-0000-0000-000000000000\" --insecure\n./medusa export secret/A --address=\"https://0.0.0.0:8201\" --token=\"00000000-0000-0000-0000-000000000000\" --format=\"json\" --insecure\n```\n\n### Importing secrets\n\u003e Get help with `./medusa import -h`\n\nImport a yaml file into a Vault instance\n\nUsage:\n  medusa import [vault path] ['file' to import | '-' read from stdin] [flags]\n\n```\n  Flags:\n  -d, --decrypt              Decrypt the Vault data before importing\n  -m, --engine-type string   Specify the secret engine type [kv1|kv2] (default \"kv2\")\n  -h, --help                 help for import\n  -p, --private-key string   Location of the RSA private key\n\n  Global Flags:\n  -a, --address string       Address of the Vault server\n  -k, --insecure             Allow insecure server connections when using SSL\n  -n, --namespace string     Namespace within the Vault server (Enterprise only)\n  -t, --token string         Vault authentication token\n```\n\nExample:\n```bash\n# Read from file\n./medusa import secret ./test/data/import-example-1.yaml -a=\"https://0.0.0.0:8201\" -t=\"00000000-0000-0000-0000-000000000000\" --insecure\nSecret successfully written to Vault instance on path [/A/B/E]\nSecret successfully written to Vault instance on path [/A/Xa/Z]\nSecret successfully written to Vault instance on path [/A/F/G]\nSecret successfully written to Vault instance on path [/A/B/C/D]\nSecret successfully written to Vault instance on path [/A/B/C/D/Db]\n\n# Read from file\n./medusa import secret/folder ./test/data/import-example-1.yaml -a=\"https://0.0.0.0:8201\" -t=\"00000000-0000-0000-0000-000000000000\" --insecure\nSecret successfully written to Vault instance on path [folder/A/F/G]\nSecret successfully written to Vault instance on path [folder/A/B/C/D]\nSecret successfully written to Vault instance on path [folder/A/B/C/D/Db]\nSecret successfully written to Vault instance on path [folder/A/B/E]\nSecret successfully written to Vault instance on path [folder/A/Xa/Z]\n\n# Read from stdin\ncat ./test/data/import-example-1.yaml | ./medusa import secret -\nSecret successfully written to Vault [https://localhost:8201] using path [/A/F/G]\nSecret successfully written to Vault [https://localhost:8201] using path [/A/B/C/D]\nSecret successfully written to Vault [https://localhost:8201] using path [/A/B/C/D/Db]\nSecret successfully written to Vault [https://localhost:8201] using path [/A/B/E]\nSecret successfully written to Vault [https://localhost:8201] using path [/A/Xa/Z]\n```\n\n### Exporting secrets\n\u003e Get help with `./medusa export -h` and yaml is the default output format\nMedusa import will take a [vault path] with [flags]\n\n```\n  Flags:\n      --display-keys-only    Display only keys of secrets but not their values\n  -e, --encrypt              Encrypt the exported Vault data\n  -m, --engine-type string   Specify the secret engine type [kv1|kv2] (default \"kv2\")\n  -f, --format string        Specify the export format [yaml|json] (default \"yaml\")\n  -h, --help                 help for export\n  -o, --output string        Write to file instead of stdout\n  -p, --public-key string    Location of the RSA public key\n\n  Global Flags:\n  -a, --address string       Address of the Vault server\n  -k, --insecure             Allow insecure server connections when using SSL\n  -n, --namespace string     Namespace within the Vault server (Enterprise only)\n  -t, --token string         Vault authentication token\n```\n\nExample:\n\n```\n./medusa export secret --address=\"https://0.0.0.0:8201\" --token=\"00000000-0000-0000-0000-000000000000\" --format=\"yaml\" --insecure\nA:\n  B:\n    C:\n      D:\n        Db:\n          DBa: value 1\n          DBb: value 2\n    E:\n      Ea: value 1\n      Eb: value 2\n  F:\n    G:\n      Ga: value1\n  Xa:\n    Z:\n      Za: value 1\n      Zb: value 2\n```\n\n### Deleting secrets\n\u003e Get help with `./medusa delete -h`\nMedusa delete will take a [vault path] with [flags]\n\n```\n  Flags:\n  -y, --auto-approve         Skip interactive approval of plan before deletion\n  -m, --engine-type string   Specify the secret engine type [kv1|kv2] (default \"kv2\")\n  -h, --help                 help for import\n\n  Global Flags:\n  -a, --address string       Address of the Vault server\n  -k, --insecure             Allow insecure server connections when using SSL\n  -n, --namespace string     Namespace within the Vault server (Enterprise only)\n  -t, --token string         Vault authentication token\n```\n\nExample:\n```\n./medusa delete secret/production --address=\"https://0.0.0.0:8201\" --token=\"00000000-0000-0000-0000-000000000000\" --insecure\nDeleting secret [secret/production/users/cart/database]\nDeleting secret [secret/production/users/cart/database/users/readuser]\nDeleting secret [secret/production/users/cart/database/users/writeuser]\nDeleting secret [secret/production/users/user/database]\nDeleting secret [secret/production/users/user/database/users/readuser]\n? Do you want to delete the 25 secrets listed above? Only 'y' will be accepted to approve.? [y/N] y\nThe secrets has now been deleted\n\n\n./medusa delete secret/staging --address=\"https://0.0.0.0:8201\" --token=\"00000000-0000-0000-0000-000000000000\" --insecure --auto-approve\nDeleting secret [secret/staging/users/cart/database]\nDeleting secret [secret/staging/users/cart/database/users/readuser]\nDeleting secret [secret/staging/users/cart/database/users/writeuser]\nDeleting secret [secret/staging/users/user/database]\nDeleting secret [secret/staging/users/user/database/users/readuser]\nThe secrets has now been deleted\n```\n\n### Decrypt secrets\n\u003e Get help with `./medusa decrypt -h`\nMedusa decrypt will take a [FILE path] with [flags]\n\n```\n  Flags:\n  -p, --private-key string   Location of the RSA private key\n```\n\nExample:\n```\n# Write to stdout\n./medusa decrypt encrypted-export.txt --private-key private-key.pem\nenv:\n  dev:\n    nomad:\n      token: secret-token\n  production:\n    nomad:\n      token: secret-other-token\n\n\n# Write to file\n./medusa decrypt encrypted-export.txt --private-key private-key.pem \u003e plaintext-export.yaml\n```\n\n### Encrypt secrets\n\u003e Get help with `./medusa encrypt -h`\nMedusa encrypt will take a [FILE path] with [flags]\n\n```\n  Flags:\n  -o, --output string       Write to file instead of stdout\n  -p, --public-key string   Location of the RSA public key\n```\n\nExample:\n```\n# Write to stdout\n./medusa encrypt plaintext-export.txt --public-key public-key.pem\n\u0026lt;Encrypted data\u0026gt;\n\n# Write to file\n./medusa encrypt plaintext-export.txt --public-key public-key.pem --output encrypted-export.txt.b64\n```\n\n## Secure secret management outside Vault\nMedusa will help you securely manage your secrets outside Vault.\nThis could for instance be as a backup of your Vault data or while your secrets are being transported between Vault instances.  \nMedusa uses a hybrid encryption solution in order to keep your secrets safe.  \n\n### Key generation\nWhen exporting your Vault secrets using Medusa, the secrets are encrypted using the AES symmetric encryption algorithm. The 256-bit AES encryption key is randomly generated by Medusa every time the export command is being called.  \nThen the AES key is encrypted by the provided RSA public key and then stored together with the encrypted secrets.  \nThis ensures that both the exported secrets and AES enctyption key can be transfered safely between Vault instances.  \nThe exported secrets and AES enctyption key can only be decrypted by a person who is in possession of the RSA private key.\n\nThe RSA key-pair can be generated by the following two commands:\n``` bash\n# Generate private key\nopenssl genrsa -out private-key.pem 4096\n\n# Generate public key\nopenssl rsa -in private-key.pem -pubout -out public-key.pem\n```\n\n### Exporting and encrypting Vault secrets\nEncrypting your Vault export is easy using Medusa. Simply add the following two flags to your command:\n\n```\n-e, --encrypt bool       Encrypt the exported Vault data [true/false]\n-p, --public-key string  Location of the RSA public key\n```\n\nUse them like this:\n``` bash\n./medusa export kv --address=\"https://my-vault-server.com\" --token=\"00000000-0000-0000-0000-000000000000\" --insecure --encrypt=\"true\" --public-key=\"public-key.pem\" --output=\"encrypted-vault-secrets.txt\"\n```\n\n### Importing and decrypting Vault secrets\nDecrypting and importing your encrypted Vault export can be done by adding the following two flags to your command:\n\n```\n-d, --decrypt bool        Decrypt the Vault data before importing [true/false]\n-p, --private-key string  Location of the RSA private key\n```\n\nUse them like this:\n``` bash\n./medusa import kv encrypted-vault-secrets.txt --address=\"https://my-vault-server.com\" --token=\"00000000-0000-0000-0000-000000000000\" --insecure --decrypt=\"true\" --private-key=\"private-key.pem\"\n```\n\n## Help\nTo test out `medusa` on your laptop\n```\nMedusa is a cli tool currently for importing a json or yaml file into HashiCorp Vault.\nCreated by Jonas Vinther \u0026 Henrik Høegh.\n\nUsage:\n  medusa [command]\n\nAvailable Commands:\n  completion  Generate the autocompletion script for the specified shell\n  decrypt     Decrypt an encrypted Vault output file into plaintext in stdout\n  delete      Recursively delete all secrets below the given path\n  encrypt     Encrypt a Vault export file onto stdout or to an output file\n  export      Export Vault secrets as yaml\n  help        Help about any command\n  import      Import a yaml file into a Vault instance\n  version     Print the version number of Medusa\n\nFlags:\n  -a, --address string                Address of the Vault server\n  -h, --help                          help for medusa\n  -k, --insecure                      Allow insecure server connections when using SSL\n      --kubernetes                    Authenticate using the Kubernetes JWT token\n      --kubernetes-auth-path string   Authentication mount point within Vault for Kubernetes\n  -n, --namespace string              Namespace within the Vault server (Enterprise only)\n  -r, --role string                   Vault role for Kubernetes JWT authentication\n  -t, --token string                  Vault authentication token\n\nUse \"medusa [command] --help\" for more information about a command.\n``` \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonasvinther%2Fmedusa","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjonasvinther%2Fmedusa","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonasvinther%2Fmedusa/lists"}