From 9b5ed36acd2023462364995e962d8ff0ac021176 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Mon, 6 Jul 2026 13:13:31 +0000 Subject: [PATCH] chore: update GPG signing instructions for clarity and accuracy in devcontainer setup --- .devcontainer/README.md | 70 +++++++++++++++++++---------------------- docs/dev-containers.md | 68 ++++++++++++++++++++++----------------- 2 files changed, 72 insertions(+), 66 deletions(-) diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 0e988e6e6f..2b0d05d0f3 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -62,63 +62,57 @@ gh --version && gh auth status && gh api user --jq .login ## Signed Commits With Host Credentials -The VS Code Dev Containers extension handles this automatically — your private -keys never enter the container, only the agent socket is forwarded: +The VS Code Dev Containers extension handles part of this automatically — your +private keys never enter the container, only the agent socket is forwarded: - Your host **`.gitconfig`** (including `user.signingkey` and `commit.gpgsign`) is copied into the container. -- Your host **`gpg-agent`** is forwarded (this is why `gnupg2` is installed), and - your GPG **public** keys are imported into the container. +- Your host **`gpg-agent` socket** is forwarded (this is why `gnupg2` is + installed). This enables the actual signing operation via the host agent. - Your host **SSH agent** is forwarded, so `git push` over SSH uses your host keys. +**Important**: VS Code forwards the host agent socket but does **not** automatically +copy your host GPG public keyring into the container. GPG requires both a public key +entry in the container's local keyring (to select the key) and the forwarded agent +(to perform the signing). Without the public key, `gpg --clearsign` fails with +`No secret key` even though the host agent connection is active. + ### One-time host setup -Make sure signing is configured on the **host** (this is what gets copied in): +1. Configure signing on the host: -```bash -git config --global user.signingkey -git config --global commit.gpgsign true -``` + ```bash + git config --global user.signingkey + git config --global commit.gpgsign true + ``` -Then, inside the container, verify the key is visible before committing: +2. Export your public key so the container can import it: -```bash -gpg --list-secret-keys -git commit -S -m "your message" # -S optional if commit.gpgsign is true -git push -``` + ```bash + # on the HOST, from repo root (auto-uses git user.signingkey) + ./.devcontainer/export-signing-key.sh -### Easiest rebuild-safe import flow + # or pass a key explicitly + ./.devcontainer/export-signing-key.sh + ``` -This devcontainer auto-imports a public key from `.git/signing.pub` on start. -If present, it runs `gpg --import .git/signing.pub` and removes the file after a -successful import. + On Windows PowerShell, use: -So the easiest setup is: + ```powershell + # on the HOST, from repo root (auto-uses git user.signingkey) + .\.devcontainer\export-signing-key.ps1 -```bash -# on the HOST, from repo root (auto-uses git user.signingkey) -./.devcontainer/export-signing-key.sh + # or pass a key explicitly + .\.devcontainer\export-signing-key.ps1 + ``` -# or pass a key explicitly -./.devcontainer/export-signing-key.sh -``` - -On Windows PowerShell, use: - -```powershell -# on the HOST, from repo root (auto-uses git user.signingkey) -.\.devcontainer\export-signing-key.ps1 - -# or pass a key explicitly -.\.devcontainer\export-signing-key.ps1 -``` +3. Rebuild the container. The `postStartCommand` auto-imports `.git/signing.pub` + and removes it. The helper auto-selects `gpg2`/`gpg` based on where your key is visible, which avoids host setups where the two binaries use different keyrings. -If you rotate keys, run the helper again on the host before the next rebuild so -the container can import the new public key. +If you rotate keys, run the export helper again on the host before the next rebuild. Expected behavior after rebuild: diff --git a/docs/dev-containers.md b/docs/dev-containers.md index c4d9d1720b..674d8a52cb 100644 --- a/docs/dev-containers.md +++ b/docs/dev-containers.md @@ -56,47 +56,59 @@ never enter the container: only the agent socket is forwarded. ### Option A: Commit and Sign in Container (Recommended) -The VS Code Dev Containers extension wires this up automatically: +The VS Code Dev Containers extension automatically handles part of this: - Your host `.gitconfig` (including `user.signingkey` and `commit.gpgsign`) is copied into the container. -- Your host `gpg-agent` is forwarded (this is why `gnupg2` is installed in the - image), and your GPG public keys are imported into the container. +- Your host `gpg-agent` **socket** is forwarded into the container (this is why + `gnupg2` is installed in the image). This covers the private key operation + (the actual signing). - Your host SSH agent is forwarded, so `git push` over SSH uses your host keys. -One-time host setup (this is what gets copied in): +**Important**: VS Code forwards the host agent socket but does **not** automatically +copy the host GPG public keyring into the container. GPG needs both a public key +entry in the local keyring (to select which key to use) and the forwarded agent +socket (to perform the signing). If the public key is missing from the container +keyring, `gpg --clearsign` will fail with `No secret key` even though the host +agent is reachable and the forwarding is active. + +This is the one-time host-side setup: + +1. Configure signing on the host: + + ```bash + git config --global user.signingkey + git config --global commit.gpgsign true + ``` + +2. Export your public key so the container can import it on startup: + + ```bash + ./.devcontainer/export-signing-key.sh + ``` + + On Windows PowerShell: + + ```powershell + .\.devcontainer\export-signing-key.ps1 + ``` + +3. Rebuild the container. The `postStartCommand` auto-imports `.git/signing.pub` + and removes it. + +Then verify inside the container: ```bash -git config --global user.signingkey -git config --global commit.gpgsign true -``` - -Then work entirely inside the container: - -```bash -gpg --list-secret-keys # verify the forwarded key is visible -git commit -S -m "your message" # -S optional when commit.gpgsign is true +gpg --list-secret-keys --keyid-format=long # should list your key +git commit -S -m "your message" # -S optional when commit.gpgsign is true git push ``` -For rebuild-safe signing, export your public key into `.git/signing.pub` on the -host so the devcontainer can auto-import it on startup: - -```bash -./.devcontainer/export-signing-key.sh -``` - -On Windows PowerShell: - -```powershell -.\.devcontainer\export-signing-key.ps1 -``` - -If you rotate keys, run the helper again before the next rebuild. +If you rotate keys, run the export helper again on the host before the next rebuild. Expected behavior after rebuild: -- Signing keeps working when host forwarding/import and `.git/signing.pub` are in sync. +- Signing keeps working when the host agent forwarding and `.git/signing.pub` import are in sync. - If signing breaks after rebuild (especially after key rotation), regenerate `.git/signing.pub` with the helper and rebuild again. If signing still fails, follow [Signing (GPG/PGP) Troubleshooting](#signing-gpgpgp-troubleshooting).