{"id":19133748,"url":"https://github.com/chazmcgarvey/groupsecret","last_synced_at":"2026-06-08T15:30:16.224Z","repository":{"id":56838899,"uuid":"112570454","full_name":"chazmcgarvey/groupsecret","owner":"chazmcgarvey","description":"A simple tool for maintaining a shared group secret","archived":false,"fork":false,"pushed_at":"2018-02-15T04:12:02.000Z","size":43,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-03T12:13:24.941Z","etag":null,"topics":["ansible-vault","encryption","perl","ssh"],"latest_commit_sha":null,"homepage":"https://metacpan.org/release/App-GroupSecret","language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chazmcgarvey.png","metadata":{"files":{"readme":"README.md","changelog":"Changes","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-11-30T05:51:32.000Z","updated_at":"2019-11-21T11:55:28.000Z","dependencies_parsed_at":"2022-08-29T04:52:40.195Z","dependency_job_id":null,"html_url":"https://github.com/chazmcgarvey/groupsecret","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chazmcgarvey%2Fgroupsecret","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chazmcgarvey%2Fgroupsecret/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chazmcgarvey%2Fgroupsecret/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chazmcgarvey%2Fgroupsecret/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chazmcgarvey","download_url":"https://codeload.github.com/chazmcgarvey/groupsecret/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240214568,"owners_count":19766263,"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":["ansible-vault","encryption","perl","ssh"],"created_at":"2024-11-09T06:23:41.790Z","updated_at":"2026-06-08T15:30:16.187Z","avatar_url":"https://github.com/chazmcgarvey.png","language":"Perl","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NAME\n\ngroupsecret - A simple tool for maintaining a shared group secret\n\n# VERSION\n\nversion 0.304\n\n# SYNOPSIS\n\n    groupsecret [--version] [--help] [-f \u003cfilepath\u003e] [-k \u003cprivatekey_path\u003e]\n                \u003ccommand\u003e [\u003cargs\u003e]\n\n    groupsecret add-key [--embed] [--update] \u003cpublickey_path\u003e ...\n\n    groupsecret delete-key \u003cfingerprint\u003e|\u003cpublickey_path\u003e ...\n\n    groupsecret list-keys\n\n    groupsecret set-secret [--keep-passphrase] \u003cpath\u003e|-|rand:\u003cnum_bytes\u003e\n\n    groupsecret [print-secret] [--no-decrypt]\n\n# DESCRIPTION\n\n[groupsecret](https://metacpan.org/pod/groupsecret) is a program that makes it easy for groups to share a secret between themselves\nwithout exposing the secret to anyone else. It could be used, for example, by a team to share an\n[ansible-vault(1)](http://man.he.net/man1/ansible-vault) password; see [\"ansible-vault\"](#ansible-vault) for more about this particular use case.\n\nThe goal of this program is to be easy to use and have few dependencies (or only have dependencies\nusers are likely to already have installed).\n\ngroupsecret works by encrypting a secret with a symmetric cipher protected by a secure random\npassphrase which is itself encrypted by one or more SSH2 RSA public keys. Only those who have access\nto one of the corresponding private keys are able to decrypt the passphrase and access the secret.\n\nThe encrypted secret and passphrase are stored in a single keyfile. You can even commit the keyfile\nin a public repo or in a private repo where some untrusted users may have read access; the secret is\nlocked away to all except those with a private key to a corresponding public key that has been added\nto the keyfile.\n\nThe keyfile is just a YAML file, so it's human-readable (except of course for the encrypted parts).\nThis make it easy to add to version control and work with diffs. You can edit the keyfile by hand if\nyou learn its very simple structure, but this program makes it even easier to manage the keyfile.\n\n# OPTIONS\n\n## --version\n\nPrint the program name and version to `STDOUT`, and exit.\n\nAlias: `-v`\n\n## --help\n\nPrint the synopsis to `STDOUT`, and exit.\n\nAlias: `-h`\n\n## --file=path\n\nSpecify a path to a keyfile which stores a secret and keys.\n\nDefaults to the value of the environment variable [\"GROUPSECRET\\_KEYFILE\"](#groupsecret_keyfile) or `groupsecret.yml`.\n\nAlias: `-f`\n\n## --private-key=path\n\nSpecify a path to a PEM private key. This is used by some commands to decrypt the passphrase that\nprotects the secret and is ignored by commands that don't need it.\n\nDefaults to the value of the environment variable [\"GROUPSECRET\\_PRIVATE\\_KEY\"](#groupsecret_private_key) or `~/.ssh/id_rsa`.\n\nAlias: `-k`\n\n# COMMANDS\n\n## add-key\n\n    groupsecret add-key path/to/mykey_rsa.pub\n\nAdds one or more SSH2 RSA public keys to a keyfile. This allows the secret contained within the\nkeyfile to be accessed by whoever has the corresponding private key.\n\nIf the `--embed` option is used, the public keys will be embeded in the keyfile. This may be\na useful way to make sure the actual keys are available in the future since they could be needed to\nencrypt a new passphrase if it ever needs to be changed. Keys that are not embedded will be searched\nfor in the filesystem; see [\"GROUPSECRET\\_PATH\"](#groupsecret_path).\n\nIf the `--update` option is used and a key with the same fingerprint is added, the new key will\nreplace the existing key. The default behavior is to skip existing keys.\n\nIf the keyfile is storing a secret, the passphrase protecting the secret will need to be decrypted\nso that access to the secret can be shared with the new key(s).\n\nAlias: `add-keys`\n\n## delete-key\n\n    groupsecret delete-key MD5:89:b3:fb:76:6c:f9:56:8e:a8:1a:df:ba:1c:ba:7d:05\n    groupsecret delete-key path/to/mykey_rsa.pub\n\nDeletes one or more keys from a keyfile. This prevents the secret contained within the keyfile from\nbeing accessed by whoever has the corresponding private key.\n\nOf course, if the owners of the key(s) being removed have already had access to the keyfile prior to\ntheir keys being removed, the secret is already exposed to them. It usually makes sense to follow up\nthis command with a [\"set-secret\"](#set-secret) command in order to change the secret.\n\nAliases: `delete-keys`, `remove-key`, `remove-keys`\n\n## list-keys\n\n    groupsecret list-keys\n\nPrints the keys that have access to the secret contained in the keyfile to `STDOUT`, one per line\nin the following format:\n\n    \u003cfingerprint\u003e \u003ccomment\u003e\n\n## set-secret\n\n    groupsecret set-secret path/to/secretfile.txt\n    groupsecret set-secret - \u003c\u003cEND\n    \u003e it's a secret to everybody\n    \u003e END\n    groupsecret set-secret rand:48\n\nSet or update the secret contained in a keyfile. The argument allows you to add a secret from\na file, from \u003cSTDIN\u003e, or from a stream of secure random bytes.\n\nIf the keyfile already contains a secret, it will be replaced by the new secret. A keyfile can only\ncontain one secret at a time. If you think you want to store more than one secret at a time, store\na tarball instead.\n\nBy default, this will also change the passphrase protecting the secret and re-encrypt the passphrase\nfor each key currently in the keyfile. This requires all of the public keys to be available (see\n[\"GROUPSECRET\\_PATH\"](#groupsecret_path)). If for some reason you want to protect the new secret with the current\npassphrase, use the `--keep-passphrase` option; this can be done without the public keys being\navailable, but it will require a private key to decrypt the passphrase.\n\nAliases: `change-secret`, `update-secret`\n\n## print-secret\n\n    groupsecret print-secret\n    groupsecret print-secret --no-decrypt\n\nPrint the secret contained in the keyfile to `STDOUT`.\n\nIf the `--no-decrypt` option is used, the secret will be printed in its encrypted form.\n\nThis requires a private key.\n\nAliases: (no command), `show-secret`\n\n# REQUIREMENTS\n\n- [OpenSSH](https://www.openssh.com) (commands: [ssh-keygen(1)](http://man.he.net/man1/ssh-keygen))\n- [OpenSSL](https://www.openssl.org) (commands: [openssl(1)](http://man.he.net/man1/openssl))\n\n# INSTALL\n\nThere are a few ways to install groupsecret to your system. First, make sure you first have the\n[\"REQUIREMENTS\"](#requirements) installed.\n\n## Using cpanm\n\nYou can install groupsecret using [cpanm](https://metacpan.org/pod/cpanm). If you have a local perl (plenv, perlbrew, etc.), you\ncan just do this:\n\n    cpanm App::GroupSecret\n\nto install the `groupsecret` executable and its Perl module dependencies. The executable will be\ninstalled to your perl's bin path, like `~/perl5/perlbrew/bin/groupsecret`.\n\nIf you're installing to your system perl, you can do:\n\n    cpanm --sudo App::GroupSecret\n\nto install the `groupsecret` executable to a system directory, like `/usr/local/bin/groupsecret`\n(depending on your perl).\n\n## For developers\n\nIf you're a developer and want to hack on the source, clone the repository and pull the\ndependencies:\n\n    git clone https://github.com/chazmcgarvey/groupsecret.git\n    cd groupsecret\n    cpanm Dist::Zilla\n    dzil authordeps --missing | cpanm\n    dzil listdeps --author --develop --missing | cpanm\n\n# ENVIRONMENT\n\n## GROUPSECRET\\_KEYFILE\n\nIf set, this program will use the value as a path to the keyfile. The [\"--file=path\"](#file-path) option takes\nprecedence if used.\n\n## GROUPSECRET\\_PRIVATE\\_KEY\n\nIf set, this program will use the value as a path to private key used for decryption. The\n[\"--private-key=path\"](#private-key-path) option takes precedence if used.\n\n## GROUPSECRET\\_PATH\n\nThe value of this variable should be a colon-separated list of directories in which to search for\npublic keys. By default, the actual keys are not embedded in keyfiles, but they may be needed to\nencrypt a new passphrase if it ever needs to be changed. Keys that are not embedded will be searched\nfor in the filesystem based on the value of this environment variable.\n\nDefaults to `.:keys:$HOME/.ssh`.\n\n# EXAMPLES\n\n## ansible-vault\n\n[Ansible Vault](http://docs.ansible.com/ansible/latest/vault.html) is a great way to securely store\nsecret configuration variables for use in your playbooks. Vaults are secured using a password, which\nis okay if you're the only one who will need to unlock the Vault, but as soon as you add team\nmembers who also need to access the Vault you are then faced with how to manage knowledge of the\npassword. When a team member leaves, you'll also need to change the Vault password which means\nyou'll need a way to communicate the change to other team members who also have access. This becomes\na burden to manage.\n\nYou can use groupsecret to manage this very easily by storing the Vault password in a groupsecret\nkeyfile. That way, you can add or remove keys and change the secret (the Vault password) at any time\nwithout affecting the team members that still have access. Team members always use their own SSH2\nRSA keys to unlock the Vault, so no new password ever needs to be communicated out.\n\nTo set this up, first create a keyfile with the public keys of everyone on your team:\n\n    groupsecret -f vault-password.yml add-keys keys/*_rsa.pub\n\nThen set the secret in the keyfile to a long random number:\n\n    groupsecret -f vault-password.yml set-secret rand:48\n\nThis will be the Ansible Vault password. You can see it if you want using the [\"print-secret\"](#print-secret)\ncommand, but you don't need to.\n\nThen we'll take advantage of the fact that an Ansible Vault password file can be an executable\nprogram that prints the Vault password to `STDOUT`. Create a file named `vault-password` with the\nfollowing script, and make it executable (`chmod +x vault-password`):\n\n    #!/bin/sh\n    # Use groupsecret \u003chttps://github.com/chazmcgarvey/groupsecret\u003e to access the Vault password\n    exec ${GROUPSECRET:-groupsecret} -f vault-password.yml print-secret\n\nCommit both `vault-password` and `vault-password.yml` to your repository.\n\nNow use [ansible-vault(1)](http://man.he.net/man1/ansible-vault) to add files to the Vault:\n\n    ansible-vault --vault-id=vault-password encrypt foo.yml bar.yml baz.yml\n\nThese examples show the Ansible 2.4+ syntax, but it can be adapted for earlier versions. The\nsignificant part of this command is `--vault-id=vault-password` which refers to the executable\nscript we created earlier. You can use that argument with other ansible-vault commands to view or\nedit the encrypted files.\n\nYou can also pass that same argument to [ansible-playbook(1)](http://man.he.net/man1/ansible-playbook) in order to use the Vault in\nplaybooks that refer to the encrypted variables:\n\n    ansible-playbook -i myinventory --vault-id=vault-password site.yml\n\nWhat this does is execute `vault-password` which executes groupsecret to print the secret contained\nin the `vault-password.yml` file (which is actually the Vault password) to `STDOUT`. In order to\ndo this, groupsecret will decrypt the keyfile passphrase using any one of the private keys that have\nassociated public keys added to the keyfile.\n\nThat's it! Pretty easy.\n\nIf and when you need to change the Vault password (such as when a team member leaves), you can\nfollow this procedure which is probably mostly self-explanatory:\n\n    groupsecret -f vault-password.yml delete-key keys/revoked/jdoe_rsa.pub\n    groupsecret -f vault-password.yml print-secret \u003eold-vault-password.txt\n    groupsecret -f vault-password.yml set-secret rand:48\n    echo \"New Vault password: $(groupsecret -f vault-password.yml)\"\n    ansible-vault --vault-id=old-vault-password.txt rekey foo.yml bar.yml baz.yml\n    # You will be prompted for the new Vault password which you can copy from the output above.\n    rm -f old-vault-password.txt\n\nThis removes access to the keyfile secret and to the Ansible Vault. Don't forget that you may also\nwant to change the variables being protected by the Vault. After all, those secrets are the actual\nthings we're protecting by doing all of this, and an exiting team member may have decided to take\na copy of those variables for himself before leaving.\n\n# BUGS\n\nPlease report any bugs or feature requests on the bugtracker website\n[https://github.com/chazmcgarvey/groupsecret/issues](https://github.com/chazmcgarvey/groupsecret/issues)\n\nWhen submitting a bug or request, please include a test-file or a\npatch to an existing test-file that illustrates the bug or desired\nfeature.\n\n# AUTHOR\n\nCharles McGarvey \u003cchazmcgarvey@brokenzipper.com\u003e\n\n# COPYRIGHT AND LICENSE\n\nThis software is Copyright (c) 2017 by Charles McGarvey.\n\nThis is free software, licensed under:\n\n    The MIT (X11) License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchazmcgarvey%2Fgroupsecret","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchazmcgarvey%2Fgroupsecret","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchazmcgarvey%2Fgroupsecret/lists"}