Skip to content

Commit 8f408e4

Browse files
authored
fix(ssh): skip file path signing keys in GPG agent forwarding (#734)
GPG key IDs are hex fingerprints, not file paths. When user.signingKey is a file path (starts with / or ~), it's an SSH key — skip passing it to setup-gpg. This handles the case where gpg.format is not set to ssh but the signing key is still an SSH key path.
1 parent fdd4906 commit 8f408e4

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

cmd/ssh.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,11 @@ func (cmd *SSHCmd) setupGPGAgent(
769769
// (SSH signing keys are handled by the separate SSH signature helper).
770770
func gpgSigningKey(log log.Logger) string {
771771
format, err := exec.Command("git", "config", "--get", "gpg.format").Output()
772-
if err == nil && strings.TrimSpace(string(format)) == "ssh" {
772+
formatStr := ""
773+
if err == nil {
774+
formatStr = strings.TrimSpace(string(format))
775+
}
776+
if formatStr == "ssh" {
773777
log.Debugf(
774778
"[GPG] gpg.format is ssh, skipping GPG signing key (handled by SSH signing helper)",
775779
)
@@ -783,6 +787,18 @@ func gpgSigningKey(log log.Logger) string {
783787
}
784788

785789
result := strings.TrimSpace(string(key))
790+
791+
// GPG key IDs are hex fingerprints, not file paths. If the signing key
792+
// looks like a file path and the format isn't x509 (which legitimately
793+
// uses certificate file paths via gpgsm), it's an SSH key.
794+
if (strings.HasPrefix(result, "/") || strings.HasPrefix(result, "~")) && formatStr != "x509" {
795+
log.Debugf(
796+
"[GPG] signing key %s looks like a file path, skipping (not a GPG key ID)",
797+
result,
798+
)
799+
return ""
800+
}
801+
786802
log.Debugf("[GPG] detected git sign key %s", result)
787803
return result
788804
}

cmd/ssh_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,15 @@ func TestGpgSigningKey_X509Format_Returned(t *testing.T) {
4545
result := gpgSigningKey(log.Discard)
4646
assert.Equal(t, "/path/to/cert", result)
4747
}
48+
49+
func TestGpgSigningKey_SSHKeyPath_Skipped(t *testing.T) {
50+
writeGitConfig(t, "[user]\n\tsigningKey = /home/user/.ssh/id_ed25519.pub\n")
51+
result := gpgSigningKey(log.Discard)
52+
assert.Empty(t, result)
53+
}
54+
55+
func TestGpgSigningKey_TildeKeyPath_Skipped(t *testing.T) {
56+
writeGitConfig(t, "[user]\n\tsigningKey = ~/.ssh/id_ed25519.pub\n")
57+
result := gpgSigningKey(log.Discard)
58+
assert.Empty(t, result)
59+
}

0 commit comments

Comments
 (0)