How to create and sign commits using GPG keys or SSH keys for authenticity
Ensure code integrity and prove authorship of every change in Git repositories using GPG keys or SSH keys. Understand the practical step-by-step process.
Summary
- Digital signatures shield the repository against identity spoofing and fraudulent commits
- GPG keys offer a mature cryptography ecosystem based on a decentralized web of trust
- SSH keys simplify workflows by reusing credentials already established for remote server access
- Visual interfaces on GitHub and GitLab display a green verification badge for valid signatures
- Mismatched local email configurations invalidate the signature and require careful scope review
The identity challenge in modern version control
Working with software development in teams requires absolute trust in the origin of code entering the central repository. In Git, the world's most popular version control system, a commit author is defined by simple text fields containing a name and an email address. In practice, this means anyone can alter their local machine configuration and pretend to be someone else when pushing code, injecting silent vulnerabilities without immediate alerts from the project's health systems.
To solve this security gap, the community adopted the concept of cryptographic signing. A digital signature acts like an inviolable wax seal or a legal signature on a document: it mathematically binds the developer's identity to the exact contents of that specific commit. When hosting platforms like GitHub or GitLab receive this material, they verify the signature using a registered public key and display a green verification badge, certifying the code originated precisely from the claimed sender.
Understanding the cryptography behind GPG and SSH
There are two primary paths to accomplish this authentication task: the GPG (GNU Privacy Guard) system, which is the traditional standard for key encryption, and the use of SSH (Secure Shell) keys, widely known for enabling secure connections to remote servers. Both approaches utilize asymmetric key pairs, consisting of a private key that must remain strictly secret on the developer's computer and a public key shared openly with the world.
The main practical difference between the two options lies in operational complexity and daily experience. The GPG ecosystem is extremely robust, managing concepts like webs of trust and key expiration, but carries a steep learning curve and sometimes confusing commands. On the other hand, SSH keys recently gained native support in Git, allowing developers to reuse the exact same key they already use to clone repositories via SSH for signing their commits, significantly reducing daily friction.
Generating and configuring GPG keys locally
If you choose the traditional GPG route, the first step is generating your key pair in your operating system's terminal. In practice, you need to prompt the GPG utility to create a new key using modern, secure algorithms, associating it with the exact email registered in your Git platform account.
- Step 1
- Open your terminal and run the standard key generation command with modern algorithms.
gpg --full-generate-key - Step 2
- Select the desired key type and set the size to 4096 bits to ensure high cryptographic security.
- Step 3
- Provide your real name, the email address matching your profile, and add a strong passphrase to protect your private key.
- Step 4
- List your existing keys to copy the long alphanumeric identifier of your newly created key.
gpg --list-secret-keys --keyid-format LONG - Step 5
- Export the corresponding public key in ASCII format to paste into your hosting platform settings.
gpg --armor --export YOUR_KEY_ID_HERE
With the key generated and copied, the next step involves configuring Git to recognize which key to use and enabling automatic signing across all local repositories. You achieve this by passing the key identifier to Git through global configuration commands, ensuring the application enforces the rule transparently for every saved unit of work.
Leveraging SSH keys to simplify workflows
If you prefer avoiding GPG key management, using an existing SSH key to sign commits presents an elegant and modern alternative. Since most engineers already utilize SSH keys to authenticate connections with remote servers, the initial setup effort drops dramatically, eliminating the need to manage multiple credential systems on the same machine.
- Verify if you already possess an active SSH key in your operating system's default directory.
ls -la ~/.ssh - If you need to create a new dedicated key for this purpose, run the generator specifying the Ed25519 algorithm for maximum efficiency.
ssh-keygen -t ed25519 -C "[email protected]" - Configure Git globally to specify that you want to use the SSH method instead of GPG for your signatures.
git config --global gpg.format ssh - Define which public SSH key file should be responsible for signing commits executed in your environment.
git config --global user.signingkey ~/.ssh/id_ed25519.pub - Enable automatic signing for all new commits executed on your development machine.
git config --global commit.gpgsign true
Validating and troubleshooting common signature failures
After completing configuration, testing whether the mechanism works correctly before pushing code to production is essential. Create a test repository, make a simple change, and execute a commit using the signing flag to verify that Git performs the operation without errors and that the remote platform recognizes authenticity.
A frequent error occurs when the email configured in the repository's local configuration file diverges from the email tied to the cryptographic key. Git rejects the signature if there is any discrepancy in these identity data points. Keeping records synchronized and regularly testing commit status with detailed listing commands ensures your software supply chain remains sound and reliable.
Final considerations on code integrity
Adopting commit signing with GPG or SSH keys raises the technical maturity level of any project, whether personal or enterprise-grade. This practice protects codebases against spoofing attacks and ensures rigorous compliance during security audits. Implementing this standard early in development prevents rework and solidifies an engineering culture built on verifiable trust and absolute transparency.