mu88
mu88

Reputation: 5404

Git signature verification

I'm new to the subject of signing Git commits and I'd like to understand how the process of verifying a GPG signature actually works. I already stumbled across these links, but none of them answers my question exactly:

The missing part for me is the following: lets say Bob creates and signs a Git commit using [email protected]. His GPG signature uses [email protected] as well and is uploaded to Bob's GitHub account. GitHub finds Bob's GPG signature and successfully verifies the Git commit.

But how does GitHub create the link between the creator of the Git commit and the GPG signature to use? Are they iterating over all registered email addresses on GitHub to find a matching one and use the corresponding GPG signature?

Or in other words: if Eve creates a GPG signature using [email protected], uploads it to Eve's GitHub account and creates and signs a commit: will the commit be marked as invalid on GitHub since Eve's GPG signature using bob@example does not belong to Bob?
At least that's how I'd expect it to work, but I want to be sure that I'm not working with wrong expectations.

Thanks!

Upvotes: 3

Views: 1176

Answers (2)

VonC
VonC

Reputation: 1327024

But how does GitHub create the link between the creator of the Git commit and the GPG signature to use?

The nature of that link has changed with:

Persistent commit signature verification is generally available (Dec. 2024)

We’re excited to announce that persistent commit signature verification is now generally available! This powerful feature ensures that commit signatures are verified once at the time of the push and remain permanently verified within their respective repository’s network.

With persistent commit signature verification, commit signatures retain their verified status even if signing keys are rotated, revoked, or contributors leave the organization.
You can view verification timestamps by hovering over the > badge on GitHub or by accessing the verified_at field through the REST API.

https://github.com/user-attachments/assets/f1b58fb5-1ffb-4669-a1df-4bb791cb15e6 -- A badge tooltip displaying the date when the signature was first verified.

This feature brings long-term reliability to your commit history, offering a consistent solution for managing commit signatures over time.
New commits have had persistent records since the public preview launch.
Existing commits progressively gain persistent records during their next verification, such as when viewing the Verified badge on GitHub or retrieving the commit via the REST API.

Learn more about commit signature verification and join the conversation in the GitHub Community.

And:

When a commit signature is verified upon being pushed to GitHub, a verification record is stored alongside the commit. This record can't be edited and will persist so that signatures remain verified over time, even if signing keys are rotated, revoked, or if contributors leave the organization.

Persistent commit signature verification applies to new commits pushed to GitHub. For any commits that predate this feature, a persistent record will be created the next time the commit's signature is verified on GitHub, helping ensure that verified statuses remain stable and reliable across the repository's history.

The verification record is persistent across the repository network, meaning that if the same commit is pushed again to the same repository or to any of its forks, the existing verification record is reused. This allows GitHub to maintain a consistent verified status across related repositories without re-verifying the commit each time it appears within the network.

When using the Rebase and Merge option on a pull request, it's important to note that the commits in the head branch are added to the base branch without commit signature verification.
When you use this option, GitHub creates a modified commit, using the data and content of the original commit. This means that GitHub didn't truly create this commit, and can't therefore sign it as a generic system user. GitHub doesn't have access to the committer's private signing keys, so it can't sign the commit on the user's behalf.

A workaround for this is to rebase and merge locally, and then push the changes to the pull request's base branch.

Upvotes: 1

bk2204
bk2204

Reputation: 76784

Each user on GitHub can upload their public key to GitHub to be used for verifying commits. Only the keys that the user has uploaded are considered valid for verifying that user's commits.

When a commit comes in, GitHub inspects the email addresses in the author and committer headers of the commit, and it uses that to determine the accounts associated with it. For signatures, only the committer account is considered, since the commit was created by the committer and could only have been validly signed by them. Then, if that user has a public key and the commit is signed, GitHub will use that key to verify it.

When we verify any secure digital signature, we learn one of two things. Either we learn that both the given key signed the message and the message has not been modified, or we learn that something else has occurred. That something else could be a different key signed the message, that the message was modified, or that a bug of some sort occurred, but all we know in that case is that the signature is not valid for that key-message combination.

If Eve tries to sign a commit for Bob, then GitHub will try to verify the signature with Bob's key, and it will fail verification. The commit will be flagged as unverified.

Upvotes: 3

Related Questions