While preparing to contribute to Debian projects, I came across a requirement that all commits must be GPG signed. My previous commits were unsigned, so I decided to set it up properly once instead of using workarounds.
This post documents the complete process I followed on Debian WSL and the issues I faced along the way.
Why GPG commit signing?
A signed commit proves that the commit was created by you and hasn't been modified. Debian projects rely on OpenPGP signatures to verify the authenticity of contributions.
Step 1: Generate a new GPG key
I started by generating a new Open PGP (RSA) key.
gpg --full-generate-key
I selected the following options:
- RSA and RSA
- 4096 bit key
- Valid for 2 years (2y)
- Name: Ayush Sharma
- Email: ayushhardeniya@email
After confirming the details, GPG asked me to create a passphrase. This passphrase protects the private key and is required whenever the key is used for signing.
Create a passphrase
The next screen asks you to create a passphrase.
This is not your GPG key.
It is simply the password that protects your private key.
I chose a strong passphrase and saved it in my password manager.
You will need this passphrase whenever GPG needs to unlock your private key for signing commits. Fortunately, GPG caches it for some time, so you usually enter it only once during a development session.
Wait for key generation
After confirming the passphrase, GPG generates the key.
During this step, you may see:
We need to generate a lot of random bytes.
This is completely normal.
Typing on the keyboard or performing some disk activity helps generate enough entropy.
Once finished, GPG prints something similar to:
gpg: revocation certificate stored as ...
public and secret key created and signed.
At this point, your GPG identity has been created successfully.
Save this passphrase in your password manager. It is not the key itself, but the password that unlocks your private key.
Step 2: Verify that the key was created
After the key generation completed, I verified it using:
gpg --list-secret-keys --keyid-format LONG
It returned my newly generated key along with its fingerprint.
Step 3: Configure Git
Next, I configured Git to use this key globally.
git config --global user.signingkey <YOUR_KEY_FINGERPRINT>
git config --global commit.gpgsign true
git config --global gpg.program gpg
Now every commit I create will be signed automatically.
Step 4: Fix the "No secret key" error
Initially, Git failed with:
gpg: signing failed: No secret key
This happened because no GPG key existed on my system. Once the key was generated, this error disappeared.
Step 5: Configure GPG for WSL
The next issue I encountered was:
gpg: agent_genkey failed: Timeout
I installed the terminal based pinentry program.
sudo apt install pinentry-curses
Then I configured GPG to use it.
mkdir -p ~/.gnupg
echo "pinentry-program /usr/bin/pinentry-curses" > ~/.gnupg/gpg-agent.conf
chmod 700 ~/.gnupg
chmod 600 ~/.gnupg/gpg-agent.conf
After that I restarted the GPG agent.
gpgconf --kill gpg-agent
gpgconf --launch gpg-agent
Step 6: Set GPG_TTY
The next problem was another timeout while signing. It turned out that GPG_TTY was not configured.
I exported it using:
export GPG_TTY=$(tty)
To make it permanent:
echo 'export GPG_TTY=$(tty)' >> ~/.bashrc
source ~/.bashrc
Now GPG always knows which terminal to use.
Step 7: Fix "Screen or window too small"
When creating my first signed commit I got:
gpg: signing failed: Screen or window too small
The issue was simply that my terminal window was too short.
Checking the size:
stty size
Mine showed only 10 rows.
After increasing the terminal height, signing worked without any issues.
Step 8: Make the first signed commit
Finally I created my first signed commit.
git commit -m "Add Ayush Sharma to CONTRIBUTORS"
It asked for Passphrase
To verify the signature:
git log --show-signature -1
The output showed:
gpg: Good signature from "Ayush Sharma <ayushhardeniya@email>"
That confirmed everything was working correctly.
Export the public key
To share the public key later with Salsa or a keyserver, I exported it using:
gpg --armor --export ayushhardeniya@email > publickey.asc
Remember that this exports only the public key. It is safe to share.
Final result
Now every commit I make across all my repositories is signed automatically.
The first commit in a session asks for the passphrase, and after that GPG caches it for some time, so I don't need to enter it for every commit.
Quick summary
- Generate a new GPG key.
gpg --full-generate-key
- Verify the key.
gpg --list-secret-keys --keyid-format LONG
- Configure Git.
git config --global user.signingkey <FINGERPRINT>
git config --global commit.gpgsign true
git config --global gpg.program gpg
- Install pinentry.
sudo apt install pinentry-curses
- Configure
gpg-agent.
echo "pinentry-program /usr/bin/pinentry-curses" > ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent
gpgconf --launch gpg-agent
- Export
GPG_TTY.
export GPG_TTY=$(tty)
echo 'export GPG_TTY=$(tty)' >> ~/.bashrc
- Create a signed commit.
git commit -m "Your commit message"
- Verify the signature.
git log --show-signature -1
That's it. This is a one time setup, and after it is done, every new repository can use the same GPG identity for signed commits.





Top comments (0)