{"id":17217592,"url":"https://github.com/lrstanley/vault-unseal","last_synced_at":"2025-05-16T09:03:17.180Z","repository":{"id":33986372,"uuid":"154544393","full_name":"lrstanley/vault-unseal","owner":"lrstanley","description":"auto-unseal utility for Hashicorp Vault","archived":false,"fork":false,"pushed_at":"2025-04-29T08:41:07.000Z","size":261,"stargazers_count":258,"open_issues_count":19,"forks_count":35,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-29T09:42:42.135Z","etag":null,"topics":["auto-unseal","cli","go","golang","hashicorp","unseal","unseals-vault-servers","vault","vault-api","vault-unseal"],"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/lrstanley.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":".github/SECURITY.md","support":".github/SUPPORT.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"lrstanley"}},"created_at":"2018-10-24T17:51:27.000Z","updated_at":"2025-04-29T08:41:10.000Z","dependencies_parsed_at":"2023-12-30T04:20:01.550Z","dependency_job_id":"aeb715c3-3a3b-4075-b0b2-78151662eccb","html_url":"https://github.com/lrstanley/vault-unseal","commit_stats":{"total_commits":195,"total_committers":8,"mean_commits":24.375,"dds":"0.33333333333333337","last_synced_commit":"6de7b79a1a305ac5038a344cee441c0226cc519a"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lrstanley%2Fvault-unseal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lrstanley%2Fvault-unseal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lrstanley%2Fvault-unseal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lrstanley%2Fvault-unseal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lrstanley","download_url":"https://codeload.github.com/lrstanley/vault-unseal/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254501555,"owners_count":22081528,"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","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":["auto-unseal","cli","go","golang","hashicorp","unseal","unseals-vault-servers","vault","vault-api","vault-unseal"],"created_at":"2024-10-15T03:44:21.999Z","updated_at":"2025-05-16T09:03:17.148Z","avatar_url":"https://github.com/lrstanley.png","language":"Go","funding_links":["https://github.com/sponsors/lrstanley"],"categories":[],"sub_categories":[],"readme":"\u003c!-- template:define:options\n{\n  \"nodescription\": true\n}\n--\u003e\n![logo](https://liam.sh/-/gh/svg/lrstanley/vault-unseal?bg=topography\u0026icon=file-icons%3Ahashicorp\u0026icon.height=65\u0026icon.color=rgba%280%2C+184%2C+126%2C+1%29)\n\n\u003c!-- template:begin:header --\u003e\n\u003c!-- do not edit anything in this \"template\" block, its auto-generated --\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/lrstanley/vault-unseal/releases\"\u003e\n    \u003cimg title=\"Release Downloads\" src=\"https://img.shields.io/github/downloads/lrstanley/vault-unseal/total?style=flat-square\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/lrstanley/vault-unseal/tags\"\u003e\n    \u003cimg title=\"Latest Semver Tag\" src=\"https://img.shields.io/github/v/tag/lrstanley/vault-unseal?style=flat-square\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/lrstanley/vault-unseal/commits/master\"\u003e\n    \u003cimg title=\"Last commit\" src=\"https://img.shields.io/github/last-commit/lrstanley/vault-unseal?style=flat-square\"\u003e\n  \u003c/a\u003e\n\n\n\n\n  \u003ca href=\"https://github.com/lrstanley/vault-unseal/actions?query=workflow%3Atest+event%3Apush\"\u003e\n    \u003cimg title=\"GitHub Workflow Status (test @ master)\" src=\"https://img.shields.io/github/actions/workflow/status/lrstanley/vault-unseal/test.yml?branch=master\u0026label=test\u0026style=flat-square\"\u003e\n  \u003c/a\u003e\n\n\n\n  \u003ca href=\"https://codecov.io/gh/lrstanley/vault-unseal\"\u003e\n    \u003cimg title=\"Code Coverage\" src=\"https://img.shields.io/codecov/c/github/lrstanley/vault-unseal/master?style=flat-square\"\u003e\n  \u003c/a\u003e\n\n  \u003ca href=\"https://pkg.go.dev/github.com/lrstanley/vault-unseal\"\u003e\n    \u003cimg title=\"Go Documentation\" src=\"https://pkg.go.dev/badge/github.com/lrstanley/vault-unseal?style=flat-square\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://goreportcard.com/report/github.com/lrstanley/vault-unseal\"\u003e\n    \u003cimg title=\"Go Report Card\" src=\"https://goreportcard.com/badge/github.com/lrstanley/vault-unseal?style=flat-square\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/lrstanley/vault-unseal/issues?q=is:open+is:issue+label:bug\"\u003e\n    \u003cimg title=\"Bug reports\" src=\"https://img.shields.io/github/issues/lrstanley/vault-unseal/bug?label=issues\u0026style=flat-square\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/lrstanley/vault-unseal/issues?q=is:open+is:issue+label:enhancement\"\u003e\n    \u003cimg title=\"Feature requests\" src=\"https://img.shields.io/github/issues/lrstanley/vault-unseal/enhancement?label=feature%20requests\u0026style=flat-square\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/lrstanley/vault-unseal/pulls\"\u003e\n    \u003cimg title=\"Open Pull Requests\" src=\"https://img.shields.io/github/issues-pr/lrstanley/vault-unseal?label=prs\u0026style=flat-square\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/lrstanley/vault-unseal/releases\"\u003e\n    \u003cimg title=\"Latest Semver Release\" src=\"https://img.shields.io/github/v/release/lrstanley/vault-unseal?style=flat-square\"\u003e\n    \u003cimg title=\"Latest Release Date\" src=\"https://img.shields.io/github/release-date/lrstanley/vault-unseal?label=date\u0026style=flat-square\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/lrstanley/vault-unseal/discussions/new?category=q-a\"\u003e\n    \u003cimg title=\"Ask a Question\" src=\"https://img.shields.io/badge/support-ask_a_question!-blue?style=flat-square\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://liam.sh/chat\"\u003e\u003cimg src=\"https://img.shields.io/badge/discord-bytecord-blue.svg?style=flat-square\" title=\"Discord Chat\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003c!-- template:end:header --\u003e\n\n\u003c!-- template:begin:toc --\u003e\n\u003c!-- do not edit anything in this \"template\" block, its auto-generated --\u003e\n## :link: Table of Contents\n\n  - [Why](#grey_question-why)\n  - [Solution](#heavy_check_mark-solution)\n  - [Installation](#computer-installation)\n    - [Container Images (ghcr)](#whale-container-images-ghcr)\n    - [Source](#toolbox-source)\n  - [Usage](#gear-usage)\n  - [TODO](#ballot_box_with_check-todo)\n  - [Support \u0026amp; Assistance](#raising_hand_man-support--assistance)\n  - [Contributing](#handshake-contributing)\n  - [License](#balance_scale-license)\n\u003c!-- template:end:toc --\u003e\n\n## :grey_question: Why\n\nHashiCorp Vault provides a few options for auto-unsealing clusters:\n\n- [Cloud KMS (AWS, Azure, GCP, and others)](https://developer.hashicorp.com/vault/docs/configuration/seal/awskms) (cloud only)\n- [Hardware Security Modules with PKCS11](https://developer.hashicorp.com/vault/docs/configuration/seal/pkcs11) (enterprise only)\n- [Transit Engine via Vault](https://developer.hashicorp.com/vault/docs/configuration/seal/transit) (requires another vault cluster)\n- [Potentially others](https://developer.hashicorp.com/vault/docs/configuration/seal)\n\nHowever, depending on your deployment conditions and use-cases of Vault, some of\nthe above may not be feasible (cost, network connectivity, complexity). This may\nlead you to want to roll your own unseal functionality, however, it's not easy to\ndo in a relatively secure manner.\n\nSo, what do we need to solve? We want to auto-unseal a vault cluster, by providing\nthe necessary unseal tokens when we find vault is sealed. We also want to make sure\nwe're sending notifications when this happens, so if vault was unsealed\nunintentionally (not patching, upgrades, etc), possibly related to crashing or\nmalicious intent, a human can investigate at a later time (**not** 3am in the\nmorning).\n\n## :heavy_check_mark: Solution\n\nThe goal for this project is to find the best way to unseal vault in a way that\ndoesn't compromise too much security (a good balance between security and ease of\nuse/uptime), without the requirement of Vault Enterprise, or having to move to a\ncloud platform.\n\nWe do this by running multiple instances of vault-unseal (you could run one\non each node in the cluster). Each instance of vault-unseal is given a subset\nof the unseal tokens. You want to give each node **just enough** tokens, that\nwhen paired with another vault-unseal node, they can work together to unseal the\nvault. What we want to avoid is giving a single vault-unseal instance enough\ntokens to unseal (to prevent a compromise leading to enough tokens being exposed\nthat could unseal the vault). Let's use the following example:\n\n![vault-unseal example diagram](https://cdn.liam.sh/share/2022/08/I8Qc1RCBMd.png)\n\nExplained further:\n\n- `cluster-1` consists of 3 nodes:\n  - `node-1`\n  - `node-2`\n  - `node-3`\n- `cluster-1` is configured with 5 unseal tokens (tokens `A`, `B`, `C`, `D`, `E`), but\n     only 3 are required to unseal a given vault node.\n- given there are 3 nodes, 3 tokens being required:\n  - vault-unseal on `node-1` gets tokens `A` and `B`.\n  - vault-unseal on `node-2` gets tokens `B` and `C`.\n  - vault-unseal on `node-3` gets tokens `A` and `C`.\n\nWith the above configuration:\n\n- Given each vault-unseal node, each node has two tokens.\n- Given the tokens provided to vault-unseal, each token (`A`, `B`, and `C`), there\n   are two instances of that token across nodes in the cluster.\n- If `node-1` is completely hard-offline, nodes `node-2` and `node-3` should have\n   all three tokens, so if the other two nodes reboot, as long as vault-unseal starts\n   up on those nodes, vault-unseal will be able to unseal both.\n- If `node-2` becomes compromised, and the tokens are read from the config\n   file (note: vault-unseal **will not start** if the permissions on the file aren't\n   `600`), this will not be enough tokens to unseal the vault.\n- vault-unseal runs as root, with root permissions.\n\n## :computer: Installation\n\nCheck out the [releases](https://github.com/lrstanley/vault-unseal/releases)\npage for prebuilt versions.\n\n\u003c!-- template:begin:ghcr --\u003e\n\u003c!-- do not edit anything in this \"template\" block, its auto-generated --\u003e\n### :whale: Container Images (ghcr)\n\n```console\n$ docker run -it --rm ghcr.io/lrstanley/vault-unseal:master\n$ docker run -it --rm ghcr.io/lrstanley/vault-unseal:0.7.0\n$ docker run -it --rm ghcr.io/lrstanley/vault-unseal:latest\n$ docker run -it --rm ghcr.io/lrstanley/vault-unseal:0.6.0\n$ docker run -it --rm ghcr.io/lrstanley/vault-unseal:0.5.1\n$ docker run -it --rm ghcr.io/lrstanley/vault-unseal:0.5.0\n$ docker run -it --rm ghcr.io/lrstanley/vault-unseal:0.4.1\n$ docker run -it --rm ghcr.io/lrstanley/vault-unseal:0.4.0\n$ docker run -it --rm ghcr.io/lrstanley/vault-unseal:0.3.0\n$ docker run -it --rm ghcr.io/lrstanley/vault-unseal:0.2.4\n$ docker run -it --rm ghcr.io/lrstanley/vault-unseal:0.2.3\n$ docker run -it --rm ghcr.io/lrstanley/vault-unseal:0.2.2\n$ docker run -it --rm ghcr.io/lrstanley/vault-unseal:0.2.1\n$ docker run -it --rm ghcr.io/lrstanley/vault-unseal:0.2.0\n```\n\u003c!-- template:end:ghcr --\u003e\n\n### :toolbox: Source\n\nNote that you must have [Go](https://golang.org/doc/install) installed (latest is usually best).\n\n    git clone https://github.com/lrstanley/vault-unseal.git \u0026\u0026 cd vault-unseal\n    make\n    ./vault-unseal --help\n\n## :gear: Usage\n\nThe default configuration path is `/etc/vault-unseal.yaml` when using `deb`/`rpm`.\nIf you are not using these package formats, copy the example config file,\n`example.vault-unseal.yaml`, to `vault-unseal.yaml`. Note, all fields can be provided\nvia environment variables (vault-unseal also supports `.env` files).\n\n```\n$ ./vault-unseal --help\nUsage:\n  vault-unseal [OPTIONS]\n\nApplication Options:\n  -v, --version          Display the version of vault-unseal and exit\n  -l, --log-path=PATH    Optional path to log output to\n  -c, --config=PATH      Path to configuration file (default: ./vault-unseal.yaml)\n\nHelp Options:\n  -h, --help             Show this help message\n```\n\n## :ballot_box_with_check: TODO\n\n- [ ] add option to use vault token/another vault instance to obtain keys (e.g. as long the leader is online)?\n- [ ] memory obfuscating/removing from memory right after unseal?\n\n\u003c!-- template:begin:support --\u003e\n\u003c!-- do not edit anything in this \"template\" block, its auto-generated --\u003e\n## :raising_hand_man: Support \u0026 Assistance\n\n* :heart: Please review the [Code of Conduct](.github/CODE_OF_CONDUCT.md) for\n     guidelines on ensuring everyone has the best experience interacting with\n     the community.\n* :raising_hand_man: Take a look at the [support](.github/SUPPORT.md) document on\n     guidelines for tips on how to ask the right questions.\n* :lady_beetle: For all features/bugs/issues/questions/etc, [head over here](https://github.com/lrstanley/vault-unseal/issues/new/choose).\n\u003c!-- template:end:support --\u003e\n\n\u003c!-- template:begin:contributing --\u003e\n\u003c!-- do not edit anything in this \"template\" block, its auto-generated --\u003e\n## :handshake: Contributing\n\n* :heart: Please review the [Code of Conduct](.github/CODE_OF_CONDUCT.md) for guidelines\n     on ensuring everyone has the best experience interacting with the\n    community.\n* :clipboard: Please review the [contributing](.github/CONTRIBUTING.md) doc for submitting\n     issues/a guide on submitting pull requests and helping out.\n* :old_key: For anything security related, please review this repositories [security policy](https://github.com/lrstanley/vault-unseal/security/policy).\n\u003c!-- template:end:contributing --\u003e\n\n\u003c!-- template:begin:license --\u003e\n\u003c!-- do not edit anything in this \"template\" block, its auto-generated --\u003e\n## :balance_scale: License\n\n```\nMIT License\n\nCopyright (c) 2018 Liam Stanley \u003cliam@liam.sh\u003e\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n\n_Also located [here](LICENSE)_\n\u003c!-- template:end:license --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flrstanley%2Fvault-unseal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flrstanley%2Fvault-unseal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flrstanley%2Fvault-unseal/lists"}