We have just started to use Git for our source control. We have a central repo and access this via SSH, so we have our respective keys set up in the authorized_keys file on our central server.
When you commit in git the meta data associated with the commit includes for example the user.name, but as far as we can see nothing stops me from setting my user.name to another users user.name and pretending that he/she made the commit.
Is there any way to prevent this in git? For example associating the user.name with a specific SSH key?
Btw my question is not why does git allow this, i've read that there are valid use cases. My question is can this be prevented in any way if we do not want to allow it?
Thanks
As you note, Git allows any user to make any commit with the author and/or committer name and email address set to any (parseable) value. (Any user can also set any commit's author and/or committer date to any arbitrary value, as long as it is something Git sees as a usable date-stamp.)
The way to vet these things on a central server is to note that git push
pushes commits, and then asks or tells the server to set one or more reference names—usually some branch and/or tag names—to point to the new commits. These requests are passed to pre-receive
and update
hooks, which can test out the new commits in whatever way they (the hooks) like, accepting or rejecting the reference-name update.
The pre-receive
hook gets all the update requests at once, on standard input, and can reject the entire push. If it accepts the push, the update
hook then gets each update request one at a time (as command-line arguments), and can reject that specific update.
There is nothing built in to Git itself to do all of this, but there are some add-ons such as Gitolite that can do this for you.
If you want to do this with something other than the crude "author name must match ssh credentials" method, you could consider requiring digital signatures on each commit (but note that the central server would still have to check these signatures and I don't think there is anything to do this in Gitolite). This is substantially trickier; normally one does not sign an individual commit, but rather an annotated tag. Since commits have the form of an authentication tree (Merkle tree), signing a particular tag implies that you trust not only that tag's commit, but all of its ancestor commits as well. (This implication is only as strong as whoever signed it meant it to be, and to find out what they meant you would have to ask them.)
Write a pre-receive
hook and there check the pushing user against the committer and / or author with some mapping.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With