Add a tutorial: setting up three services with master passphrase
Marco Ricci

Marco Ricci commited on 2024-10-05 09:04:28
Zeige 3 geänderte Dateien mit 250 Einfügungen und 1 Löschungen.


The new tutorial is an introductory tutorial that deals with setting up
the first few services with `derivepassphrase vault`.  It deals with
installing the software and configuring the first three services.  I've
included one out-of-scope item (a one-time-password hardware token) and
one ill-specified requirement on special characters as practical
examples of things a new user might actually encounter in practice, and
how to deal with these (or not).

The tutorial is complete content-wise, but probably needs some
copy-editing, and definitely needs some practical feedback.  The
installation section is also untested, and lacking in comprehensiveness,
as there are multiple sane ways to install Python software such as this
one.  Once other documentation is complete, this tutorial may also need
some minor revision on whether and where to link to further topics that
were only briefly touched here.
... ...
@@ -7,7 +7,7 @@
7 7
 
8 8
 ## Tutorials
9 9
 
10
-* Setting up `derivepassphrase` from scratch for three existing accounts, with a master passphrase
10
+* [Setting up `derivepassphrase` from scratch for three existing accounts, with a master passphrase](tutorials/basic-setup-password.md)
11 11
 * Setting up `derivepassphrase` from scratch for three existing accounts, with a new SSH key
12 12
 
13 13
 ## How-tos
... ...
@@ -0,0 +1,244 @@
1
+# Tutorial: setting up `derivepassphrase vault` for three accounts, with a master passphrase
2
+
3
+## The scenario
4
+
5
+In this tutorial, we will setup `derivepassphrase` for three services, using a master passphrase and the standard `vault` passphrase derivation scheme.
6
+We will assume the following three services with the following passphrase policies:
7
+
8
+<div class="grid cards" markdown>
9
+
10
+-   __email account__
11
+
12
+    ---
13
+
14
+    - between 12 and 20 characters
15
+    - no spaces
16
+    - 1 upper case letter, 1 lower case letter, 1 digit
17
+    * no character immediately repeated more than 3 times
18
+
19
+-   __bank account__
20
+
21
+    ---
22
+
23
+    - only digits
24
+    * exactly 5 digits
25
+    * an additional one-time password via a hardware token ("[two-factor authentication][2FA]")
26
+
27
+-   __work account__
28
+
29
+    ---
30
+
31
+    - exactly 8 characters
32
+    * no spaces
33
+    - 1 special character, 1 letter, 1 digit
34
+    - must be changed every quarter (January, April, July and October) to a different value ("passphrase rotation" or "rollover")
35
+    - must actually be different from the previous *two* passphrases
36
+
37
+</div>
38
+
39
+[2FA]: https://en.wikipedia.org/wiki/Two-factor_authentication
40
+
41
+## Installing `derivepassphrase`
42
+
43
+Install `pipx`:
44
+
45
+~~~~ shell-session
46
+$ cd ~
47
+$ python3 -m venv .venv
48
+$ . .venv/bin/activate
49
+$ pip install pipx
50
+~~~~
51
+
52
+Install `derivepassphrase`:
53
+
54
+~~~~ shell-session
55
+$ pipx install derivepassphrase
56
+~~~~
57
+
58
+Check that the installation was successful.
59
+
60
+~~~~ shell-session
61
+$ devirepassphrase --version
62
+derivepassphrase, version 0.2.0
63
+~~~~
64
+
65
+(…or similar output.)
66
+
67
+## Choosing a master passphrase
68
+
69
+`derivepassphrase` uses a master passphrase `MP`, and derives all other passphrases `P` from `MP`.
70
+We shall choose the master passphrase: `I am an insecure master passphrase, but easy to type.`
71
+
72
+## Setting up the email account
73
+
74
+In `derivepassphrase`, each passphrase configuration contains a *service name*, which is how `derivepassphrase` distinguishes between configurations.
75
+This service name can be chosen freely, but the resulting passphrase depends on the chosen service name.
76
+For our email account, we choose the straightforward service name `email`.
77
+
78
+We need to translate the passphrase policy into options for `derivepassphrase`:
79
+
80
+- A policy "(at least) `n` upper case letters" translates to the option `--lower n`, for any `n` greater than 0.
81
+  Lower case letters (`--upper`), digits (`--number`), symbols (`--symbol`), spaces (`--space`) and dashes (`--dash`) work similarly.
82
+- A policy "spaces *forbidden*" translates to the option `--space 0`.
83
+  Again, other character classes behave similarly.
84
+- A policy "no character immediately repeated more than `n` times" translates to the option `--repeat n`, for any `n` greater than 0.
85
+  In particular, `--repeat 1` means no character may be immediately repeated.
86
+* A policy "between `n` and `m` characters long" translates to `--length k`, for any `k` between `n` and `m` which you choose.
87
+  (`derivepassphrase` does not explicitly choose a passphrase length for you.)
88
+
89
+For the `email` service, we choose passphrase length 12.
90
+This leads to the command-line options `--length 12 --space 0 --upper 1 --lower 1 --number 1 --repeat 3`.
91
+Because we are using a master passphrase, we also need the `-p` option.
92
+
93
+!!! note "Note: interactive input"
94
+
95
+    In code listings, sections enclosed in `[[...]]` signify input to the program, for you to type or paste in.
96
+
97
+    Also, it is normal for passphrase prompts to not "echo" the text you type in.
98
+
99
+~~~~ shell-session
100
+$ derivepassphrase vault --length 12 --space 0 --upper 1 --lower 1 \
101
+>                        --number 1 --repeat 3 -p email
102
+Passphrase: [[I am an insecure master passphrase, but easy to type.]]
103
+kEFwoD=C?@+7
104
+~~~~
105
+
106
+By design, we can re-generate the same passphrase using the same input to `derivepassphrase`:
107
+
108
+~~~~ shell-session
109
+$ derivepassphrase vault --length 12 --space 0 --upper 1 --lower 1 \
110
+>                        --number 1 --repeat 3 -p email
111
+Passphrase: [[I am an insecure master passphrase, but easy to type.]]
112
+kEFwoD=C?@+7
113
+~~~~
114
+
115
+We can then visit our email provider and change the passphrase to `kEFwoD=C?@+7`.
116
+
117
+### Storing the settings to disk
118
+
119
+Because it is tedious to memorize and type in the correct settings to re-generate this passphrase, `derivepassphrase` can optionally store these settings, using the `--config` option.
120
+
121
+~~~~ shell-session
122
+$ derivepassphrase vault --config --length 12 --space 0 --upper 1 --lower 1 \
123
+>                        --number 1 --repeat 3 email
124
+~~~~
125
+
126
+!!! warning "Warning: `-p` and `--config`"
127
+
128
+    Do **not** use the `-p` and the `--config` options together to store the master passphrase!
129
+    The configuration is assumed to *not contain sensitive contents* and is *not encrypted*, so your master passphrase is then visible to *anyone* with appropriate priviledges!
130
+
131
+Check that the settings are stored correctly:
132
+
133
+~~~~ shell-session
134
+$ derivepassphrase vault --export -
135
+{"services": {"email": {"length": 12, "repeat": 3, "lower": 1, "upper": 1, "number": 1, "space": 0}}}
136
+~~~~
137
+
138
+Once the settings are stored, only the service name and the master passphrase option are necessary:
139
+
140
+~~~~ shell-session
141
+$ derivepassphrase vault -p email
142
+Passphrase: [[I am an insecure master passphrase, but easy to type.]]
143
+kEFwoD=C?@+7
144
+~~~~
145
+
146
+## Setting up the bank account
147
+
148
+We choose the straightforward service name `bank`.
149
+The passphrase policy leads to the command-line options `--length 5 --lower 0 --upper 0 --number 5 --space 0 --dash 0 --symbol 0`.
150
+
151
+The additional one-time password is generated by the hardware token, and therefore out of the scope for `derivepassphrase`.
152
+
153
+The rest is similar to the `email` account: we configure our stored settings, generate the passphrase, and request the bank change the account passphrase to match the generated passphrase.
154
+
155
+~~~~ shell-session
156
+$ derivepassphrase vault --config --length 5 --lower 0 --upper 0 --number 5 \
157
+>                        --space 0 --dash 0 --symbol 0 bank
158
+$ derivepassphrase vault -p bank
159
+Passphrase: [[I am an insecure master passphrase, but easy to type.]]
160
+98517
161
+~~~~
162
+
163
+## Setting up the work account
164
+
165
+We first take care of the first two constraints (passphrase length and permitted/required characters), then deal with the passphrase change/reuse aspects afterwards.
166
+Again, we start with the straightforward service name `work`, we choose "upper case letters" to fulfill the "1 letter" requirement, and add the options `--length 8 --space 0 --symbol 1 --upper 1 --number 1`.
167
+
168
+~~~~ shell-session
169
+$ derivepassphrase vault --length 8 --space 0 --symbol 1 --upper 1 --number 1 \
170
+>                        -p work
171
+Passphrase: [[I am an insecure master passphrase, but easy to type.]]
172
+r?9\XQR&
173
+~~~~
174
+
175
+Then we attempt to set the work passphrase to `r?9\XQR&`… but our employer's identity management system returns an error: `illegal character: &`.
176
+What happened?
177
+
178
+### Complication 1: What is a (permitted) "special character"?
179
+
180
+`derivepassphrase` considers the characters `!"#$%&'()*+,./:;<=>?@[\]^{|}~-_'` to be permitted special characters.
181
+Other service providers may permit other characters (quite rare) or fewer characters (quite common).
182
+(Service providers may also *not* explicitly say which special characters they permit, except through trial and error.)
183
+
184
+!!! abstract "Further reading"
185
+
186
+    → How to deal with "supported" and "unsupported" special characters (TODO)
187
+
188
+For this case specifically, we restrict ourselves to the dashes as the only permitted special characters, and hope that this passes their passphrase policy.
189
+
190
+~~~~ shell-session
191
+$ derivepassphrase vault --length 8 --space 0 --symbol 0 --dash 1 \
192
+>                        --upper 1 --number 1 -p work
193
+Passphrase: [[I am an insecure master passphrase, but easy to type.]]
194
+it90-HPO
195
+~~~~
196
+
197
+This works.
198
+For now.
199
+
200
+### Complication 2: How to implement passphrase rotation?
201
+
202
+`derivepassphrase` can only ever derive one passphrase per configuration, so passphrase rotation cannot be accomplished by reusing the same configuration.
203
+So some part of the configuration---generally the service name---needs to change upon each rotation.
204
+
205
+!!! abstract "Further reading"
206
+
207
+    → How to deal with regular passphrase rotation (TODO)
208
+
209
+We choose to append a very coarse timestamp to the "base" service name `work`: the 4-digit year, a `Q`, and the "quarter" number (1, 2, 3 or 4).
210
+As of October 2024, this leads to the final service name `work-2024Q4`.
211
+
212
+~~~~ shell-session
213
+$ derivepassphrase vault --config --length 8 --space 0 --symbol 0 --dash 1 \
214
+>                        --upper 1 --number 1 work-2024Q4
215
+$ derivepassphrase vault -p work-2024Q4
216
+Passphrase: [[I am an insecure master passphrase, but easy to type.]]
217
+-P268G0A
218
+~~~~
219
+
220
+## Summary
221
+
222
+We have installed `derivepassphrase` and set up three accounts for use with the `vault` passphrase derivation scheme, and the master passphrase `I am an insecure master passphrase, but easy to type.`.
223
+Our configuration should look like this:
224
+
225
+~~~~ shell-session
226
+$ derivepassphrase vault --export -
227
+{"services": {"email": {"length": 12, "repeat": 3, "lower": 1, "upper": 1, "number": 1, "space": 0}, "bank": {"length": 5, "lower": 0, "upper": 0, "number": 5, "space": 0, "dash": 0, "symbol": 0}, "work-2024Q4": {"length": 8, "upper": 1, "number": 1, "space": 0, "dash": 1, "symbol": 0}}}
228
+~~~~
229
+
230
+We should also get the following output when asking for those passphrases again:
231
+
232
+~~~~ shell-session
233
+$ derivepassphrase vault -p email
234
+Passphrase: [[I am an insecure master passphrase, but easy to type.]]
235
+kEFwoD=C?@+7
236
+$ derivepassphrase vault -p bank
237
+Passphrase: [[I am an insecure master passphrase, but easy to type.]]
238
+98517
239
+$ derivepassphrase vault -p work-2024Q4
240
+Passphrase: [[I am an insecure master passphrase, but easy to type.]]
241
+-P268G0A
242
+~~~~
243
+
244
+This completes the tutorial.
... ...
@@ -89,6 +89,8 @@ plugins:
89 89
 nav:
90 90
   - Overview: index.md
91 91
   #- Tutorials & Examples: tutorials.md
92
+  - Tutorials & Examples:
93
+    - tutorials/basic-setup-password.md
92 94
   #- How-Tos: how-tos.md
93 95
   - Reference:
94 96
     - reference/index.md
... ...
@@ -107,6 +109,8 @@ nav:
107 109
   - Changelog: changelog.md
108 110
 exclude_docs: |
109 111
   changelog.d
112
+not_in_nav: |
113
+  _future.md
110 114
 
111 115
 markdown_extensions:
112 116
   - abbr
... ...
@@ -118,6 +122,7 @@ markdown_extensions:
118 122
   - smarty
119 123
   - toc:
120 124
       permalink: true
125
+  - pymdownx.details
121 126
   - pymdownx.superfences
122 127
   - pymdownx.tabbed:
123 128
       alternate_style: true
124 129