Signing Commits with SSH Keys Instead of GPG: Setup and Practice
AI generated
git
HEAD
Git
SSH Commit Signing
signing commits with SSH keys instead of GPG

Since Git 2.34, an already existing SSH key can be used directly to sign commits, with no separate GPG installation and no dedicated key management of its own. Anyone already using SSH for push and pull gets to verified commits with considerably less overhead this way.

9 min read Git Security

1. Why sign commits at all

The author field of a Git commit is plain, unauthenticated text, name and email address can be set to anything with git commit --author, with no proof required that the named person actually created the commit. A cryptographic signature closes exactly that gap by proving that a commit was created using the private key belonging to a specific, verifiable identity.

Especially on projects with several contributors or with security relevant code, a verified signature builds additional trust during code review and, if something goes wrong, provides solid proof of which specific person actually stands behind a given commit. With a compromised access path, for instance a stolen push token, a strict signing requirement helps reliably tell forged commits apart from genuine ones, since an attacker without the matching private key simply cannot produce a valid signature.

2. Why GPG signing often gets abandoned in practice

GPG brings a fully separate key management system for commit signing, including a web of trust concept, its own gpg-agent process, and its own key format that has nothing to do with any SSH keys already in use. For many developers that means an entirely additional tool stack that has to be installed and maintained solely for this one purpose.

In practice, that extra overhead is exactly what often causes GPG signing to fall by the wayside despite an official policy, since gpg-agent asks for the passphrase again after every restart, key generation feels unfamiliar and complex, and error messages after a misconfiguration are rarely self explanatory. On freshly set up development machines or inside containerized build environments, GPG setup frequently fails even earlier, either due to missing entropy sources for key generation or because gpg-agent has no graphical surface at all to prompt for the passphrase in the first place.

3. SSH signatures as an alternative since Git 2.34

Since Git 2.34, Git supports a second, alternative signature format via gpg.format ssh, which internally relies on OpenSSH's own signing functionality, specifically ssh-keygen -Y sign and ssh-keygen -Y verify. That means the exact same SSH key already used to authenticate against the Git server can be used directly to sign commits as well.

That considerably lowers the barrier to entry, since no additional key pair has to be generated and no separate software has to be installed, anyone already pushing over SSH typically already has everything needed for signing.

4. Configuring Git for SSH signing

The switch happens through three configuration values: gpg.format is set to ssh, user.signingkey points to the path of the public SSH key, and commit.gpgsign enables automatic signing for every future commit, so the -S flag no longer needs to be passed manually every time.

Setting tag.gpgsign in addition applies the same automatic signing to annotated tags too, which is particularly recommended for release tags whose origin should be verifiable as well.


# Switch Git to SSH based signing
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true
git config --global tag.gpgsign true

5. The allowed_signers file for local verification

For Git to actually verify an SSH signature locally, it needs a mapping between email address and public key inside a so called allowed_signers file, whose path is stored in gpg.ssh.allowedSignersFile. Every line in that file ties one email address to exactly one public key in the familiar OpenSSH format.

Without that file, Git can still sign, but neither git log --show-signature nor git verify-commit produce a meaningful result then, since the reference information about which public key belongs to which identity is simply missing.


# Point Git at the allowed_signers file
git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers

# Content of the file: one line per identity
# max@mironsoft.de ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIxxxxx...

6. Signing commits and checking the signature

With commit.gpgsign enabled, every new commit gets signed automatically without any further action. Without that global setting, a single commit can still be signed deliberately with the -S option, which works well as a gradual first step before turning on automatic signing for every future commit.

For verification, git log --show-signature reports directly inside the log output whether and with which key a commit was signed, while git verify-commit produces the same proof for a single specific commit hash and fits nicely into an automated check script.


# Sign a single commit deliberately
git commit -S -m "Feature: reworked price calculation"

# Verify the signature of a specific commit
git verify-commit HEAD

7. Support on GitHub and GitLab

GitHub accepts SSH signing keys as their own key type, stored separately from the regular authentication key in the account settings, even though both can technically be the exact same key. A successfully verified commit gets the same green Verified badge there that used to be reserved exclusively for GPG signed commits.

GitLab supports SSH signatures as well, manages the associated public keys under the user settings, and marks verified commits in the web interface accordingly, so verification stays visible not just locally but across the whole team.

8. SSH signing and GPG signing side by side

The biggest practical difference lies in management overhead: SSH signing reuses key infrastructure that already exists, while GPG brings an entirely separate, parallel management layer. When it comes to revoking a compromised key, though, GPG's revocation certificate concept offers a somewhat more mature, dedicated mechanism than the SSH world does.

A clear advantage of SSH signing shows up with hardware security keys: a FIDO2 token such as a YubiKey can be used directly for signing through ssh-agent, with no need to set up a separate GPG smartcard configuration on top.

9. Rolling out signing across a team

For a binding rollout across a team, it makes sense to distribute commit.gpgsign and gpg.format ssh through a central, documented onboarding guide rather than relying on each individual developer's own configuration. On the server side, the requirement to sign can additionally be enforced technically through push rules or protected branch settings.

The allowed_signers file itself can sensibly be maintained directly inside the project repository and pulled in through a relative include path in the local Git configuration, so new team members automatically receive the current, centrally maintained list the moment they clone the repository.

Criterion SSH signing GPG signing
Extra software required No, uses existing OpenSSH Yes, a separate GPG installation
Key reusable Yes, the same key as for push/pull No, a dedicated key pair is needed
Hardware token support Directly via ssh-agent Only through an extra smartcard setup
Revoking a compromised key Remove manually from allowed_signers Dedicated revocation certificate
Support on GitHub and GitLab Yes, its own Verified badge Yes, established for years

Mironsoft

Git workflows, branching strategies, and CI hooks

Chaotic Git history and unclear branching rules across the team?

We set up clean Git workflows, clarify branching strategies for the team, and automate quality checks via Git hooks and CI pipelines so the history stays traceable.

Workflow Audit

Review the existing branching strategy and merge practice for weak spots.

Hook Automation

Set up pre-commit and pre-push hooks for linting, tests, and commit conventions.

Team Training

Teach rebase, cherry-pick, and conflict resolution hands-on across the team.

10. Summary

SSH Commit Signing

Core idea

gpg.format ssh signs commits with the very same SSH key already used for push and pull.

Key file

The allowed_signers file ties email addresses to public keys and enables local verification.

Verification commands

git log --show-signature and git verify-commit show and confirm the signature of a commit.

Platform support

GitHub and GitLab display SSH signed commits with the same Verified badge as GPG signed commits.

11. FAQ: SSH Commit Signing

1From which Git version does SSH based commit signing work?
From Git 2.34 onward, on older versions only the classic GPG format is available for commit signatures.
2Do I need to generate a new SSH key just to sign commits?
No, an already existing SSH key that is also used for authentication can be used directly for signing.
3What happens if the allowed_signers file is missing?
Git can still sign, but neither git log --show-signature nor git verify-commit produce a meaningful result then, since the mapping from key to identity is missing.
4Do SSH signed commits get the same Verified badge on GitHub as GPG signed ones?
Yes, GitHub shows the same green Verified badge for both signature types, provided the public key was previously registered as a signing key on the account.
5Can I enable SSH signing for individual commits only instead of globally?
Yes, without the global commit.gpgsign setting, a single commit can still be signed deliberately with the -S option.
6Does SSH signing work with a hardware security key such as a YubiKey?
Yes, a FIDO2 token can be used directly for signing through ssh-agent, no additional GPG smartcard setup is needed for that.
7How do I revoke a compromised SSH signing key?
Most simply by removing the corresponding entry from the allowed_signers file and, if applicable, from the signing key settings of the platform in use.
8Can tags be signed with SSH too, not just commits?
Yes, with the additional tag.gpgsign setting, annotated tags get signed automatically just like commits.
9Does GitLab support SSH signatures the same way GitHub does?
Yes, GitLab manages the public signing keys under the user settings and marks verified commits accordingly in the web interface.
10Is SSH signing more secure than GPG signing?
Both offer a comparable level of cryptographic security, the practical difference lies mainly in lower management overhead and simpler hardware token support with SSH.