Release App-GroupSecret 0.302
[chaz/groupsecret] / README.md
1 # NAME
2
3 groupsecret - A simple tool for maintaining a shared group secret
4
5 # VERSION
6
7 version 0.302
8
9 # SYNOPSIS
10
11 groupsecret [--version] [--help] [-f <filepath>] [-k <privatekey_path>]
12 <command> [<args>]
13
14 groupsecret add-key [--embed] [--update] <publickey_path> ...
15
16 groupsecret delete-key <fingerprint>|<publickey_path> ...
17
18 groupsecret list-keys
19
20 groupsecret set-secret [--keep-passphrase] <path>|-|rand:<num_bytes>
21
22 groupsecret [print-secret] [--no-decrypt]
23
24 # DESCRIPTION
25
26 [groupsecret](https://metacpan.org/pod/groupsecret) is a program that makes it easy for groups to share a secret between themselves
27 without exposing the secret to anyone else. It could be used, for example, by a team to share an
28 [ansible-vault(1)](http://man.he.net/man1/ansible-vault) password; see ["ansible-vault"](#ansible-vault) for more about this particular use case.
29
30 The goal of this program is to be easy to use and have few dependencies (or only have dependencies
31 users are likely to already have installed).
32
33 groupsecret works by encrypting a secret with a symmetric cipher protected by a secure random
34 passphrase which is itself encrypted by one or more SSH2 RSA public keys. Only those who have access
35 to one of the corresponding private keys are able to decrypt the passphrase and access the secret.
36
37 The encrypted secret and passphrase are stored in a single keyfile. You can even commit the keyfile
38 in a public repo or in a private repo where some untrusted users may have read access; the secret is
39 locked away to all except those with a private key to a corresponding public key that has been added
40 to the keyfile.
41
42 The keyfile is just a YAML file, so it's human-readable (except of course for the encrypted parts).
43 This make it easy to add to version control and work with diffs. You can edit the keyfile by hand if
44 you learn its very simple structure, but this program makes it even easier to manage the keyfile.
45
46 # OPTIONS
47
48 ## --version
49
50 Print the program name and version to `STDOUT`, and exit.
51
52 Alias: `-v`
53
54 ## --help
55
56 Print the synopsis to `STDOUT`, and exit.
57
58 Alias: `-h`
59
60 ## --file=path
61
62 Specify a path to a keyfile which stores a secret and keys.
63
64 Defaults to the value of the environment variable ["GROUPSECRET\_KEYFILE"](#groupsecret_keyfile) or `groupsecret.yml`.
65
66 Alias: `-f`
67
68 ## --private-key=path
69
70 Specify a path to a PEM private key. This is used by some commands to decrypt the passphrase that
71 protects the secret and is ignored by commands that don't need it.
72
73 Defaults to the value of the environment variable ["GROUPSECRET\_PRIVATE\_KEY"](#groupsecret_private_key) or `~/.ssh/id_rsa`.
74
75 Alias: `-k`
76
77 # COMMANDS
78
79 ## add-key
80
81 groupsecret add-key path/to/mykey_rsa.pub
82
83 Adds one or more SSH2 RSA public keys to a keyfile. This allows the secret contained within the
84 keyfile to be accessed by whoever has the corresponding private key.
85
86 If the `--embed` option is used, the public keys will be embeded in the keyfile. This may be
87 a useful way to make sure the actual keys are available in the future since they could be needed to
88 encrypt a new passphrase if it ever needs to be changed. Keys that are not embedded will be searched
89 for in the filesystem; see ["GROUPSECRET\_PATH"](#groupsecret_path).
90
91 If the `--update` option is used and a key with the same fingerprint is added, the new key will
92 replace the existing key. The default behavior is to skip existing keys.
93
94 If the keyfile is storing a secret, the passphrase protecting the secret will need to be decrypted
95 so that access to the secret can be shared with the new key(s).
96
97 Alias: `add-keys`
98
99 ## delete-key
100
101 groupsecret delete-key MD5:89:b3:fb:76:6c:f9:56:8e:a8:1a:df:ba:1c:ba:7d:05
102 groupsecret delete-key path/to/mykey_rsa.pub
103
104 Deletes one or more keys from a keyfile. This prevents the secret contained within the keyfile from
105 being accessed by whoever has the corresponding private key.
106
107 Of course, if the owners of the key(s) being removed have already had access to the keyfile prior to
108 their keys being removed, the secret is already exposed to them. It usually makes sense to follow up
109 this command with a ["set-secret"](#set-secret) command in order to change the secret.
110
111 Aliases: `delete-keys`, `remove-key`, `remove-keys`
112
113 ## list-keys
114
115 groupsecret list-keys
116
117 Prints the keys that have access to the secret contained in the keyfile to `STDOUT`, one per line
118 in the following format:
119
120 <fingerprint> <comment>
121
122 ## set-secret
123
124 groupsecret set-secret path/to/secretfile.txt
125 groupsecret set-secret - <<END
126 > it's a secret to everybody
127 > END
128 groupsecret set-secret rand:48
129
130 Set or update the secret contained in a keyfile. The argument allows you to add a secret from
131 a file, from <STDIN>, or from a stream of secure random bytes.
132
133 If the keyfile already contains a secret, it will be replaced by the new secret. A keyfile can only
134 contain one secret at a time. If you think you want to store more than one secret at a time, store
135 a tarball instead.
136
137 By default, this will also change the passphrase protecting the secret and re-encrypt the passphrase
138 for each key currently in the keyfile. This requires all of the public keys to be available (see
139 ["GROUPSECRET\_PATH"](#groupsecret_path)). If for some reason you want to protect the new secret with the current
140 passphrase, use the `--keep-passphrase` option; this can be done without the public keys being
141 available, but it will require a private key to decrypt the passphrase.
142
143 Aliases: `change-secret`, `update-secret`
144
145 ## print-secret
146
147 groupsecret print-secret
148 groupsecret print-secret --no-decrypt
149
150 Print the secret contained in the keyfile to `STDOUT`.
151
152 If the `--no-decrypt` option is used, the secret will be printed in its encrypted form.
153
154 This requires a private key.
155
156 Aliases: (no command), `show-secret`
157
158 # REQUIREMENTS
159
160 - [OpenSSH](https://www.openssh.com) (commands: [ssh-keygen(1)](http://man.he.net/man1/ssh-keygen))
161 - [OpenSSL](https://www.openssl.org) (commands: [openssl(1)](http://man.he.net/man1/openssl))
162
163 # INSTALL
164
165 There are a few ways to install groupsecret to your system. First, make sure you first have the
166 ["REQUIREMENTS"](#requirements) installed.
167
168 ## Using cpanm
169
170 You can install groupsecret using [cpanm](https://metacpan.org/pod/cpanm). If you have a local perl (plenv, perlbrew, etc.), you
171 can just do this:
172
173 cpanm App::GroupSecret
174
175 to install the `groupsecret` executable and its Perl module dependencies. The executable will be
176 installed to your perl's bin path, like `~/perl5/perlbrew/bin/groupsecret`.
177
178 If you're installing to your system perl, you can do:
179
180 cpanm --sudo App::GroupSecret
181
182 to install the `groupsecret` executable to a system directory, like `/usr/local/bin/groupsecret`
183 (depending on your perl).
184
185 ## For developers
186
187 If you're a developer and want to hack on the source, clone the repository and pull the
188 dependencies:
189
190 git clone https://github.com/chazmcgarvey/groupsecret.git
191 cd groupsecret
192 cpanm Dist::Zilla
193 dzil authordeps --missing | cpanm
194 dzil listdeps --author --develop --missing | cpanm
195
196 # ENVIRONMENT
197
198 ## GROUPSECRET\_KEYFILE
199
200 If set, this program will use the value as a path to the keyfile. The ["--file=path"](#file-path) option takes
201 precedence if it is used.
202
203 ## GROUPSECRET\_PRIVATE\_KEY
204
205 If set, this program will use the value as a path to the keyfile. The ["--private-key=path"](#private-key-path) option
206 takes precedence if it is used.
207
208 ## GROUPSECRET\_PATH
209
210 The value of this variable should be a colon-separated list of directories in which to search for
211 public keys. By default, the actual keys are not embedded in keyfiles, but they may be needed to
212 encrypt a new passphrase if it ever needs to be changed. Keys that are not embedded will be searched
213 for in the filesystem based on the value of this environment variable.
214
215 Defaults to `.:keys:$HOME/.ssh`.
216
217 # EXAMPLES
218
219 ## ansible-vault
220
221 [Ansible Vault](http://docs.ansible.com/ansible/latest/vault.html) is a great way to securely store
222 secret configuration variables for use in your playbooks. Vaults are secured using a password, which
223 is okay if you're the only one who will need to unlock the Vault, but as soon as you add team
224 members who also need to access the Vault you are then faced with how to manage knowledge of the
225 password. When a team member leaves, you'll also need to change the Vault password which means
226 you'll need a way to communicate the change to other team members who also have access. This becomes
227 a burden to manage.
228
229 You can use groupsecret to manage this very easily by storing the Vault password in a groupsecret
230 keyfile. That way, you can add or remove keys and change the secret (the Vault password) at any time
231 without affecting the team members that still have access. Team members always use their own SSH2
232 RSA keys to unlock the Vault, so no new password ever needs to be communicated out.
233
234 To set this up, first create a keyfile with the public keys of everyone on your team:
235
236 groupsecret -f vault-password.yml add-keys keys/*_rsa.pub
237
238 Then set the secret in the keyfile to a long random number:
239
240 groupsecret -f vault-password.yml set-secret rand:48
241
242 This will be the Ansible Vault password. You can see it if you want using the ["print-secret"](#print-secret)
243 command, but you don't need to.
244
245 Finally, we'll take advantage of the fact that a Ansible Vault password file can be an executable
246 program that prints the Vault password to `STDOUT`. Create a file named `vault-password` with the
247 following script, and make it executable (`chmod +x vault-password`):
248
249 #!/bin/sh
250 # Use groupsecret <https://github.com/chazmcgarvey/groupsecret> to access the Vault password
251 exec ${GROUPSECRET:-groupsecret} -f vault-password.yml print-secret
252
253 Commit both `vault-password` and `vault-password.yml` to your repository.
254
255 Now use [ansible-vault(1)](http://man.he.net/man1/ansible-vault) to add files to the Vault:
256
257 ansible-vault --vault-id=vault-password encrypt foo.yml bar.yml baz.yml
258
259 These examples show the Ansible 2.4+ syntax, but it can be adapted for earlier versions. The
260 significant part of this command is `--vault-id=vault-password` which refers to the executable
261 script we created earlier. You can use that argument with other ansible-vault commands to view or
262 edit the encrypted files.
263
264 You can also pass that same argument to `ansible-playbook(1)` in order to use the Vault in
265 playbooks that refer to the encrypted variables:
266
267 ansible-playbook -i myinventory --vault-id=vault-password site.yml
268
269 What this does is execute `vault-password` which executes groupsecret to print the secret contained
270 in the `vault-password.yml` file (which is actually the Vault password) to <STDOUT>. In order to do
271 this, groupsecret will decrypt the keyfile passphrase using any one of the private keys that have
272 associated public keys added to the keyfile.
273
274 That's it! Pretty easy.
275
276 If and when you need to change the Vault password (such as when a team member leaves), you can
277 follow this procedure which is probably mostly self-explanatory:
278
279 groupsecret -f vault-password.yml delete-key keys/revoked/jdoe_rsa.pub
280 groupsecret -f vault-password.yml print-secret >old-vault-password.txt
281 groupsecret -f vault-password.yml set-secret rand:48
282 echo "New Vault password: $(groupsecret -f vault-password.yml)"
283 ansible-vault --vault-id=old-vault-password.txt rekey foo.yml bar.yml baz.yml
284 # You will be prompted for the new Vault password which you can copy from the output above.
285 rm -f old-vault-password.txt
286
287 This removes access to the keyfile secret and to the Ansible Vault. Don't forget that you may also
288 want to change the variables being protected by the Vault. After all, those secrets are the actual
289 things we're protecting by doing all of this, and an exiting team member may have decided to take
290 a copy of those variables for himself before leaving.
291
292 # BUGS
293
294 Please report any bugs or feature requests on the bugtracker website
295 [https://github.com/chazmcgarvey/groupsecret/issues](https://github.com/chazmcgarvey/groupsecret/issues)
296
297 When submitting a bug or request, please include a test-file or a
298 patch to an existing test-file that illustrates the bug or desired
299 feature.
300
301 # AUTHOR
302
303 Charles McGarvey <chazmcgarvey@brokenzipper.com>
304
305 # COPYRIGHT AND LICENSE
306
307 This software is Copyright (c) 2017 by Charles McGarvey.
308
309 This is free software, licensed under:
310
311 The MIT (X11) License
This page took 0.044334 seconds and 4 git commands to generate.