threads / discuss / 6378

Re: Commit signing

Subject: Re: Commit signing

## tl;dr

21 messages between Jan 15, 2007 and Jan 15, 2007.

replies: 20people: 9as markdown or json

Andy Parkins· Jan 15, 2007, 10:00 UTC · lore

Commit signing

Hello,

I was just talking to another developer in my office about version control. He's working with Windows so has chosen Monotone for a version control system. I didn't have any huge objections, as I'm sure monotone can be migrated to git without much trouble (they look to support the same features from my brief reading).

Of course my favourite is git, but we were talking about the certificates needed by monotone for each developer. I assume that monotone therefore signs every commit. It obviously crossed my mind as to how one would do that with git? We obviously already have the ability to sign a tag, but is there a way in which one could sign every commit.

The more I think about it, the more it could be a reasonable question. In my own repository I can obviously create whatever commits i like, claiming them to be from whomever I like just by altering a few config settings. If I put a few of those in my own repository and then managed to persuade Junio to pull from me - wouldn't I have faked commits from another developer? However, I wouldn't be able to fake a gpg signature.

Andy
-- 
Dr Andy Parkins, M Eng (hons), MIEE
andyparkins@gmail.com
Matthias Kestenholz· Jan 15, 2007, 10:13 UTC · re: Andy Parkins · lore
On Mon, 2007-01-15 at 10:00 +0000, Andy Parkins wrote:
Show 7 quoted lines
> Hello,
> 
> I was just talking to another developer in my office about version control.  
> He's working with Windows so has chosen Monotone for a version control 
> system.  I didn't have any huge objections, as I'm sure monotone can be 
> migrated to git without much trouble (they look to support the same features 
> from my brief reading).

The decision to use SHA1 hashes for all objects comes from Monotone, so the design has to be somewhat similar.

Show 5 quoted lines
> Of course my favourite is git, but we were talking about the certificates 
> needed by monotone for each developer.  I assume that monotone therefore 
> signs every commit.  It obviously crossed my mind as to how one would do that 
> with git?  We obviously already have the ability to sign a tag, but is there 
> a way in which one could sign every commit.

You'd need to automatically generate a signed tag for every commit (for example in a post-commit hook? Or use a wrapper script for git-commit which runs git-tag -s afterwards)

Show 7 quoted lines
> 
> The more I think about it, the more it could be a reasonable question.  In my 
> own repository I can obviously create whatever commits i like, claiming them 
> to be from whomever I like just by altering a few config settings.  If I put 
> a few of those in my own repository and then managed to persuade Junio to 
> pull from me - wouldn't I have faked commits from another developer?  
> However, I wouldn't be able to fake a gpg signature.
You just explained why no one should pull from people he does not trust.

I think it would be overkill to sign every single commit, signed tags are enough to sign the whole history (as everyone should know by now).

Matthias
Shawn O. Pearce· Jan 15, 2007, 10:15 UTC · re: Andy Parkins · lore
Andy Parkins <andyparkins@gmail.com> wrote:
Show 18 quoted lines
> I was just talking to another developer in my office about version control.  
> He's working with Windows so has chosen Monotone for a version control 
> system.  I didn't have any huge objections, as I'm sure monotone can be 
> migrated to git without much trouble (they look to support the same features 
> from my brief reading).
> 
> Of course my favourite is git, but we were talking about the certificates 
> needed by monotone for each developer.  I assume that monotone therefore 
> signs every commit.  It obviously crossed my mind as to how one would do that 
> with git?  We obviously already have the ability to sign a tag, but is there 
> a way in which one could sign every commit.
> 
> The more I think about it, the more it could be a reasonable question.  In my 
> own repository I can obviously create whatever commits i like, claiming them 
> to be from whomever I like just by altering a few config settings.  If I put 
> a few of those in my own repository and then managed to persuade Junio to 
> pull from me - wouldn't I have faked commits from another developer?  
> However, I wouldn't be able to fake a gpg signature.

You could sign the content of the raw commit and include the signature in the payload, much like we do with tags. E.g.:

	tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904
	parent 5064201cfd47822e567456fb1d6a76a5e81da800
	parent e6987d056595deace8cba91ce0a2524bb91770a9
	author Shawn O. Pearce <spearce.org> 1168855184 -0400
	committer Shawn O. Pearce <spearce.org> 1168855184 -0400
	Merge branch 'branch' into 'master'.
	-----BEGIN PGP SIGNATURE-----
	Version: GnuPG v1.4.6 (GNU/Linux)
	iD8DBQBFiY2zwMbZpPMRm5oRAll0AJ0ZR+Bu8zjMVe8eEKR8Xr+3QMtndACcC2Kl
	aWSkKLptN0LAOpDinq+aqOc=
	=dZlu
	-----END PGP SIGNATURE-----

But that's horribly ugly and probably vast overkill. Plus the only way to really verify each commit is to have the complete database of PGP public keys handy. A commit-msg hook could probably implement the signing.

What I'm actually doing in one particular environment is checking the committer string against a database of known committer strings associated with the current UNIX uid. My update hook[*1*] performs a `git log --pretty=raw $3 --not --all` query to determine any commits which are coming in as part of this push and which are not already referenced by an existing head or tag in this repository. For each of those the committer line *must* match one stored in the allowed-committers file for the current user, as these are brand new commits being introduced to the repository.

This works well as everyone has a UNIX account on the same system and logs in via SSH. The easiest way for us to share changes is to just push them to a single central repository. That repository is performing the checking. And since every commit signs the entire chain of commits which came before it, we're in effect implicitly signing our commits by pushing them to that server. And other developers are agreeing by building on top of that work.

[*1*] If anyone wants the hook, let me know.  I'd be happy to
      share it.  But since its undocumented I haven't offered it
      up as a contrib in git.git yet.
-- 
Shawn.
Shawn O. Pearce· Jan 15, 2007, 10:27 UTC · re: Shawn O. Pearce · lore
"Shawn O. Pearce" <spearce@spearce.org> wrote:
> Andy Parkins <andyparkins@gmail.com> wrote:
> > Of course my favourite is git, but we were talking about the certificates 
> > needed by monotone for each developer.

One problem here is a certificate does not make a security system. Obviously anyone can generate a certificate and claim anything they want within it, just the same as you can claim anything you want in a Git commit or tag. What's needed is some external method that all interested parties trust to verify a given certificate is associated with a given entity.

> What I'm actually doing in one particular environment is checking
> the committer string against a database of known committer strings
> associated with the current UNIX uid.

In this particular case access to the UNIX system is tightly controlled. Much paperwork must be filled out and signed by multiple people, all of whom recognize the user on sight and know why they need access to that system. They also have checked the user's identity through multiple background checks, fingerprinting, etc.

In other words the entire authentication problem was already solved, trusting the UNIX uid just let Git plug into that seamlessly.

The problem is obviously harder on the Internet. I've never met anyone on this mailing list in person, but the quality (or lack thereof sometimes) is evident in my work, and since its all peer-reviewed anyway Junio finds little risk in incorporating the good stuff into git.git. No certificate required.

-- 
Shawn.
Johannes Schindelin· Jan 15, 2007, 10:43 UTC · re: Shawn O. Pearce · lore
Hi,
On Mon, 15 Jan 2007, Shawn O. Pearce wrote:
> I've never met anyone on this mailing list in person, but the quality 
> (or lack thereof sometimes) is evident in my work, and since its all 
> peer-reviewed anyway Junio finds little risk in incorporating the good 
> stuff into git.git.  No certificate required.

Exactly. I think it is one of the reasons monotone is so unpopular (at least as far as I am concerned): it makes the start really cumbersome. And in the end you gain nothing.

And you see what the result is when looking into corporate projects. More often than not, bureaucratic procedures (e.g. tracking time, meetings, specifications) supersede quality-assuring procedures (e.g. permanent updates on the TODO list, code review, discussion on implementation details), and quite often, the code just sucks.

My favourite example is when I found 34 different (!) implementations of a tree structure in the same project.

So, if you start relying on the validity of code just because somebody signed it, you will reap trouble.

Ciao, Dscho

Daniel Barkalow· Jan 15, 2007, 20:25 UTC · re: Shawn O. Pearce · lore
On Mon, 15 Jan 2007, Shawn O. Pearce wrote:
Show 30 quoted lines
> "Shawn O. Pearce" <spearce@spearce.org> wrote:
> > Andy Parkins <andyparkins@gmail.com> wrote:
> > > Of course my favourite is git, but we were talking about the certificates 
> > > needed by monotone for each developer.
> 
> One problem here is a certificate does not make a security system.
> Obviously anyone can generate a certificate and claim anything they
> want within it, just the same as you can claim anything you want in
> a Git commit or tag.  What's needed is some external method that
> all interested parties trust to verify a given certificate is
> associated with a given entity.
> 
> > What I'm actually doing in one particular environment is checking
> > the committer string against a database of known committer strings
> > associated with the current UNIX uid.
> 
> In this particular case access to the UNIX system is tightly
> controlled.  Much paperwork must be filled out and signed by multiple
> people, all of whom recognize the user on sight and know why they
> need access to that system.  They also have checked the user's
> identity through multiple background checks, fingerprinting, etc.
> 
> In other words the entire authentication problem was already solved,
> trusting the UNIX uid just let Git plug into that seamlessly.
> 
> The problem is obviously harder on the Internet.  I've never
> met anyone on this mailing list in person, but the quality (or
> lack thereof sometimes) is evident in my work, and since its all
> peer-reviewed anyway Junio finds little risk in incorporating the
> good stuff into git.git.  No certificate required.

In theory, we could put certificates as blobs in the repository and reference them in the commit header. The names and such in the certificate would, of course, not be verified in any particular way, but the fingerprint would be an effective identity. We'd be able to tell that a commit was prepared by someone with access to the same certificate that was used to build the reputation.

If we saw certificates with different fingerprints with the same name, we'd know to ask what was going on, because that's suspicious.

Of course, there would be no requirement to sign commits, or to have a certificate, or to get anyone in particular to say anything in particular about a certificate. But you'd be able to create a pseudonym if you wanted and have cryptographicly secure access to it.

	-Daniel
*This .sig left intentionaly blank*
Johannes Schindelin· Jan 15, 2007, 10:31 UTC · re: Shawn O. Pearce · lore
Hi,
On Mon, 15 Jan 2007, Shawn O. Pearce wrote:
Show 43 quoted lines
> Andy Parkins <andyparkins@gmail.com> wrote:
> > I was just talking to another developer in my office about version control.  
> > He's working with Windows so has chosen Monotone for a version control 
> > system.  I didn't have any huge objections, as I'm sure monotone can be 
> > migrated to git without much trouble (they look to support the same features 
> > from my brief reading).
> > 
> > Of course my favourite is git, but we were talking about the certificates 
> > needed by monotone for each developer.  I assume that monotone therefore 
> > signs every commit.  It obviously crossed my mind as to how one would do that 
> > with git?  We obviously already have the ability to sign a tag, but is there 
> > a way in which one could sign every commit.
> > 
> > The more I think about it, the more it could be a reasonable question.  In my 
> > own repository I can obviously create whatever commits i like, claiming them 
> > to be from whomever I like just by altering a few config settings.  If I put 
> > a few of those in my own repository and then managed to persuade Junio to 
> > pull from me - wouldn't I have faked commits from another developer?  
> > However, I wouldn't be able to fake a gpg signature.
> 
> You could sign the content of the raw commit and include the signature
> in the payload, much like we do with tags.  E.g.:
> 
> 	tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904
> 	parent 5064201cfd47822e567456fb1d6a76a5e81da800
> 	parent e6987d056595deace8cba91ce0a2524bb91770a9
> 	author Shawn O. Pearce <spearce.org> 1168855184 -0400
> 	committer Shawn O. Pearce <spearce.org> 1168855184 -0400
> 
> 	Merge branch 'branch' into 'master'.
> 
> 	-----BEGIN PGP SIGNATURE-----
> 	Version: GnuPG v1.4.6 (GNU/Linux)
> 
> 	iD8DBQBFiY2zwMbZpPMRm5oRAll0AJ0ZR+Bu8zjMVe8eEKR8Xr+3QMtndACcC2Kl
> 	aWSkKLptN0LAOpDinq+aqOc=
> 	=dZlu
> 	-----END PGP SIGNATURE-----
> 
> But that's horribly ugly and probably vast overkill.  Plus the only
> way to really verify each commit is to have the complete database of
> PGP public keys handy.  A commit-msg hook could probably implement
> the signing.

But it would only sign the _message_. You would have to sign the whole _raw_ commit message, to include also the ancestry. But there is no hook _between_ constructing that _raw_ commit message and actually writing the commit object (this would have to be in builtin-commit-tree.c:151).

Ciao, Dscho

Shawn O. Pearce· Jan 15, 2007, 10:43 UTC · re: Johannes Schindelin · lore
Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
Show 7 quoted lines
> On Mon, 15 Jan 2007, Shawn O. Pearce wrote:
> > A commit-msg hook could probably implement the signing.
> 
> But it would only sign the _message_. You would have to sign the whole 
> _raw_ commit message, to include also the ancestry. But there is no hook 
> _between_ constructing that _raw_ commit message and actually writing the 
> commit object (this would have to be in builtin-commit-tree.c:151).

Sorry, I was assuming people knew what was in the grey matter upstairs. :-)

I meant to say something along the lines of:
  A commit-msg hook could probably implement the signing.  However
  doing that would require generating the raw commit data using the
  current timestamp, and that would require having git-commit.sh set
  the timestamp into GIT_COMMITTER_DATE and GIT_AUTHOR_DATE before
  it runs the hook, or before git-commit-tree.  Clearly an ugly mess.

Johannes is right. A proper signing would probably need to be done in commit-tree itself. Or commit-tree would need to be invoked to create a dummy commit, fetch it back out with cat-file, sign that, then regenerate the commit with the same prior timestamps. Ugly.

But I don't really see a need for commit signing in Git. The best way to shuttle commits around in Git-space is through published repositories. You probably want to grab whatever is on that repository, and you either trust the repository owner or you don't. If you don't trust the owner, but you trust the pusher, than using 1 annotated tag per push is reasonable and gives you something to verify the repository owner isn't playing games. If you don't trust the pusher than you should be reviewing the changes before deciding to keep them in your project.

But even then annotated tags are overkill. You could just receive the commit SHA1 out-of-band from the pusher (e.g. email, like Junio's hidden X-master-at header) and verify that by hand. 8 digits is probably more than enough to hand-verify the entire commit chain you are receiving.

-- 
Shawn.
Karl Hasselström· Jan 15, 2007, 14:52 UTC · re: Shawn O. Pearce · lore
On 2007-01-15 05:43:36 -0500, Shawn O. Pearce wrote:
Show 11 quoted lines
> If you don't trust the owner, but you trust the pusher, than using 1
> annotated tag per push is reasonable and gives you something to
> verify the repository owner isn't playing games. If you don't trust
> the pusher than you should be reviewing the changes before deciding
> to keep them in your project.
>
> But even then annotated tags are overkill. You could just receive
> the commit SHA1 out-of-band from the pusher (e.g. email, like
> Junio's hidden X-master-at header) and verify that by hand. 8 digits
> is probably more than enough to hand-verify the entire commit chain
> you are receiving.

No. You've just constructed a system whose security depends on a 32-bit hash. This is one of those situations where you really do need all the digits.

-- 
Karl Hasselström, kha@treskal.com
      www.treskal.com/kalle
Andy Parkins· Jan 15, 2007, 10:42 UTC · re: Shawn O. Pearce · lore
On Monday 2007 January 15 10:15, Shawn O. Pearce wrote:
> You could sign the content of the raw commit and include the signature
> in the payload, much like we do with tags.  E.g.:
That looks good to me.
> But that's horribly ugly and probably vast overkill.  Plus the only
> way to really verify each commit is to have the complete database of
> PGP public keys handy.  A commit-msg hook could probably implement
> the signing.

Not such overkill. I wasn't thinking of verifying every commit ever made every time the repository changes. I was thinking more of a situation when a particular commit is identified as being troublesome (like introducing a backdoor), and the person listed as comitter denies all knowledge. At that point one would verify the signature.

As an added extra, the host of the central repository could have a list of "allowed keys" so that only correctly signed commits would be allowed into the repository.

As an example of why this would be useful: let's say we have a developer committing to a maintainer repository who then merges those changes into mainline and pushes up to the central repository (like what happens with Linux). The commits to the central repository are made using the ssh login of the maintainer, but they are adding commits by someone else. What if that someone else isn't allowed to commit to the central? With signed commits the option is available to exclude them.

I don't think the argument that Matthias offered ("You just explained why no one should pull from people he does not trust.") is a good one. One might not want trust to be transitive. Just because I trust you, doesn't not mean that I trust those who you trust. The path of getting commits in via a trusted person, perhaps even via multiple levels of transitive trust might not be something that is wanted in every project. Having signed commits would at least give the option.

Show 9 quoted lines
> What I'm actually doing in one particular environment is checking
> the committer string against a database of known committer strings
> associated with the current UNIX uid.  My update hook[*1*] performs
> a `git log --pretty=raw $3 --not --all` query to determine any
> commits which are coming in as part of this push and which are not
> already referenced by an existing head or tag in this repository.
> For each of those the committer line *must* match one stored in
> the allowed-committers file for the current user, as these are
> brand new commits being introduced to the repository.

This addresses the problem somewhat. However, the problem I'm talking about is where a commit identity has been faked by someone committing to a secondary (or tertiary) level repository. While you are ensuring that the current user is allowed to commit on behalf of someone else to your repository, you haven't protected anything, because they could simply fake their ID to one of the "allowed" set and your test will pass.

> performing the checking.  And since every commit signs the entire
> chain of commits which came before it, we're in effect implicitly

While true, on a big project, with changes mainly in different areas, the fact that I committed a/file1.c after you committed b/file2.c doesn't mean I've signed off on your b/file2.c changes being non-malicious.

This is all just paranoia obviously. It's nothing that is in the remotest bit urgent, or perhaps even practical.

Andy
-- 
Dr Andy Parkins, M Eng (hons), MIEE
andyparkins@gmail.com
Shawn O. Pearce· Jan 15, 2007, 10:56 UTC · re: Andy Parkins · lore
Andy Parkins <andyparkins@gmail.com> wrote:
> On Monday 2007 January 15 10:15, Shawn O. Pearce wrote:
> As an added extra, the host of the central repository could have a list 
> of "allowed keys" so that only correctly signed commits would be allowed into 
> the repository.
But that might reject cases where one commit has been brought up
from other repositories yet its part of a chain of 1,000 commits
now being pushed into the central repository.  You need to allow
the head that is coming in, and everything in its past.
 
Show 7 quoted lines
> As an example of why this would be useful: let's say we have a developer 
> committing to a maintainer repository who then merges those changes into 
> mainline and pushes up to the central repository (like what happens with 
> Linux).  The commits to the central repository are made using the ssh login 
> of the maintainer, but they are adding commits by someone else.  What if that 
> someone else isn't allowed to commit to the central?  With signed commits the 
> option is available to exclude them.

You can't just clip commits out during a push! Are you going to reject the push because the trusted SSH-logged in maintainer has pulled in changes from elsewhere and has decided that they are good enough for inclusion?

Show 7 quoted lines
> I don't think the argument that Matthias offered ("You just explained why no 
> one should pull from people he does not trust.") is a good one.  One might 
> not want trust to be transitive.  Just because I trust you, doesn't not mean 
> that I trust those who you trust.  The path of getting commits in via a 
> trusted person, perhaps even via multiple levels of transitive trust might 
> not be something that is wanted in every project.  Having signed commits 
> would at least give the option.
Yes, that's very valid.  But if you trust me and I've gone and
built 100 commits on top of something I got from someone else I
trust but that you don't trust, you are going to reject all of my
changes and ask that I rewrite them?  That's quite paranoid.
 
Show 10 quoted lines
> > What I'm actually doing in one particular environment is checking
> > the committer string against a database of known committer strings
> > associated with the current UNIX uid.
> 
> This addresses the problem somewhat.  However, the problem I'm talking about 
> is where a commit identity has been faked by someone committing to a 
> secondary (or tertiary) level repository.  While you are ensuring that the 
> current user is allowed to commit on behalf of someone else to your 
> repository, you haven't protected anything, because they could simply fake 
> their ID to one of the "allowed" set and your test will pass.

Actually I'm checking for exact matching against the committer string. Every UNIX uid has exactly one (and only one) committer string associated with it. The name on their payroll and security paperwork, and the corporate email that was assigned to them. So you *cannot* push something which was committed by another user or which you committed for them on their behalf. But you can set the author field to anything you want; indeeded I often copy in changes from other people and mark them as the author will retaining the committer line as myself.

This causes a huge problem with our local mirror of git.git. Normally I would just run git-fetch on the server to update the mirror (thus bypassing the update hook, which screams out that I'm not Junio) but that system doesn't have cURL or expat built and I can only fetch over HTTP from there. So I wind up having to go through extra hoops to update commits which came from someone I trust, but which ain't me.

-- 
Shawn.
Johannes Schindelin· Jan 15, 2007, 11:08 UTC · re: Shawn O. Pearce · lore
Hi,
On Mon, 15 Jan 2007, Shawn O. Pearce wrote:
Show 14 quoted lines
> Andy Parkins <andyparkins@gmail.com> wrote:
> 
> > I don't think the argument that Matthias offered ("You just explained 
> > why no one should pull from people he does not trust.") is a good one.  
> > One might not want trust to be transitive.  Just because I trust you, 
> > doesn't not mean that I trust those who you trust.  The path of 
> > getting commits in via a trusted person, perhaps even via multiple 
> > levels of transitive trust might not be something that is wanted in 
> > every project.  Having signed commits would at least give the option.
> 
> Yes, that's very valid.  But if you trust me and I've gone and built 100 
> commits on top of something I got from someone else I trust but that you 
> don't trust, you are going to reject all of my changes and ask that I 
> rewrite them?  That's quite paranoid.
It is not only paranoid. It is bad practice.

We might be tempted to forget in these horrible times that distrust itself is a perpetuum mobile. Distrust results in distrust. And nobody being distrusted likes that fact. It makes for a bad working environment, for less code quality, and quite often, people get ideas from being distrusted: "If they think I could include a backdoor, well, that might actually be a good idea!".

Please have a look at the Linux kernel development, or for that matter, git development itself. Here, people care, people trust, people respect each other (sometimes YELLING, to keep discussions exciting). And the result is: nice code.

Ciao, Dscho

Andy Parkins· Jan 15, 2007, 11:50 UTC · re: Johannes Schindelin · lore
On Monday 2007 January 15 11:08, Johannes Schindelin wrote:
> It is not only paranoid. It is bad practice.

True. However, I don't see that it is Git's place to dictate policy. If a company wants to use Git and wants to use it in an oppressive and inefficient manner, while alienating their developers, who are we to stand in their way?

> Please have a look at the Linux kernel development, or for that matter,
> git development itself. Here, people care, people trust, people respect
> each other (sometimes YELLING, to keep discussions exciting). And the
> result is: nice code.

Again true. What has that to do with Git though? Why shouldn't Git have features that let people with different methods of development from you use it? It is certainly true that signed commits /is/ a feature. And it's a feature that some people might want. If there isn't a technical argument against it, what does it matter?

(Note: it doesn't matter enough to me that I would put the time in, I'm arguing in the abstract really - should features be kept out because they allow a development method we would find distasteful?)

Andy
-- 
Dr Andy Parkins, M Eng (hons), MIEE
andyparkins@gmail.com
Johannes Schindelin· Jan 15, 2007, 12:02 UTC · re: Andy Parkins · lore
Hi,
On Mon, 15 Jan 2007, Andy Parkins wrote:
Show 7 quoted lines
> It is certainly true that signed commits /is/ a feature.  And it's a 
> feature that some people might want.  If there isn't a technical 
> argument against it, what does it matter?
> 
> (Note: it doesn't matter enough to me that I would put the time in, I'm 
> arguing in the abstract really - should features be kept out because 
> they allow a development method we would find distasteful?)

You gave the answer yourself: until there is somebody who needs it, I guess it will not be there.

Note that it would be relatively easy: I already gave the location where the hook should go (builtin-commit-tree.c, line 151), and you can see an example how to execute a hook in receive-pack.c, lines 67ff.

Ciao, Dscho

P.S.: Yes, I am encouraging you to implement it.
Andy Parkins· Jan 15, 2007, 11:41 UTC · re: Shawn O. Pearce · lore
On Monday 2007 January 15 10:56, Shawn O. Pearce wrote:
> You can't just clip commits out during a push!  Are you going to
> reject the push because the trusted SSH-logged in maintainer has
> pulled in changes from elsewhere and has decided that they are good
> enough for inclusion?
Yes.
What about this set of repositories
 Central - Maintainer - Lieutenant - Subsystem Maintainer - Idiot - Vandal
While I'm not saying that it should be mandatory, I do think that the central 
repository should have an optional way of stopping the vandal using the 
idiot's repository to push unnoticed bad changes in under somebody else's 
name.  What about:
 * Vandal spends one year developing reasonable relationship with Idiot, all
   patches are good.  Occasional big patches are pulled by Idiot.
 * Vandal prepares extra big series of commits, with ostensibly good
   functionality.  In the middle of large series adds one small commit with
   the committer set to someone other than himself.  In fact, he sets it to be
   someone he doesn't like.
 * Idiot pulls from Vandal's repository.
 * pull, pull, pull, push because we all trust the person we're pulling from.
 * Vandal's changes are now in Central.
> Yes, that's very valid.  But if you trust me and I've gone and
> built 100 commits on top of something I got from someone else I
> trust but that you don't trust, you are going to reject all of my
> changes and ask that I rewrite them?  That's quite paranoid.

Well yes. I personally wouldn't bother, but I'm casting myself in the role of "paranoid" maintainer for this discussion.

The answer is: no, you can't put your 100+X commits in my repository because I don't trust the person who wrote X of them. It is paranoid, and it is overkill, but it is also /my/ repository. It might also be that you are my employee and you will do as you are damn well told.

I'm arguing that git should cater for the borderline sociopath as well as the well adjusted developer as well. After all, PHB's need version control too :-)

> the author field to anything you want; indeeded I often copy in
> changes from other people and mark them as the author will retaining
> the committer line as myself.

In the case above, it is the distributed nature of git that causes the problem, the original comitter is Idiot, but the repository that the changes use to get into central is Maintainer's.

This has spiralled more than I ever intended anyway. You (and Johannes) have answered my question: namely that there isn't an easy way to do it (with a commit script) and that it's not really a major issue anyway.

Andy
-- 
Dr Andy Parkins, M Eng (hons), MIEE
andyparkins@gmail.com
Martin Langhoff· Jan 15, 2007, 18:36 UTC · re: Andy Parkins · lore
On 1/16/07, Andy Parkins <andyparkins@gmail.com> wrote:
> What about this set of repositories
>
>  Central - Maintainer - Lieutenant - Subsystem Maintainer - Idiot - Vandal
...
>  * Vandal spends one year developing reasonable relationship with Idiot, all
>    patches are good.  Occasional big patches are pulled by Idiot.

If you are using signatures, the trojan horse would make sure he gets his patches signed. What is the advantage again?

>  * Vandal prepares extra big series of commits, with ostensibly good
>    functionality.  In the middle of large series adds one small commit with
>    the committer set to someone other than himself.  In fact, he sets it to be
>    someone he doesn't like.
How about
 - not pulling without review
 - pulling only "own" patches from peripheral developers
> Well yes.  I personally wouldn't bother, but I'm casting myself in the role
> of "paranoid" maintainer for this discussion.

And if you are so paranoid, then you review, and mandate that all patches get a lot of reading ;-) because bugs slip in due to idiocy a whole lot more than because of trojans. Maybe you force patches to be sent to a mailing list, discussed and merged in only if they survive the hard-assed review. Like it happens with git or linux.

Show 8 quoted lines
> The answer is: no, you can't put your 100+X commits in my repository because I
> don't trust the person who wrote X of them.  It is paranoid, and it is
> overkill, but it is also /my/ repository.  It might also be that you are my
> employee and you will do as you are damn well told.
>
> I'm arguing that git should cater for the borderline sociopath as well as the
> well adjusted developer as well.  After all, PHB's need version control
> too :-)

Architecturally, you can't rewrite history just like that -- merge skipping patches isn't possible. You _can_, however, cancel a merge because something looks fishy.

> In the case above, it is the distributed nature of git that causes the
> problem, the original comitter is Idiot, but the repository that the changes
> use to get into central is Maintainer's.

IIRC Linus discussed this early on, and his view was that authorship only gives you false security. The only security is in reviewing code. And that the code-signed patches are dog-slow too.

cheers,
martin
Andy Parkins· Jan 15, 2007, 19:23 UTC · re: Martin Langhoff · lore
On Monday 2007, January 15 18:36, Martin Langhoff wrote:
Show 5 quoted lines
> >  * Vandal spends one year developing reasonable relationship with Idiot,
> > all patches are good.  Occasional big patches are pulled by Idiot.
>
> If you are using signatures, the trojan horse would make sure he gets
> his patches signed. What is the advantage again?

He can't sign it as someone else, and so when it is eventually discovered the culprit can be hunted down and flogged.

> IIRC Linus discussed this early on, and his view was that authorship
> only gives you false security. The only security is in reviewing code.
> And that the code-signed patches are dog-slow too.

Eh? It's only a little bit of extra text to carry around. It's signed by the original author when it enters a repository, so it's not a huge price to pay in any one place. The checking, if you wanted to enable it, would only be done once per incoming commit to a master repository. All-in-all, nothing that you wouldn't be willing to pay if you wanted this feature.

As an aside; I would also suggest that this isn't just about people trojaning a commit. You could also argue that without it, this whole Signed-Off-By business is a bit a moot point.

The signed-off-by lines in the kernel are being used to establish original authorship and entry path of every line in the kernel. It's fairly worthless though when the "signing" is just someone writing an easily forged line of text. For example, what is to stop that naughty lad Linus from adding some code the infringes a copyright to the kernel and adding a "Signed-Off-By: Martin Langhoff" to the bottom? Equally, when SCO come knocking with their "we wrote that line", a secure digital signature chain would go a long way to proving that a submission wasn't faked.

I'm not sure how far commit signing would go towards preventing that, but it could certainly be part of the solution. Commit signing doesn't have to be all about trusting developers, it can be about recording history in an independently checkable way.

Andy
-- 
Dr Andrew Parkins, M Eng (Hons), AMIEE
andyparkins@gmail.com
Martin Langhoff· Jan 15, 2007, 22:26 UTC · re: Andy Parkins · lore
On 1/16/07, Andy Parkins <andyparkins@gmail.com> wrote:
Show 10 quoted lines
> On Monday 2007, January 15 18:36, Martin Langhoff wrote:
>
> > >  * Vandal spends one year developing reasonable relationship with Idiot,
> > > all patches are good.  Occasional big patches are pulled by Idiot.
> >
> > If you are using signatures, the trojan horse would make sure he gets
> > his patches signed. What is the advantage again?
>
> He can't sign it as someone else, and so when it is eventually discovered the
> culprit can be hunted down and flogged.

Fair enough. But you should should not pull from peripheral devs. Ever. Core developers pull from eachother, everyone else posts patches. That's how it's meant to be used.

And if you do a pull from a peripheral developer (to grab a specific interesting patch series), you review it to check it contains what you expect. As the person doing the merge, _your_ name is on the line.

Show 9 quoted lines
> > IIRC Linus discussed this early on, and his view was that authorship
> > only gives you false security. The only security is in reviewing code.
> > And that the code-signed patches are dog-slow too.
>
> Eh? It's only a little bit of extra text to carry around.  It's signed by the
> original author when it enters a repository, so it's not a huge price to pay
> in any one place.  The checking, if you wanted to enable it, would only be
> done once per incoming commit to a master repository.  All-in-all, nothing
> that you wouldn't be willing to pay if you wanted this feature.

I guess the argument was against the cost of running expensive checks in operations that should be fast. On the other hand, if youare happy for the git internal machinery to ignore alll this, you _could_ add this trivially with a slight modification of the commit msg.

At commit-time, just add a signature block at the bottom, making sure you are including the tree and parent SHA1s in the text signed by the commit (the commit however will have no GPG starts here" line at the top when it is displayed).

> As an aside; I would also suggest that this isn't just about people trojaning
> a commit.  You could also argue that without it, this whole Signed-Off-By
> business is a bit a moot point.
Well, it's covered by a trust-but-review ethos...
Show 8 quoted lines
> The signed-off-by lines in the kernel are being used to establish original
> authorship and entry path of every line in the kernel.  It's fairly worthless
> though when the "signing" is just someone writing an easily forged line of
> text.  For example, what is to stop that naughty lad Linus from adding some
> code the infringes a copyright to the kernel and adding a "Signed-Off-By:
> Martin Langhoff" to the bottom?  Equally, when SCO come knocking with
> their "we wrote that line", a secure digital signature chain would go a long
> way to proving that a submission wasn't faked.

Oh, evil Linus. It takes a bit more work to take my name in vain. SMTP hosts, IP addresses of the sending machine, etc. And yet...

<social, nontechnical commentary follows>

... you probably know about Debian and its keysigning parties. One of the net results is that pretty much nobody reviews the work developers do in their packages. Nobody. All signed and pretty, but in most debian packages the review is nil. And you can mostly trust that a given upload came from me or someone that has my keys. Sure. But trust has smothered review.

So while I don't disagree that it can be implemented easily, I doubt it will improve the technical quality of a project to introduce it. And it is trivial to prove that it lowers the social/human quality, as it brings in all sorts of politics and exclusion games (present in CVS/SVN today). Starting from the "are you in the keychain?" game, to forcing passport-based keysigning parties (not bad in itself) that lead to bs like "I don't trust non-western-central-country-passports", "I don't think you look like your passport picture". And then smart people get tired and do stuff like this http://blog.madduck.net/geek/2006.05.24-tr-id-at-keysigning

Sorry about the rant :-) but I consider this kind of stuff a good reason to stay away from a project. Judge the patch, nothing else.

martin
Johannes Schindelin· Jan 15, 2007, 10:59 UTC · re: Andy Parkins · lore
Hi,
On Mon, 15 Jan 2007, Andy Parkins wrote:
Show 7 quoted lines
> As an example of why this would be useful: let's say we have a developer 
> committing to a maintainer repository who then merges those changes into 
> mainline and pushes up to the central repository (like what happens with 
> Linux).  The commits to the central repository are made using the ssh 
> login of the maintainer, but they are adding commits by someone else.  
> What if that someone else isn't allowed to commit to the central?  With 
> signed commits the option is available to exclude them.

IMHO the thinko is the old CVS one. With git we _discourage_ a central repository where everybody pushes into. We _encourage_ local repositories, which are controlled by _one_ person.

If you need a central repository with one "official" version, then designate a release officer. This officer is responsible to keep the repository clean. And I _guarantee_ you that she can tell where she pulled bad commits from: it is written down in the "Merge from" message.

And BTW you have no option to exclude unsigned commits when pushing to a repository. It is either all in or all out.

Ciao, Dscho

Jeff King· Jan 15, 2007, 21:11 UTC · re: Jakub Narebski · lore
On Mon, Jan 15, 2007 at 09:24:55PM +0100, Jakub Narebski wrote:
> By the way, how to make tag pointing to a out-of-tree blob, like
> junio-gpg-pub tag in git.git?
git-tag will accept the usual object syntax:
  git-tag magic HEAD:foo
  git-tag magic e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
So you just need to create the blob:
  git-hash-object -w foo

If you make an annotated tag, git-show will give you the actual tag; looks like it doesn't peel away unless it's a commit.

-Peff

← back to recent threads