vscode: Remote SSH - Git: gpg failed to sign the data

Does this issue occur when all extensions are disabled?: Yes/No

  • VS Code Version: 1.59.0

  • OS Version:

    Version: 1.59.0 (user setup)
    Commit: 379476f0e13988d90fab105c5c19e7abc8b1dea8
    Date: 2021-08-04T23:13:12.822Z
    Electron: 13.1.7
    Chrome: 91.0.4472.124
    Node.js: 14.16.0
    V8: 9.1.269.36-electron.0
    OS: Windows_NT x64 10.0.19043
    

Steps to Reproduce:

I’m using Remote - SSH from Windows 10 to Ubuntu 20.04 LTS.

  1. Add the following code to ~/.profile

    export GPG_TTY=$(tty)
    
  2. Configure git

    git config --global commit.gpgsign true
    git config --global --unset gpg.program
    git config --global --add gpg.program /usr/bin/gpg
    
  3. Enable Commit Signing

    image

  4. Commit

    image

  5. Open Git Log

    > git -c user.useConfigOnly=true commit --quiet --allow-empty-message --file - -S
    error: gpg failed to sign the data
    fatal: failed to write commit object
    > git config --get-all user.name
    > git config --get-all user.email
    
  6. Show Command Output

    > git -c user.useConfigOnly=true commit --quiet --allow-empty-message --file - -S
    error: gpg failed to sign the data
    fatal: failed to write commit object
    

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 31
  • Comments: 30

Most upvoted comments

As a workaround:

  1. Open Terminal and commit once

    export GPG_TTY=$(tty)
    git commit -m "OK" -S
    

    …Enter your password…

  2. Git Reset

    git reset HEAD~
    
  3. Then you can use VSCode git commit signing

Same issue here. I am on Windows10 using SSH and developing on Fedora. The following gets it to work, but the steps must be repeated every time you re-open VSCode.

  1. Manually run export GPG_TTY=$(tty)
  2. Run echo "test" | gpg2 --clearsign enter password
  3. You can now perform signed commits using the Terminal and VSCode GUI. (If code signing is enabled / setup)

If you don’t do step 1 and go straight to step 2, you get this error;

gpg: signing failed: Inappropriate ioctl for device
gpg: [stdin]: clear-sign failed: Inappropriate ioctl for device

I can confirm the problem. I am using remote SSH from a Windows machine developing on a Linux machine. I have export GPG_TTY=$(tty) in my .profile. But I have to manually export it in the console and sign something once in the console (e.g. echo "test" | gpg2 --clearsign) to be able to use VSCode to use signed git commits.

Same here. Using VS Code from a MBP on Big Sur v11.6, along with the Remote SSH plugin and managing my git repo from the remote server. gpg signing always fails when committing in the source control area, but always succeeds after providing my passphrase using one of the commands above (e.g. echo "test" | gpg --clearsign or commit -S -m "message")

Using Ubuntu 22.10

Step 0: Workaround

(Works with pinentry-curses and pinentry-gtk2)

Inspired by this StackOverflow thread I added to my ~/.bashrc

export GPG_TTY=$(tty)
echo "" | gpg --clearsign

And now VSCode asks the startup in terminal for the passphrase that git later remembers. But this is unequivocally a workaround.

Step 1: The offender

However I also tried in the ssh terminal a command that (according to Git log) VSCode uses to commit

echo "commit message" | git -c user.useConfigOnly=true commit --quiet --allow-empty-message --file -

And it fails identically as in the VSCode. But when I remove --quiet flag passphrase window in ssh terminal appears and everything works fine.

Step 2: It works locally

Importantly, the same command (with --quiet) works fine when run locally both from VSCode and terminal. But significant difference is a fact that it opens a GUI passphrase prompt.

That GUI prompt looks similarly to the one opened (on default Ubuntu) by pkexec. In ssh terminal pkexec doesn’t open a GUI prompt but asks for password in the terminal instead.

But git with --quiet flag instead of asking for passphrase in the ssh terminal opens a GUI prompt on the machine that I ssh into.

Edit: The problematic package that is responsible for the GUI prompt is pinentry-gnome3. Switching to pinentry-tty makes VSCode commit not work both locally and remotely. Edit 2: pinentry-qt doesn’t work either. Edit 3: pinentry-gtk2 brings most improvement by working in local-VSCode, local-terminal and ssh-terminal but not in ssh-VSCode.

Step ?: Conclusion

So git/gpg not asking for the passphrase when connected remotely seems to be a result of ~unusual case of how git/gpg passphrase GUI prompt and X11 forwarding works~ how pinentry and VSCode and X11 forwarding (doesn’t) work.

I genuinely don’t feel like this is a bug. I feel like it is not knowing where to save your settings on your specific OS. If you use my reply before this as an example - my issue was simply that I wasn’t saving the env variable in the right profile file. Once I did that, it has been fixed every since. I don’t feel like this is a bug, and that this is being beaten to death.

In my opinion this is a bug of VSCode. And either --quiet flag should be removed or pinentry should be allowed to show prompt in the terminal. I think this should work out of the box without a need to reconfigure users system.

same problem: (macos -> debian)

Version: 1.68.1 (Universal)
Commit: 30d9c6cd9483b2cc586687151bcbcd635f373630
Date: 2022-06-14T12:52:13.188Z
Electron: 17.4.7
Chromium: 98.0.4758.141
Node.js: 16.13.0
V8: 9.8.177.13-electron.0
OS: Darwin arm64 22.0.0

Remote-SSH: v0.82.1

I can confirm the problem. I am using remote SSH from a Windows machine developing on a Linux machine. I have export GPG_TTY=$(tty) in my .profile. But I have to manually export it in the console and sign something once in the console (e.g. echo "test" | gpg2 --clearsign) to be able to use VSCode to use signed git commits.

Yup, can confirm the same behaviour in same environment (win10 -> Centos7).

Restarting VSCode worked for me when I confirmed it was working on my terminal (after adding export GPG_TTY=$(tty) to my .zshrc)

Make sure echo "test" | gpg --clearsign runs successfully first before trying the below.

Very helpful to check what git commit is doing under the hood. Run the following commit with GIT_TRACE=1 as follow

GIT_TRACE=1 git commit -S -m "MESSAGE"

This will show what user name, email, and key git uses when committing.

In my case, I found that git was picking up the wrong user and key details for signing the commit. I mainly intended to use the local config of the repo rather than the global and adding the following to the local git config (located at “REPO_PATH/.git/config”) got signing the commit to work both in Terminal and VSCode.

[user]
    name = USER NAME
    email = USER EMAIL
    signingKey = SIGNING KEY

It can also be set with the following:

git config --local user.name "USER NAME"
git config --local user.email "USER EMAIL"
git config --local user.signingkey "USIGNING KEY"

To avoid retyping export GPG_TTY=$(tty) manually you can tell VSCode to start bash like a login shell by passing the -l parameter to the bash command. You can do that by adding "args": ["-l"] in the terminal.integrated.profiles.linux setting of VSCode:

"terminal.integrated.profiles.linux": {
    "bash": {
        "path": "bash",
        "args": ["-l"],
        "icon": "terminal-bash"
    }
},
"terminal.integrated.defaultProfile.linux": "bash"

Guys seem like mine one was solved when I placed export GPG_TTY=$(tty) in ~/.bashrc instead of ~/.profile.

When an interactive shell that is not a login shell is started, Bash reads and executes commands from ~/.bashrc, if that file exists.

This was an excerpt from the GNU bash reference manual. Please do take a look at it. https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html

Thank you for the post. When I had first replied to this topic, I was a bit ignorant which file my distro used. The ~/.bachrc probably will work, but for me, I put export GPG_TTY=$(tty) in ~/.bash_profile. I did this because this is where things profile related such as environment variables typically go in Fedora, which is the distro I use. Once I added export GPG_TTY=$(tty), I did source ~/.bash_profile to reload the file. After that I was able to perform a signed commit, close VSCode completely, re-open and perform a signed commit without performing any extra steps.

I think the overall issue was kind of a misunderstanding. Different distros expect env variables in different places. By manually running export GPG_TTY=$(tty), you’re setting it for that session. Placing it in whichever profile file your distro uses and either rebooting or entering source ~/.bash_profile should solve it.

TLDR;

Fedora users put export GPG_TTY=$(tty) in ~/.bash_profile and run source ~/.bash_profile.

Guys seem like mine one was solved when I placed export GPG_TTY=$(tty) in ~/.bashrc instead of ~/.profile.

When an interactive shell that is not a login shell is started, Bash reads and executes commands from ~/.bashrc, if that file exists.

This was an excerpt from the GNU bash reference manual. Please do take a look at it. https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html