Rework the documentation concerning SSH agent use
Marco Ricci

Marco Ricci commited on 2026-01-21 22:55:28
Zeige 2 geänderte Dateien mit 268 Einfügungen und 60 Löschungen.

... ...
@@ -18,10 +18,21 @@
18 18
 ## Configuring `derivepassphrase vault` to use an SSH key
19 19
 
20 20
 Assuming the prerequisites are satisfied, ensure that the SSH agent is
21
-running, the SSH key is loaded into the agent, and, on UNIX systems,
22
-that the `SSH_AUTH_SOCK` environment variable is correctly set up.
21
+running, the SSH key is loaded into the agent, and that
22
+`derivepassphrase` knows how to obtain the agent's socket address:
23
+
24
+- On UNIX systems, the `SSH_AUTH_SOCK` environment variable must be
25
+  correctly set up.
26
+- On Windows systems, by default, the `SSH_AUTH_SOCK` environment
27
+  variable must be correctly set up.
28
+  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.
31
+
23 32
 The exact commands depend on the SSH agent in use.
24 33
 
34
+!!! info "Setup commands"
35
+
25 36
     === "OpenSSH"
26 37
 
27 38
         === "on UNIX"
... ...
@@ -48,9 +59,7 @@ The exact commands depend on the SSH agent in use.
48 59
 
49 60
             ([Using OpenSSH on Windows is possible, but currently *not
50 61
             recommended*; we recommend Pageant
51
-        instead.][OPENSSH_ON_WINDOWS_LIMITATIONS]
52
-        Pageant has priority over OpenSSH: if both are running,
53
-        `derivepassphrase vault` will connect to Pageant.)
62
+            instead.][OPENSSH_ON_WINDOWS_LIMITATIONS])
54 63
 
55 64
             The agent is started as a system service.
56 65
             This only needs to be set up once.
... ...
@@ -78,8 +87,28 @@ The exact commands depend on the SSH agent in use.
78 87
 
79 88
             (Your key filename and key comment will likely differ.)
80 89
 
81
-        [OPENSSH_ON_WINDOWS_LIMITATIONS]: ../reference/prerequisites-ssh-key.md#agent-specific-notes
82
-        [OPENSSH_ON_WINDOWS_DOC]: https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh_keymanagement#user-key-generation
90
+            Finally, inform `derivepassphrase` about the OpenSSH agent's
91
+            address:
92
+
93
+            === "`openssh_on_windows` socket provider"
94
+
95
+                Edit the file
96
+                <code>C:\&#x200b;Users\&#x200b;&lt;username>&#x200b;AppData\&#x200b;Roaming\&#x200b;derivepassphrase\&#x200b;config.toml</code>
97
+                and set the key `vault.ssh-agent-socket-provider` to
98
+                `openssh_on_windows`:
99
+
100
+                ~~~~ toml title="config.toml"
101
+                [vault]
102
+                ssh-agent-socket-provider = "openssh_on_windows"
103
+                ~~~~
104
+
105
+            === "`SSH_AUTH_SOCK` on Windows (not recommended)"
106
+
107
+                (The "native" SSH agent socket provider must be in use.)
108
+
109
+                ~~~~ pwsh-session title="Further setup commands (Powershell, as User): setting SSH_AUTH_SOCK"
110
+                PS> $env:SSH_AUTH_SOCK = "\\.\pipe\openssh-ssh-agent"
111
+                ~~~~
83 112
 
84 113
     === "PuTTY"
85 114
 
... ...
@@ -98,6 +127,39 @@ The exact commands depend on the SSH agent in use.
98 127
             the "key timeout" constraint.
99 128
             The "Add key (encrypted)" mode is thus *recommended*.
100 129
 
130
+            Finally, inform `derivepassphrase` about the Pageant's address:
131
+
132
+            === "`pageant_on_windows` socket provider"
133
+
134
+                Edit the file
135
+                <code>C:\&#x200b;Users\&#x200b;&lt;username>&#x200b;AppData\&#x200b;Roaming\&#x200b;derivepassphrase\&#x200b;config.toml</code>
136
+                and set the key `vault.ssh-agent-socket-provider` to
137
+                `pageant_on_windows`:
138
+
139
+                ~~~~ toml title="config.toml"
140
+                [vault]
141
+                ssh-agent-socket-provider = "pageant_on_windows"
142
+                ~~~~
143
+
144
+            === "`SSH_AUTH_SOCK` on Windows (not recommended)"
145
+
146
+                (The "native" SSH agent socket provider must be in use.)
147
+
148
+                Pageant's address is unfortunately not fixed.
149
+                To get Pageant to write out its socket address on startup,
150
+                start it with the `--openssh-config <filename>` option to
151
+                write an OpenSSH-compatible configuration snippet to
152
+                `<filename>`, which includes the address.
153
+
154
+                ~~~~ pwsh-session title="Further setup commands (Powershell, as User): setting SSH_AUTH_SOCK"
155
+                PS> pageant --openssh-config file.conf
156
+                PS> 
157
+                PS> # Now read file.conf to learn the address; it looks like
158
+                PS> # "\\.\pipe\pageant.<username>.0123456789abcdef..."
159
+                PS>
160
+                PS> $env:SSH_AUTH_SOCK = "\\.\pipe\pageant.YourUsernameHere.0123456789deadbeef..."
161
+                ~~~~
162
+
101 163
         === "on UNIX"
102 164
 
103 165
             ~~~~ console title="Typical setup commands: starting the agent and loading the key"
... ...
@@ -117,22 +179,15 @@ The exact commands depend on the SSH agent in use.
117 179
             $ # This is equivalent to passing --enable-ssh-support upon agent
118 180
             $ # startup.
119 181
             $ echo enable-ssh-support:0:1 | gpgconf --change-options gpg-agent
182
+            $ # Then export the SSH_AUTH_SOCK environment variable appropriately.
183
+            $ export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
120 184
             ~~~~
121 185
 
122
-    === "on Windows"
123
-
124
-        ~~~~ pwsh-session title="Typical setup commands (PowerShell): enabling SSH agent support in GnuPG"
125
-        PS> # This is equivalent to passing --enable-ssh-support upon agent
126
-        PS> # startup.
127
-        PS> echo enable-ssh-support:0:1 | gpgconf --change-options gpg-agent
128
-        ~~~~
129
-
130
-    (Loading native SSH keys into `gpg-agent` requires a separate SSH
131
-    agent client such as OpenSSH; see the [agent-specific notes in the
186
+            (Loading native SSH keys into `gpg-agent` requires
187
+            a separate SSH agent client such as OpenSSH; see the
188
+            [agent-specific notes in the
132 189
             prerequisites][PREREQ_AGENT_SPECIFIC_NOTES].)
133 190
 
134
-    === "on UNIX"
135
-
136 191
             ~~~~ console title="Typical setup commands: loading the key into the agent with the OpenSSH tools"
137 192
             $ ssh-add -c ~/.ssh/my-vault-ed25519-key
138 193
             Enter passphrase for /home/user/.ssh/my-vault-ed25519-key (will confirm each use): 
... ...
@@ -140,8 +195,44 @@ The exact commands depend on the SSH agent in use.
140 195
             The user must confirm each use of the key
141 196
             ~~~~
142 197
 
198
+            (Your key filename and key comment may differ.)
199
+
143 200
         === "on Windows"
144 201
 
202
+            Edit the file `gpg-agent.conf` in the GnuPG home directory to
203
+            contain the line `enable-win32-openssh-support`, which is
204
+            equivalent to passing `--enable-win32-openssh-support` upon
205
+            agent startup.
206
+            This causes `gpg-agent` to masquerade as OpenSSH`s agent.
207
+
208
+            Then, inform `derivepassphrase` about the agent's address,
209
+            i.e., of the OpenSSH agent's socket address:
210
+
211
+            === "`openssh_on_windows` socket provider"
212
+
213
+                Edit the file
214
+                <code>C:\&#x200b;Users\&#x200b;&lt;username>&#x200b;AppData\&#x200b;Roaming\&#x200b;derivepassphrase\&#x200b;config.toml</code>
215
+                and set the key `vault.ssh-agent-socket-provider` to
216
+                `openssh_on_windows`:
217
+
218
+                ~~~~ toml title="config.toml"
219
+                [vault]
220
+                ssh-agent-socket-provider = "openssh_on_windows"
221
+                ~~~~
222
+
223
+            === "`SSH_AUTH_SOCK` on Windows (not recommended)"
224
+
225
+                (The "native" SSH agent socket provider must be in use.)
226
+
227
+                ~~~~ pwsh-session title="Further setup commands (Powershell, as User): setting SSH_AUTH_SOCK"
228
+                PS> $env:SSH_AUTH_SOCK = "\\.\pipe\openssh-ssh-agent"
229
+                ~~~~
230
+
231
+            (Loading native SSH keys into `gpg-agent` requires
232
+            a separate SSH agent client such as OpenSSH; see the
233
+            [agent-specific notes in the
234
+            prerequisites][PREREQ_AGENT_SPECIFIC_NOTES].)
235
+
145 236
             ~~~~ console title="Typical setup commands (PowerShell): loading the key into the agent with the OpenSSH tools"
146 237
             $ ssh-add "C:\Users\YourUsernameHere\Documents\my-vault-ed25519-key"
147 238
             Enter passphrase for C:\Users\YourUsernameHere\Documents\my-vault-ed25519-key (will confirm each use): 
... ...
@@ -192,5 +283,8 @@ Next, configure `derivepassphrase vault` to use the loaded SSH key.
192 283
     → Tradeoffs between a master passphrase and a master SSH key,
193 284
     section "Should I use one master SSH key, or many keys?" (TODO)
194 285
 
286
+[OPENSSH_ON_WINDOWS_LIMITATIONS]: ../reference/prerequisites-ssh-key.md#agent-specific-notes
287
+[OPENSSH_ON_WINDOWS_DOC]: https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh_keymanagement#user-key-generation
288
+
195 289
 [PREREQ]: ../reference/prerequisites-ssh-key.md
196 290
 [PREREQ_AGENT_SPECIFIC_NOTES]: ../reference/prerequisites-ssh-key.md#agent-specific-notes
... ...
@@ -41,7 +41,7 @@ on their respective operating system.
41 41
         [The Windows port of OpenSSH lacks support for key constraints
42 42
         [1]][OPENSSH_ON_WINDOWS_NO_KEY_CONSTRAINTS_1]
43 43
         [[2]][OPENSSH_ON_WINDOWS_NO_KEY_CONSTRAINTS_2], which are the
44
-        main advantage OpenSSH had over Pageant.
44
+        main advantage OpenSSH has over Pageant.
45 45
         Without this functionality, Pageant is the better choice: more
46 46
         supported key formats, manually lockable and unlockable key
47 47
         material in the agent, and no Administrator credentials needed
... ...
@@ -58,11 +58,32 @@ on their respective operating system.
58 58
         OpenSSH agent on Windows, instead of merely *assuming* it is
59 59
         doing so.
60 60
 
61
-        [OPENSSH_ON_WINDOWS_NO_KEY_CONSTRAINTS_1]: https://github.com/PowerShell/Win32-OpenSSH/issues/1056#issuecomment-362494167 "Issue #1056: ssh-agent should support '-c' and '-t' options of ssh-add"
62
-        [OPENSSH_ON_WINDOWS_NO_KEY_CONSTRAINTS_2]: https://github.com/PowerShell/Win32-OpenSSH/issues/2314#issuecomment-2529160589 'Issue #2314: Adding key with confirmation option to ssh-agent gives "agent refused operation"'
63
-
64 61
     === "GnuPG/`gpg-agent`"
65 62
 
63
+        ??? info "GnuPG terminology"
64
+
65
+            GnuPG home directory
66
+            :   The directory where GnuPG keeps its configuration;
67
+                defaults to
68
+                <code>C:\&#x200b;Users\&#x200b;&lt;username>\&#x200b;AppData\&#x200b;Roaming\&#x200b;gnupg</code>
69
+                on Windows and <code>~/&#x200b;.gnupg</code> on POSIX.
70
+                The user may set up multiple such directories.
71
+                Agents are bound to a specific home directory;
72
+                conversely, there can only be one agent per home
73
+                directory.
74
+
75
+            keygrip
76
+            :   A GnuPG-specific fingerprint for cryptographic keys.
77
+                Similar to the SSH key fingerprint, but not SSH-specific.
78
+
79
+            `sshcontrol`
80
+            :   A text file in the GnuPG home directory, listing the
81
+                keygrips of SSH-compatible keys which `gpg-agent` knows
82
+                about.
83
+                `gpg-agent` will only advertise keys from this list if
84
+                the corresponding private key is also known (on disk, on
85
+                a smartcard, etc.).
86
+
66 87
         * `gpg-agent` v2.0 and later uses a *persistent* database of
67 88
           known keys, SSH or otherwise.
68 89
           "Adding" a key to the agent actually means *importing* it, and
... ...
@@ -86,6 +107,65 @@ on their respective operating system.
86 107
           It is impossible to remove an SSH key from `gpg-agent` using
87 108
           standard SSH agent operations.
88 109
 
110
+            ??? info "Removing an SSH key from `gpg-agent` manually"
111
+
112
+                The list of SSH-capable keys currently held by
113
+                `gpg-agent` can be queried interactively with the
114
+                `gpg-connect-agent` tool:
115
+
116
+                === "SSH keys uploaded"
117
+
118
+                    ~~~~ console linenums="1"
119
+                    $ gpg-connect-agent 'KEYINFO --ssh-list --ssh-fpr=SHA256' /bye
120
+                    S KEYINFO 04779A9B67BC8930046D9ABA86F1F85E1957D593 D - - 1 C SHA256:0h+WAokssfhzfzVyuMLJlIcWyCtk5WiXI8BHyhXYxC0 - S
121
+                    S KEYINFO 9233C66A7A62D5866493F613D5F2E1A24343E048 D - - 1 C SHA256:1OHE0HrVlaSzJn2aQXQIKRu0tfO1CEMefy95K2Bt0xA - S
122
+                    OK
123
+                    ~~~~
124
+
125
+                === "OpenPGP keys used as SSH keys"
126
+
127
+                    ~~~~ console linenums="1"
128
+                    $ gpg-connect-agent 'KEYINFO --list --with-ssh --ssh-fpr=SHA256' /bye
129
+                    S KEYINFO 04779A9B67BC8930046D9ABA86F1F85E1957D593 D - - 1 C SHA256:0h+WAokssfhzfzVyuMLJlIcWyCtk5WiXI8BHyhXYxC0 - S
130
+                    S KEYINFO 9233C66A7A62D5866493F613D5F2E1A24343E048 D - - 1 C SHA256:1OHE0HrVlaSzJn2aQXQIKRu0tfO1CEMefy95K2Bt0xA - S
131
+                    OK
132
+                    ~~~~
133
+
134
+                The agent identifies cryptographic keys (of any kind) by
135
+                the keygrip (the third entry on each line, so
136
+                `04779A9B67BC8930046D9ABA86F1F85E1957D593` for the first
137
+                key and `9233C66A7A62D5866493F613D5F2E1A24343E048` for
138
+                the second key in the snippet above).
139
+                By matching the SSH fingerprint (the ninth entry on each
140
+                line), we can then determine the keygrip of the key we
141
+                wish to remove from the agent:
142
+
143
+                ~~~~ console linenums="6"
144
+                > DELETE_KEY 04779A9B67BC8930046D9ABA86F1F85E1957D593
145
+                OK
146
+                > DELETE_KEY 9233C66A7A62D5866493F613D5F2E1A24343E048
147
+                OK
148
+                ~~~~
149
+
150
+                (The agent will prompt for confirmation.)
151
+                We can then confirm that the key is no longer loaded
152
+                because the fourth entry changes from `D` ("on disk") to
153
+                `-` ("missing"):
154
+
155
+                ~~~~ console linenums="10"
156
+                > KEYINFO --ssh-list --ssh-fpr=SHA256
157
+                S KEYINFO 04779A9B67BC8930046D9ABA86F1F85E1957D593 - - - - - - - S
158
+                S KEYINFO 9233C66A7A62D5866493F613D5F2E1A24343E048 - - - - - - - S
159
+                OK
160
+                > BYE
161
+                OK closing connection
162
+                ~~~~
163
+
164
+                At this point, the keys are no longer available to the
165
+                agent, but still "known" to the agent.
166
+                To make `gpg-agent` "forget" them, the respective
167
+                keygrip needs to be removed from `sshcontrol`.
168
+
89 169
         * `gpg-agent` does not advertise its communication socket by
90 170
           default, contrary to other SSH agents, so it must be manually
91 171
           advertised:
... ...
@@ -120,30 +200,39 @@ on their respective operating system.
120 200
             === "Windows (OpenSSH emulation)"
121 201
 
122 202
                 From v2.4 onwards, `gpg-agent` supports masquerading as
123
-                OpenSSH's `ssh-agent` on Windows, by starting the agent
124
-                with the `--enable-win32-openssh-support` command-line
125
-                argument.
126
-                (Usually, this would be added to the `gpg-agent`
127
-                configuration file instead of being manually supplied on
128
-                the command-line.)
129
-
130
-                This mode is untested.
131
-                We, the `derivepassphrase` authors, do not know how to
132
-                run `gpg-agent` on Windows with masquerading as OpenSSH
133
-                enabled: the steps outlined in the official
134
-                documentation for `gpg-agent` do not work as advertised.
135
-                [We have asked for clarification on GnuPG's developer
136
-                mailing list.][GPG_AGENT_ON_WINDOWS_WTF]
137
-
138
-                [GPG_AGENT_ON_WINDOWS_WTF]: https://lists.gnupg.org/pipermail/gnupg-devel/2025-December/036116.html
203
+                OpenSSH's `ssh-agent` on Windows, by passing the
204
+                `--enable-win32-openssh-support` command-line argument
205
+                to the agent.
206
+                (Because of `gpg-agent`'s idiosyncratic autostart
207
+                behavior, it is usually simpler to add the corresponding
208
+                option `enable-win32-openssh-support` to the `gpg-agent`
209
+                configuration file instead.)
210
+
211
+                This mode is fully supported, at least as of GnuPG
212
+                version 2.4.8.
213
+                Note, however, that [the GnuPG developers consider this
214
+                communication endpoint support experimental and
215
+                untested][GPG_AGENT_OPENSSH_EMULATION_EXPERIMENTAL],[^gpg-agent-openssh-emulation-experimental]
216
+                so it is unclear if GnuPG will continue to provide this
217
+                masquerading functionality.
139 218
 
140 219
 </section>
141 220
 
142
-### A Python installation that can talk to the SSH agent { #python-support }
221
+[^gpg-agent-openssh-emulation-experimental]: This experimental status is
222
+    presumably specifically about the communication system in use
223
+    (Windows named pipes), which is only available on Windows and thus
224
+    impossible to test on other operating systems.
225
+    The GnuPG developers appear to have insufficient access to Windows
226
+    machines to continue testing and maintaining this subsystem.
227
+    ([The same lack of access to Windows machines originally affected
228
+    *our* development of SSH agent support on Windows for
229
+    `derivepassphrase` as well.][BUG_WINDOWS_SSH_AGENT_SUPPORT])
230
+
231
+[GPG_AGENT_OPENSSH_EMULATION_EXPERIMENTAL]: https://dev.gnupg.org/T8013#210624
232
+[OPENSSH_ON_WINDOWS_NO_KEY_CONSTRAINTS_1]: https://github.com/PowerShell/Win32-OpenSSH/issues/1056#issuecomment-362494167 "Issue #1056: ssh-agent should support '-c' and '-t' options of ssh-add"
233
+[OPENSSH_ON_WINDOWS_NO_KEY_CONSTRAINTS_2]: https://github.com/PowerShell/Win32-OpenSSH/issues/2314#issuecomment-2529160589 'Issue #2314: Adding key with confirmation option to ssh-agent gives "agent refused operation"'
143 234
 
144
-As of version 0.6, Windows is supported.
145
-[Your Python installation must support interfacing with the Windows
146
-system DLLs.][ctypes.WinDLL]
235
+### A Python installation that can talk to the SSH agent { #python-support }
147 236
 
148 237
 On non-Windows operating systems, the SSH agent is expected to advertise
149 238
 its communication socket via the `SSH_AUTH_SOCK` environment variable,
... ...
@@ -151,10 +240,30 @@ which is common procedure.
151 240
 Therefore, [your Python installation must support UNIX domain
152 241
 sockets][socket.AF_UNIX].
153 242
 
243
+Since version 0.6, Windows is supported.
244
+[Your Python installation must support interfacing with the Windows
245
+system DLLs.][ctypes.WinDLL]
246
+By default, like on non-Windows systems, the SSH agent is expected to
247
+advertise its communication socket via the `SSH_AUTH_SOCK` environment
248
+variable.
249
+Alternatively, `derivepassphrase` can be configured to connect to the
250
+well-known socket addresses of Pageant or the OpenSSH agent
251
+instead.[^pageant-socket-address]
252
+
253
+[^pageant-socket-address]: In particular, Pageant uses a non-constant,
254
+    long and pseudo-random socket address that is ([by
255
+    design][CAPABILITIES]) computationally infeasible to compute for
256
+    other processes not running in the same user's session.
257
+    This would be non-sensical to require the user to compute
258
+    externally, then set `SSH_AUTH_SOCK` accordingly, instead of
259
+    teaching `derivepassphrase` to compute the address itself.
260
+
261
+[CAPABILITIES]: https://en.wikipedia.org/wiki/Capability-based_security
262
+
154 263
 `derivepassphrase vault --version` will report on supported and on
155
-unavailable features, including "master SSH key":[^1]
264
+unavailable features, including "master SSH key":[^feature-support]
156 265
 
157
-[^1]: This indicates support in principle, on this
266
+[^feature-support]: This indicates support in principle, on this
158 267
     hardware/software/system combination, for interfacing with an SSH
159 268
     agent.
160 269
     At runtime, this could still fail, e.g. because the SSH agent isn't
... ...
@@ -188,7 +297,7 @@ unavailable features, including "master SSH key":[^1]
188 297
 For an SSH key to be usable by `derivepassphrase`, the SSH agent must
189 298
 always generate the same signature for the same input, i.e. the
190 299
 signature must be deterministic for this key type.
191
-Commonly used SSH key types (as of August 2025) include [ECDSA][],
300
+Commonly used SSH key types (as of January 2026) include [ECDSA][],
192 301
 [Ed25519][], [RSA][], and, somewhat less commonly, [Ed448][] and
193 302
 [DSA][].
194 303
 
... ...
@@ -246,7 +355,7 @@ If you do not yet have a (supported) SSH key, we recommend Ed25519 for
246 355
 maximum speed and reasonable availability, otherwise RSA for maximum
247 356
 availability.
248 357
 We do not in general recommend Ed448 because it is not widely
249
-implemented (as of August 2025).
358
+implemented (as of January 2026).
250 359
 
251 360
 ??? example "Generating new SSH keys for `derivepassphrase`"
252 361
 
... ...
@@ -304,28 +413,32 @@ implemented (as of August 2025).
304 413
 
305 414
         Alternatively, GnuPG supports reusing keys in its native OpenPGP
306 415
         format for SSH as long as the underlying key type is compatible.
307
-        First, obtain GnuPG's internal identifier (the "keygrip") for
308
-        the correct key you may want to use.
309
-        (Warning: OpenPGP subkeys have a different keygrip, so be sure
310
-        to use the correct one.)
416
+        First, obtain the keygrip for the correct key you may want to
417
+        use.
418
+        ([See the agent-specific notes for GnuPG
419
+        terminology.](#agent-specific-notes))
311 420
 
312 421
         ~~~~ console
313 422
         $ gpg --list-keys --with-keygrip sample-key@example.com
314
-        pub   rsa4096 2025-07-27 [SC] [expires: 2025-08-01]
315
-              675F056879A81925E3E0DE60370C2A7D2E40FF4C
316
-              Keygrip = C71CB33DC50C9972EF9C135B0FB70D87B1491923
423
+        sec   rsa4096 2026-01-21 [SC] [expires: 2026-01-24]
424
+              375509534445A9CA834F15E21A1525F3334C607A
425
+              Keygrip = D91EBFAC7C503623B8BCC628B5B5A233AD7CA219
317 426
         uid           [ultimate] Sample Key <sample-key@example.com>
318
-        sub   rsa4096 2025-07-27 [E] [expires: 2025-08-01]
319
-              Keygrip = 84129D49C9A0654BDFAE2DACBC7A9D8C563FF884
427
+        ssb   rsa4096 2026-01-21 [E] [expires: 2026-01-24]
428
+              Keygrip = E3F1DC21B524B5515C16D8E6112F20F3810C64F2
320 429
         ~~~~
321 430
 
431
+        (Note that OpenPGP *subkeys* have a different keygrip than the
432
+        *main key*.
433
+        Be sure to use the correct one, e.g.,
434
+        D91EBFAC7C503623B8BCC628B5B5A233AD7CA219.)
435
+
322 436
         === "before v2.3.7"
323 437
 
324
-            Add the keygrip (on a line of its own) to the `sshcontrol`
325
-            file in the GnuPG configuration directory.
438
+            Add the keygrip (on a line of its own) to `sshcontrol`.
326 439
 
327 440
             ~~~~ console
328
-            $ echo C71CB33DC50C9972EF9C135B0FB70D87B1491923 >> ~/.gnupg/sshcontrol
441
+            $ echo D91EBFAC7C503623B8BCC628B5B5A233AD7CA219 >> ~/.gnupg/sshcontrol
329 442
             ~~~~
330 443
 
331 444
         === "v2.3.7 and later"
... ...
@@ -333,7 +446,8 @@ implemented (as of August 2025).
333 446
             Set a key attribute to permit this key's use in SSH:
334 447
 
335 448
             ~~~~ console
336
-            $ gpg-connect-agent 'keyattr C71CB33DC50C9972EF9C135B0FB70D87B1491923 Use-for-ssh: true' /bye
449
+            $ gpg-connect-agent 'KEYATTR D91EBFAC7C503623B8BCC628B5B5A233AD7CA219 Use-for-ssh: true' /bye
450
+            OK
337 451
             ~~~~
338 452
 
339 453
 ---
340 454