Search code examples
gitversion-controlgitlab

Verifying git commit without gpg signing


We started using git as VCS, with previously using SVN, and found out that in git you can easily distuingish the real person behind changes and commits. Now we are wondering why this design choice was made and if there is a thing we overlook.

Let's asume the following things:

  1. Everybody has registered an ssh key to gitlab
  2. Commits are not signed with gpg
  3. Everybody uses git bash using the registered ssh key

Now as we all know the author and committer is just meta-data for git and can easily be spoofed like this:

  1. git config --global --add user.email [email protected]
  2. git config --global --add user.name "Incognito User"
  3. git commit -m "You don't know who I really am" --author="Max Mustermann "
  4. git push

The metadata for the commit would then look something like this:

Author:     Max Mustermann <[email protected]>
AuthorDate: Mon Jun 4 13:12:47 2018 +0200
Commit:     Incognito User <[email protected]>
CommitDate: Mon Jun 4 13:13:26 2018 +0200

Now I thought there has to be a way to find the used ssh key or real person for the commit, since the terminal and the system know the key and thus the real person behind the commit and push.

Question: Is there no way at all to find out the real person without using gpg signing?

PS: No, we don't distrust each other to exploit this, but we are rather curious and want to understand.


Solution

  • Update - copying the information from torek's comment, because I believe this context is important enough that it should be available in the answer itself instead of just in the comments:


    First, you need to separate git from gitlab. As far as git is concerned, ssh is just one of the possible protocols you might use to connect to your server. Your ssh key, or the validity thereof, doesn't matter to git; that's between you and your server as the server authenticates you so that it can decide if you're authorized to connect via ssh.

    (The server might perform more granular authorization checks, especially for hosts like gitlab whose whole function is to integrate with git. Nonetheless, this is the host's business, not git's.)

    Hosting services like gitlab may choose to log activity based on the ssh key, or they may not. Even if they do, that only tells you who pushed the commit into that server, which may not be the same as the author or the committer. For example:

    Let's say Alice wrote the code; she's the author. She sent a copy of her work to Bob. Bob put the code into a local git repo. Bob is the committer. Bob created a bundle file and sent it to Cindy. Now Cindy loads Bob's commit containing Alice's code into her local repo, then pushes to gitlab using her ssh key. Now, git itself doesn't care about Cindy's role in this; she's not the author and she's not the committer. But if gitlab chooses to log activity based on ssh key, gitlab may log that Cindy introduced the commit to that server.

    The method for creating verifiable commits in git is to use signatures[1]. So no, there is "no way at all to find out the real person without using [git's mechanism for recording the real person]".

    Note that this arises from the distributed nature of Git. Without some sort of external constraint, it's impossible to say if Cindy is legitimately relaying Alice and Bob's work. With SVN, there's one clearly-distinguished central server / Source of Truth, and Alice must connect to that server to create a commit, after which Bob must connect to that server, and Cindy must connect to that server. Each individual connects individually to the server. Unlike SVN, Git does not assume this must always happen. If you want to enforce such a policy yourself, you can by having your server do it.

    -torek


    [1] And while I don't know if their views have changed, at least some of the git devs early on stated the belief that signing tags - not directly signing commits - is the right way to do it.