Overhaul the SSH key tutorial, also aligning it with the SSH key how-to
Marco Ricci

Marco Ricci commited on 2026-03-14 17:33:38
Zeige 5 geänderte Dateien mit 103 Einfügungen und 19 Löschungen.


On The Annoying OS, we add screenshots for the steps involving `pageant`
and `puttygen`, because we cannot present a verbatim shell transcript.
The instructions avoid giving motor instructions ("click on ...", "type
... in", etc.) as much as possible, both for consistency with the UNIX
instructions and to focus on the higher-level operations instead.  This
also avoids doing users with motor impairments or unusual input device
setups the disservice of giving them instructions they cannot follow.

We add a definition for "key rotation", and further short commentary on
key compartmentalization and locking the agent (or the key in the
agent).

We align the visual style of both this tutorial and the SSH key how-to
by using the text framing approach from the latter to frame alternate
blocks of content (e.g. operating system-specific instructions), either
explicitly or implicitly, as needed. We ensure that this style is also
used consistently in the how-to as well. Finally, we also add the
`pageant` logo to the how-to, and image credits for the logo on both
pages.
... ...
@@ -19,15 +19,23 @@
19 19
 
20 20
 Assuming the prerequisites are satisfied, ensure that the SSH agent is
21 21
 running, the SSH key is loaded into the agent, and that
22
-`derivepassphrase` knows how to obtain the agent's socket address:
22
+`derivepassphrase` can <i>discover</i> the agent:
23 23
 
24
-- On UNIX systems, the `SSH_AUTH_SOCK` environment variable must be
24
+!!! info "Making the SSH agent discoverable"
25
+
26
+    === "on UNIX"
27
+
28
+        …the `SSH_AUTH_SOCK` environment variable must be correctly set up.
29
+
30
+    === "on Windows"
31
+
32
+        …by default, the `SSH_AUTH_SOCK` environment variable must be
25 33
         correctly set up.
26
-- On Windows systems, by default, the `SSH_AUTH_SOCK` environment
27
-  variable must be correctly set up.
34
+
28 35
         Alternatively, `derivepassphrase` can be explicitly configured to
29
-  connect to OpenSSH or Pageant (PuTTY) without consulting
30
-  `SSH_AUTH_SOCK`, in which case OpenSSH or Pageant must be running.
36
+        connect to OpenSSH or Pageant (PuTTY) directly, without consulting
37
+        `SSH_AUTH_SOCK`.
38
+        In that case, the respective agent must be running.
31 39
 
32 40
 The exact commands depend on the SSH agent in use.
33 41
 
... ...
@@ -114,6 +122,17 @@ The exact commands depend on the SSH agent in use.
114 122
 
115 123
         === "on Windows"
116 124
 
125
+            <div style="float: right;">
126
+
127
+            <figure markdown>
128
+            ![A CRT monitor wearing a spy hat.][PAGEANT_ICON]{ width="96" loading=lazy }
129
+            <figcaption>
130
+            The `pageant` icon
131
+            </figcaption>
132
+            </figure>
133
+
134
+            </div>
135
+
117 136
             Start Pageant; this adds the Pageant icon to the Windows task
118 137
             bar.
119 138
             Then add the key via the right-click context menu, "Add key" or
... ...
@@ -124,10 +143,10 @@ The exact commands depend on the SSH agent in use.
124 143
             re-encrypting it, meaning that the key cannot be used by
125 144
             malicious clients while encrypted.
126 145
             This can be used to partially alleviate the lack of support for
127
-            the "key timeout" constraint.
146
+            the "key timeout" and "confirm on use" constraint.
128 147
             The "Add key (encrypted)" mode is thus *recommended*.
129 148
 
130
-            Finally, inform `derivepassphrase` about the Pageant's address:
149
+            Finally, inform `derivepassphrase` about Pageant's address:
131 150
 
132 151
             === "`pageant_on_windows` socket provider"
133 152
 
... ...
@@ -244,6 +263,8 @@ The exact commands depend on the SSH agent in use.
244 263
 
245 264
 Next, configure `derivepassphrase vault` to use the loaded SSH key.
246 265
 
266
+!!! quote ""
267
+
247 268
     === "global key"
248 269
 
249 270
         ~~~~ console
... ...
@@ -283,8 +304,19 @@ Next, configure `derivepassphrase vault` to use the loaded SSH key.
283 304
     → Tradeoffs between a master passphrase and a master SSH key,
284 305
     section "Should I use one master SSH key, or many keys?" (TODO)
285 306
 
307
+<aside markdown>
308
+
309
+??? abstract "Image credits"
310
+
311
+    - The `pageant` logo is part of the PuTTY software package, generated from source files contained within.
312
+      [License][PUTTY_ICONS_LICENSE]
313
+
314
+</aside>
315
+
286 316
 [OPENSSH_ON_WINDOWS_LIMITATIONS]: ../reference/prerequisites-ssh-key.md#agent-specific-notes
287 317
 [OPENSSH_ON_WINDOWS_DOC]: https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh_keymanagement#user-key-generation
318
+[PAGEANT_ICON]: ../tutorials/pageant.svg
319
+[PUTTY_ICONS_LICENSE]: https://git.tartarus.org/?p=simon/putty.git;a=blob;f=LICENCE;h=091556577ce55d3502f121460668c5495de91baa;hb=refs/tags/0.83 "License for the PuTTY software suite (and icons)"
288 320
 
289 321
 [PREREQ]: ../reference/prerequisites-ssh-key.md
290 322
 [PREREQ_AGENT_SPECIFIC_NOTES]: ../reference/prerequisites-ssh-key.md#agent-specific-notes
... ...
@@ -48,6 +48,8 @@ Without support for SSH keys, this tutorial cannot be completed.
48 48
 `derivepassphrase` cannot generate SSH keys or do SSH key operations itself; instead, it relies on widespread and well-tested third-party software such as OpenSSH or PuTTY for this purpose.
49 49
 We need to install such software as well.
50 50
 
51
+!!! info "Setup steps"
52
+
51 53
     === "UNIX (and Cygwin/MSYS, WSL, and Git for Windows)"
52 54
 
53 55
         You likely already have OpenSSH installed, or can easily install them via your package manager or via [the official OpenSSH distribution][OPENSSH].
... ...
@@ -62,7 +64,7 @@ We need to install such software as well.
62 64
         (Some desktop environments automatically launch an agent on startup.)
63 65
         We can check this via `ssh-add -l`.
64 66
 
65
-    === "Could not open a connection…"
67
+        === "&quot;Could not open a connection…&quot;"
66 68
 
67 69
             ~~~~ shell-session
68 70
             $ ssh-add -l
... ...
@@ -82,7 +84,7 @@ We need to install such software as well.
82 84
             $ trap "kill $SSH_AGENT_PID" 0
83 85
             ~~~~
84 86
 
85
-    === "The agent has no identities."
87
+        === "&quot;The agent has no identities.&quot;"
86 88
 
87 89
             ~~~~ shell-session
88 90
             $ ssh-add -l
... ...
@@ -91,7 +93,7 @@ We need to install such software as well.
91 93
 
92 94
             The agent is already running.
93 95
 
94
-    === "(numbers, random characters, …)"
96
+        === "random gibberish"
95 97
 
96 98
             ~~~~ shell-session
97 99
             $ ssh-add -l
... ...
@@ -108,7 +110,7 @@ We need to install such software as well.
108 110
         <div style="float: right;">
109 111
 
110 112
         <figure markdown>
111
-    ![A CRT monitor wearing a spy hat.][PAGEANT_ICON]{ width="96" }
113
+        ![A CRT monitor wearing a spy hat.][PAGEANT_ICON]{ width="96" loading=lazy }
112 114
         <figcaption>
113 115
         [The `pageant` icon][PUTTY_ICON_HISTORY]
114 116
         </figcaption>
... ...
@@ -135,13 +137,21 @@ We need to install such software as well.
135 137
 ??? warning "Operational risk: reusing &quot;login&quot; SSH keys for passphrase derivation"
136 138
 
137 139
     SSH keys are typically used as access tokens for logging in on a remote system.
138
-    You are **discouraged** from reusing such an existing "login" key for passphrase derivation.
139
-    A master SSH key is a **long-lived secret**, and should **never need to be rotated, unless compromised or lost**.
140
+    You are **strongly discouraged** from reusing such an existing "login" key for passphrase derivation.
141
+    A master SSH key is a **long-lived secret**, and should **never need to be rotated[^key-rotation-def], unless compromised or lost**.
140 142
     Rotating a master SSH key means **forcibly changing all passphrases that are derived from this key**.
141
-    By contrast, a login SSH key is an access token, and may be rotated for other policy-related reasons (e.g. "upgrades" to a different algorithm, consolidation of multiple keys into a smaller set of new keys, or artificially introduced key expiry).
143
+    By contrast, a login SSH key is an access token, and may be rotated for other policy-related reasons (e.g. algorithm or key size upgrades, key consolidation, …).
144
+
145
+    Beyond key rotation, reusing an existing login key also means that, when compromised, **all your logins *and* all your passphrases will be affected**.
146
+
147
+[^key-rotation-def]: <dfn>key rotation</dfn>: the exchange of a cryptographic key against a newer one, for the same purpose/access/capabilities as the old one, as a matter of policy, to artificially limit the scope of the old key.
148
+    Usually done on a schedule.
149
+    Typical policy reasons include protection against loss of access to the key material, and upgrades to different algorithms or key sizes (where possible).
142 150
 
143 151
 We generate a new Ed25519-type key for use with `derivepassphrase`.
144 152
 
153
+!!! info "Generating a key (operating system-specific)"
154
+
145 155
     === "UNIX (and Cygwin/MSYS, WSL, and Git for Windows)"
146 156
 
147 157
         We store the key as `my-vault-ed25519-key` in `~/.ssh`, using the comment "vault key".
... ...
@@ -172,12 +182,24 @@ We generate a new Ed25519-type key for use with `derivepassphrase`.
172 182
     === "Windows"
173 183
 
174 184
         Start `puttygen`.
175
-    Under "Parameters", as "Type of key to generate", select **EdDSA**, and as "Curve to use for generating this key", select **Ed25519 (256 bits)**.
185
+        Under "Parameters", as "Type of key to generate", select **EdDSA**, and as "Curve to use for generating this key", select **Ed25519 (255 bits)**.
176 186
         Then, under "Actions", select "Generate", and follow the on-screen instructions.
187
+
188
+        <figure markdown>
189
+        ![puttygen's key generation parameters][PUTTYGEN_KEY_PARAMETERS]{ loading=lazy }
190
+        </figure>
191
+
177 192
         Set the comment to "vault key", and set a strong key passphrase (*recommended*).
178 193
         Finally, select "Save private key", and store the key as `my-vault-ed25519-key.ppk` in `My Documents`.
179 194
         We can now close `puttygen`.
180 195
 
196
+        <figure markdown>
197
+        ![puttygen after key generation][PUTTYGEN_KEY_GENERATION]{ loading=lazy }
198
+        </figure>
199
+
200
+[PUTTYGEN_KEY_PARAMETERS]: puttygen-key-parameters.png
201
+[PUTTYGEN_KEY_GENERATION]: puttygen-key-generation.png
202
+
181 203
 <section id="sample-key" markdown>
182 204
 
183 205
 !!! note "Note: reproducibility"
... ...
@@ -198,6 +220,8 @@ We generate a new Ed25519-type key for use with `derivepassphrase`.
198 220
 We then need to load the key into the agent, so that `derivepassphrase` can interact with it.
199 221
 The key will persist as long as the agent is running, and will need to be re-added the next time the agent is started.
200 222
 
223
+!!! info "Loading the key into the agent (operating system-specific)"
224
+
201 225
     === "UNIX (and Cygwin/MSYS, WSL, and Git for Windows)"
202 226
 
203 227
         We instruct the agent to pop up a confirmation prompt each time the key is used, as a safety precaution.
... ...
@@ -209,16 +233,29 @@ The key will persist as long as the agent is running, and will need to be re-add
209 233
         The user must confirm each use of the key
210 234
         ~~~~
211 235
 
236
+        Now each call to `derivepassphrase vault` using this SSH key (only when deriving a passphrase) will ellicit a confirmation prompt by the agent.
237
+        Conversely, any confirmation prompt for this key *at other times* originates from a *different* program, and is therefore suspicious and should not be granted.
238
+        (See operational risks above.)
239
+
212 240
     === "Windows"
213 241
 
214
-    Right-click on the `pageant` icon (the CRT computer monitor with the black hat) in the Windows task bar, then select "Add key (encrypted)".
215
-    Select `my-vault-ed25519-key.ppk` in `My Documents`.
242
+        Open `pageant`'s context menu (via right-click), then select "Add key (encrypted)".
243
+        In the file chooser dialog that opens, select `my-vault-ed25519-key.ppk` in `My Documents`.
216 244
         The key should now be loaded.
217
-    Double-click on the `pageant` icon, or right-click and then select "View keys", to bring up the list of keys `pageant` is currently holding in memory.
245
+
246
+        <figure markdown>
247
+        ![pageant context menu][PAGEANT_CONTEXT_MENU]{ loading=lazy }
248
+        </figure>
249
+
250
+        To verify this, select "View keys" from `pageant`'s context menu to bring up the list of keys `pageant` is currently holding in memory.
218 251
         The Ed25519 key we just created should be listed there, along with the "vault key" comment.
219 252
 
220 253
         Upon first use of the key, `pageant` will issue a passphrase prompt for the key passphrase.
221 254
         The key will be unlocked, and thus usable without prompts, until it is re-encrypted in the "View keys" menu.
255
+        Re-encrypt/lock the key whenever you are done using it with `derivepassphrase` to minimize the time window during which the key is accessible to other programs.
256
+        (See operational risks above.)
257
+
258
+[PAGEANT_CONTEXT_MENU]: pageant-context-menu.png
222 259
 
223 260
 ## Reconfiguring the accounts
224 261
 
... ...
@@ -250,6 +287,8 @@ Passphrase: [[I am an insecure master passphrase, but easy to type.]]
250 287
 We first reconfigure the `email` account to use the master SSH key.
251 288
 `derivepassphrase` presents us with a key selector for all SSH keys suitable for passphrase derivation, including the one we generated earlier.
252 289
 
290
+!!! quote ""
291
+
253 292
     === "Only one suitable key"
254 293
 
255 294
         We confirm the selection.
... ...
@@ -302,6 +341,8 @@ To get the other two services to use the master SSH key as well, we *could* reco
302 341
 However, that is unnecessarily repetitive.
303 342
 Instead, we will set up `derivepassphrase` to use this master SSH key by default.
304 343
 
344
+!!! quote ""
345
+
305 346
     === "Only one suitable key"
306 347
 
307 348
         ~~~~ shell-session
... ...
@@ -387,8 +428,19 @@ pEY-qg7n
387 428
 
388 429
 This completes the tutorial.
389 430
 
431
+<aside markdown>
432
+
433
+??? abstract "Image credits"
434
+
435
+    - The `pageant` logo is part of the PuTTY software package, generated from source files contained within.
436
+      [License][PUTTY_ICONS_LICENSE]
437
+
438
+</aside>
439
+
390 440
 [BASIC_SETUP_PASSPHRASE]: basic-setup-passphrase.md
391 441
 [PREREQ_SSH_KEY]: ../reference/prerequisites-ssh-key.md#ssh-key
392 442
 
393 443
 [OPENSSH]: https://www.openssh.org/
394 444
 [PUTTY]: https://putty.software/
445
+
446
+[PUTTY_ICONS_LICENSE]: https://git.tartarus.org/?p=simon/putty.git;a=blob;f=LICENCE;h=091556577ce55d3502f121460668c5495de91baa;hb=refs/tags/0.83 "License for the PuTTY software suite (and icons)"