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 |