diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 13a2dd50ea..0e988e6e6f 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -117,6 +117,14 @@ On Windows PowerShell, use: 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. + +Expected behavior after rebuild: + +- Signing keeps working when host forwarding/import and `.git/signing.pub` are in sync. +- If signing breaks after rebuild (especially after key rotation), regenerate `.git/signing.pub` with the helper and rebuild again. + After **Rebuild Container** (or next container start), verify in the container: ```bash @@ -124,57 +132,26 @@ gpg --list-secret-keys --keyid-format=long git commit -S -m "test signed commit" ``` -### Manually importing your public key - -If `git commit -S` fails with `gpg: signing failed: No secret key`, the forwarded -agent holds your **private** key but the container keyring is missing the matching -**public** key, so gpg can't locate it. Import it manually. - -First, on the **host**, find your real key ID. On macOS, gpg is often `gpg2` and -may use a different keyring than plain `gpg`, so use the binary that actually holds -your keys: - -```bash -gpg2 --list-secret-keys --keyid-format=long # ID is the part after the '/' on the sec line -git config --global user.signingkey # what git is set to sign with -``` - -Export that key on the **host** into the shared repo checkout (`.git/` is not -tracked, so it is a safe drop point): - -```bash -# on the HOST — replace with your real key ID -gpg2 --armor --export \ - > /Users//path/to/alfresco-ng2-components/.git/signing.pub -``` - -Import it in the **container** and point git at it: - -```bash -# in the CONTAINER (repo root) -gpg --import .git/signing.pub && rm .git/signing.pub -git config --global user.signingkey - -# verify — a passphrase prompt (if any) appears on the HOST, not the container -gpg --list-secret-keys --keyid-format=long -echo test | gpg -u --clearsign -git commit -S -m "test signed commit" -``` - ### Other signing gotchas - `gpg-connect-agent 'keyinfo --list' /bye` printing **`connection to agent is in restricted mode`** is **normal and good** — VS Code forwards the host's restricted `gpg-agent.extra` socket, which allows signing but blocks key listing. It does not mean the agent is missing. -- Still failing after importing the public key? The forwarding didn't attach — - on the host run `gpgconf --launch gpg-agent` and confirm `echo test | gpg2 - --clearsign` works there, then **Dev Containers: Rebuild Container**. +- If signing fails after a rebuild, regenerate `.git/signing.pub` on the host with + `./.devcontainer/export-signing-key.sh` (or + `./.devcontainer/export-signing-key.ps1` on PowerShell) and rebuild again. +- If it still fails, the forwarding likely did not attach — on the host run + `gpgconf --launch gpg-agent` and confirm `echo test | gpg2 --clearsign` works, + then **Dev Containers: Rebuild Container**. - Confirm `gnupg2` is present in the container: `gpg --version`. - The automatic gitconfig / GPG / SSH forwarding is a feature of the **VS Code Dev Containers extension**. If you run this config via the plain `@devcontainers/cli`, you must mount `~/.gnupg`, `~/.gitconfig`, and the agent sockets yourself. +For a full troubleshooting checklist, see +[docs/dev-containers.md](../docs/dev-containers.md#signing-gpgpgp-troubleshooting). + See [docs/dev-containers.md](../docs/dev-containers.md#git-operations-and-signing) for alternative signing strategies (host-only signing, CI-enforced signing). diff --git a/docs/dev-containers.md b/docs/dev-containers.md index d118eb6a60..c4d9d1720b 100644 --- a/docs/dev-containers.md +++ b/docs/dev-containers.md @@ -79,31 +79,46 @@ git commit -S -m "your message" # -S optional when commit.gpgsign is true git push ``` -If signing fails with `gpg failed to sign the data` / `no secret key`, the agent -forwarding did not attach — rebuild the container or reload the VS Code window. +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. + +Expected behavior after rebuild: + +- Signing keeps working when host forwarding/import and `.git/signing.pub` 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). > Note: the automatic gitconfig / GPG / SSH forwarding is a feature of the VS Code > Dev Containers extension. If you run this configuration via the plain > `@devcontainers/cli`, mount `~/.gnupg`, `~/.gitconfig`, and the agent sockets -> yourself, or fall back to Option B. +> yourself. ### Option B: Sign Commits on Host -For the strongest key isolation, keep signing on the host: +Policy alternative for strongest key isolation: - Keep private signing keys only on the host. -- Do normal development in the container. -- Stage and commit from a host terminal in the same repository checkout - (for example, `git commit -S ...`). - -Good fit when your policy forbids forwarding signing agents into containers. +- Do development in the container, then commit from a host terminal. ### Option C: Unsigned Commits in Container, Signed Merge in CI/Host -- Commit in container without local signing. -- Enforce signing at merge/release time using host or CI controls. +Policy alternative for simpler contributor setup: -This can simplify local setup for contributors while preserving integrity checks in protected branches. +- Commit in container without local signing. +- Enforce signing at merge/release time in host/CI controls. ### Practical Daily Pattern @@ -140,6 +155,50 @@ Useful files to inspect: - [.devcontainer/Dockerfile](../.devcontainer/Dockerfile) - VS Code Dev Containers logs under your local VS Code logs directory +### Signing (GPG/PGP) Troubleshooting + +If `git commit -S` fails in the container: + +1. Confirm host signing config: + + ```bash + git config --global user.signingkey + git config --global commit.gpgsign + ``` + +2. Refresh the rebuild-safe public key file on the host: + + ```bash + ./.devcontainer/export-signing-key.sh + ``` + + Windows PowerShell: + + ```powershell + .\.devcontainer\export-signing-key.ps1 + ``` + +3. Rebuild the container. + +4. Verify inside container: + + ```bash + gpg --list-secret-keys --keyid-format=long + git commit -S -m "test signed commit" + ``` + +5. If it still fails, restart host agent forwarding and rebuild: + + ```bash + gpgconf --launch gpg-agent + echo test | gpg2 --clearsign + ``` + +Notes: + +- `gpg-connect-agent 'keyinfo --list' /bye` reporting restricted mode is expected in Dev Containers. +- If you run via plain `@devcontainers/cli` instead of the VS Code extension, mount `.gnupg`, `.gitconfig`, and agent sockets manually. + ### Nx Daemon Not Starting in Container If `NX_DAEMON=true` is set but `pn nx daemon` still reports that the daemon is not running, Nx may have persisted a stale disable marker from a previous startup failure.