git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [Request for Documentation] Differentiate signed (commits/tags/pushes)
@ 2017-03-06 19:59 Stefan Beller
  2017-03-06 22:13 ` Junio C Hamano
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Stefan Beller @ 2017-03-06 19:59 UTC (permalink / raw)
  To: tom, Matthieu Moy, git@vger.kernel.org, Junio C Hamano

When discussing migrating to a new hashing function, I tried to learn
about the subtleties of the different things that can be gpg-signed in
Git.

What is the difference between signed commits and tags?
(Not from a technical perspective, but for the end user)

Both of them certify that a given tree is the desired
content for your repository, but git-tag seems to be designed for
conveying a trusted state to collaborators, whereas git-commit
is primarily designed to just record a state.

So in which case would I want to use a signed commit?
(which then overlaps with signed pushes)

A signed push can certify that a given payload (consisting
of multiple commits on possibly multiple branches) was transmitted
to a remote, which can be recorded by the remote as e.g. a proof
of work.

The man page of git-commit doesn't discuss gpg signing at all,
git-tag has some discussion on how to properly use tags. Maybe
there we could have a discussion on when not to use tags, but
rather signed commits?

Off list I was told gpg-signed commits are a "checkbox feature",
i.e. no real world workflow would actually use it. (That's a bold
statement, someone has to use it as there was enough interest
to implement it, no?)

Thanks,
Stefan

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)
  2017-03-06 19:59 [Request for Documentation] Differentiate signed (commits/tags/pushes) Stefan Beller
@ 2017-03-06 22:13 ` Junio C Hamano
  2017-03-06 22:52   ` Stefan Beller
                     ` (2 more replies)
  2017-03-07  7:16 ` Matthieu Moy
  2017-03-07  9:23 ` Jeff King
  2 siblings, 3 replies; 13+ messages in thread
From: Junio C Hamano @ 2017-03-06 22:13 UTC (permalink / raw)
  To: Stefan Beller; +Cc: tom, Matthieu Moy, git@vger.kernel.org

Stefan Beller <sbeller@google.com> writes:

> What is the difference between signed commits and tags?
> (Not from a technical perspective, but for the end user)

When you "commit -s", you are signing the bytes in the commit
object, which means that you are attesting the fact that the tree
you wanted to record is one of the 47 other colliding tree objects
that happen to share that 40-hex hash value, and also the fact that
the commits you wanted to record as its parents have certain SHA-1
hash values.  As you are relying on the resistance to preimage
attack against SHA-1 at least locally around that signed commit,
there wouldn't be meaningful difference between a 50-commit series
each of which is individually signed with "commit -s", such a
50-commit series, only the top of which is signed with "commit -s",
and the same 50-commit series, on the top of which is signed with
"tag -s".

"tag -s" also has the benefit of being retroactive.  You can create
commit, think about it for a week and then later tag it.  And ask
others to also tag the same one.  You cannot do so with "commit -s".

> A signed push can certify that a given payload (consisting
> of multiple commits on possibly multiple branches) was transmitted
> to a remote, which can be recorded by the remote as e.g. a proof
> of work.

A signed push is _NOT_ about certifying the objects in the history
DAG.  It is about certifying the _intent_ of pointing _REFS_ into
points in the object graph.  "This is a commit I made to add feature
frotz" is something you might say with "commit -s" and "these
commits behind this point are for upcoming 2.13 release" is
something you might say with "tag -s v2.13-rc0".  But "I made it"
and "I made it for this purpose" are different things.  I may not
want the "feature frotz" commit included in the maintenance track,
so it would be a mistake for push a history that contains it to
update refs/heads/maint ref.  A push certificate can protect hosting
sites like GitHub, when I complain to them saying "you guys are
pointing at a wrong commit with refs/heads/maint", by allowing them
to respond with "well, you made the push to perform that update and
here is what you GPG signed".

> Off list I was told gpg-signed commits are a "checkbox feature",
> i.e. no real world workflow would actually use it. (That's a bold
> statement, someone has to use it as there was enough interest
> to implement it, no?)

I'd agree with that "checkbox" description, except that you need to
remember that a project can enforce _any_ workflow to its developer,
even if it does not make much sense, and at that point, the workflow
would become a real-world workflow.  The word "real world workflow"
does not make any assurance if that workflow is sensible.

Historically, "tag -s" came a lot earlier.  When a project for
whatever reason wants signature for each and every commit so that
they somehow can feel good, without "commit -s", it would have made
us unnecessary work to scale tag namespace only because there will
be tons of pointless tags.  "commit -s" was a remedy for that.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)
  2017-03-06 22:13 ` Junio C Hamano
@ 2017-03-06 22:52   ` Stefan Beller
  2017-03-07  0:08     ` Junio C Hamano
  2017-03-06 23:03   ` Junio C Hamano
  2017-03-06 23:59   ` Jakub Narębski
  2 siblings, 1 reply; 13+ messages in thread
From: Stefan Beller @ 2017-03-06 22:52 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: tom, Matthieu Moy, git@vger.kernel.org

On Mon, Mar 6, 2017 at 2:13 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Stefan Beller <sbeller@google.com> writes:
>
>> What is the difference between signed commits and tags?
>> (Not from a technical perspective, but for the end user)
>
> When you "commit -s", you are signing the bytes in the commit
> object, which means that you are attesting the fact that the tree
> you wanted to record is one of the 47 other colliding tree objects
> that happen to share that 40-hex hash value, and also the fact that
> the commits you wanted to record as its parents have certain SHA-1
> hash values.  As you are relying on the resistance to preimage
> attack against SHA-1 at least locally around that signed commit,
> there wouldn't be meaningful difference between a 50-commit series
> each of which is individually signed with "commit -s", such a
> 50-commit series, only the top of which is signed with "commit -s",
> and the same 50-commit series, on the top of which is signed with
> "tag -s".
>
> "tag -s" also has the benefit of being retroactive.  You can create
> commit, think about it for a week and then later tag it.  And ask
> others to also tag the same one.  You cannot do so with "commit -s".

ok, so there is *no* advantage of signing a commit over tags?
I'll see if I can write a patch that enhances Documentation/git-commit.txt
pointing to git-tag instead.

>> A signed push can certify that a given payload (consisting
>> of multiple commits on possibly multiple branches) was transmitted
>> to a remote, which can be recorded by the remote as e.g. a proof
>> of work.
>
> A signed push is _NOT_ about certifying the objects in the history

Yes that is my understanding, though I was unclear in writing it.

> I'd agree with that "checkbox" description, [...]
>  "commit -s" was a remedy for that.

Out of curiosity: Does (did) such a project exist? Can I read up on that
and their best practices?

Thanks,
Stefan

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)
  2017-03-06 22:13 ` Junio C Hamano
  2017-03-06 22:52   ` Stefan Beller
@ 2017-03-06 23:03   ` Junio C Hamano
  2017-03-06 23:59   ` Jakub Narębski
  2 siblings, 0 replies; 13+ messages in thread
From: Junio C Hamano @ 2017-03-06 23:03 UTC (permalink / raw)
  To: Stefan Beller; +Cc: tom, Matthieu Moy, git@vger.kernel.org

Junio C Hamano <gitster@pobox.com> writes:

> Stefan Beller <sbeller@google.com> writes:
>
>> What is the difference between signed commits and tags?
>> (Not from a technical perspective, but for the end user)
> ...
>> A signed push can certify that a given payload (consisting
>> of multiple commits on possibly multiple branches) was transmitted
>> to a remote, which can be recorded by the remote as e.g. a proof
>> of work.
> ...
> A signed push is _NOT_ about certifying the objects in the history
> DAG.  It is about certifying the _intent_ of pointing _REFS_ into
> points in the object graph.
> ...
> Historically, "tag -s" came a lot earlier.  When a project for
> whatever reason wants signature for each and every commit so that
> they somehow can feel good, without "commit -s", it would have made
> us unnecessary work to scale tag namespace only because there will
> be tons of pointless tags.  "commit -s" was a remedy for that.

While we are enumerating them, it is worth mentioning the mergetag
header of a commit object.

This is added to a (merge) commit object when you merged a signed
tag that points at a commit, and the intent is to eliminate the need
to _keep_ the ref around that is created only for the purpose of
"please pull from me, I tagged and signed the tip of the history I
want you to pull" request.  From that point of view, you could say
it is also reducing the load on refs/tags/ namespace, but more
importantly by not requiring the ref around, it allows you to verify
that the merge commit merged the correct tag with _only_ the commit
object by reproducing the payload of the signed tag that was merged
in the commit object in full.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)
  2017-03-06 22:13 ` Junio C Hamano
  2017-03-06 22:52   ` Stefan Beller
  2017-03-06 23:03   ` Junio C Hamano
@ 2017-03-06 23:59   ` Jakub Narębski
  2017-03-07  0:16     ` Junio C Hamano
  2 siblings, 1 reply; 13+ messages in thread
From: Jakub Narębski @ 2017-03-06 23:59 UTC (permalink / raw)
  To: Junio C Hamano, Stefan Beller; +Cc: tom, Matthieu Moy, git@vger.kernel.org

W dniu 06.03.2017 o 23:13, Junio C Hamano pisze:
> Stefan Beller <sbeller@google.com> writes:
> 
>> What is the difference between signed commits and tags?
>> (Not from a technical perspective, but for the end user)
[...]
>> Off list I was told gpg-signed commits are a "checkbox feature",
>> i.e. no real world workflow would actually use it. (That's a bold
>> statement, someone has to use it as there was enough interest
>> to implement it, no?)
> 
> I'd agree with that "checkbox" description, except that you need to
> remember that a project can enforce _any_ workflow to its developer,
> even if it does not make much sense, and at that point, the workflow
> would become a real-world workflow.  The word "real world workflow"
> does not make any assurance if that workflow is sensible.
> 
> Historically, "tag -s" came a lot earlier.  When a project for
> whatever reason wants signature for each and every commit so that
> they somehow can feel good, without "commit -s", it would have made
> us unnecessary work to scale tag namespace only because there will
> be tons of pointless tags.  "commit -s" was a remedy for that.

Also from what I remember signed commits came before mergetags, that
is the result of merging a signed tag (storing the signature of
one of parents of the merge commit to not pollute tag namespace).

And this workflow, from what I know, is quite useful.

-- 
Jakub Narębski
 


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)
  2017-03-06 22:52   ` Stefan Beller
@ 2017-03-07  0:08     ` Junio C Hamano
  2017-03-07  0:58       ` Stefan Beller
  0 siblings, 1 reply; 13+ messages in thread
From: Junio C Hamano @ 2017-03-07  0:08 UTC (permalink / raw)
  To: Stefan Beller; +Cc: tom, Matthieu Moy, git@vger.kernel.org

Stefan Beller <sbeller@google.com> writes:

>> "tag -s" also has the benefit of being retroactive.  You can create
>> commit, think about it for a week and then later tag it.  And ask
>> others to also tag the same one.  You cannot do so with "commit -s".
>
> ok, so there is *no* advantage of signing a commit over tags?

Did I say anything that remotely resembles that?  Puzzled.

If the reason you want to have GPG signature on a commit is not
because you want to mark some meaningful place in the history, but
you are signing each and every ones out of some random reason, there
is no reason why you would want "tag -s" them, so you can see it as
an advantage of "commit -s" over "tag -s", because to such a
project, all commits that are not tagged look the same and there is
no "landmark" value to use "tag -s" for each and every one of them.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)
  2017-03-06 23:59   ` Jakub Narębski
@ 2017-03-07  0:16     ` Junio C Hamano
  0 siblings, 0 replies; 13+ messages in thread
From: Junio C Hamano @ 2017-03-07  0:16 UTC (permalink / raw)
  To: Jakub Narębski; +Cc: Stefan Beller, tom, Matthieu Moy, git@vger.kernel.org

Jakub Narębski <jnareb@gmail.com> writes:

> Also from what I remember signed commits came before mergetags, that
> is the result of merging a signed tag (storing the signature of
> one of parents of the merge commit to not pollute tag namespace).
>
> And this workflow, from what I know, is quite useful.

The "commit -s" on a merge commit lets you as the integrator to
attest that you made that merge.  The "mergetag" records the
signature by the contributor that says the tip that was merged was
what the contributor wanted to get merged.  

It is entirely reasonable to sign a merge commit that merges a
signed tag.  They serve two different and unrelated purposes.




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)
  2017-03-07  0:08     ` Junio C Hamano
@ 2017-03-07  0:58       ` Stefan Beller
  0 siblings, 0 replies; 13+ messages in thread
From: Stefan Beller @ 2017-03-07  0:58 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: tom, Matthieu Moy, git@vger.kernel.org, Jakub Narębski

On Mon, Mar 6, 2017 at 4:08 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Stefan Beller <sbeller@google.com> writes:
>
>>> "tag -s" also has the benefit of being retroactive.  You can create
>>> commit, think about it for a week and then later tag it.  And ask
>>> others to also tag the same one.  You cannot do so with "commit -s".
>>
>> ok, so there is *no* advantage of signing a commit over tags?
>
> Did I say anything that remotely resembles that?  Puzzled.

Well that was brain having a short circuit.

>
> If the reason you want to have GPG signature on a commit is not
> because you want to mark some meaningful place in the history, but
> you are signing each and every ones out of some random reason,

and I am looking for these "some random reason"s.
If it is e.g. a ISO9001 requirement, I'll happily accept that as such.

By signing things, you certify your intent, i.e. by signing a commit,
you certify that you intent to create the commit as-is in some repository
on some branch (unlike the push certificate that specifies the repo and
branch).

> there
> is no reason why you would want "tag -s" them, so you can see it as
> an advantage of "commit -s" over "tag -s", because to such a
> project, all commits that are not tagged look the same and there is
> no "landmark" value to use "tag -s" for each and every one of them.

Okay. They are two different things, but to me they seem to archive
the same thing, with a tag having more niceties provided.
e.g. when you make a new release, you could just bump the version
in the versions file and sign the commit. As the commit is part of the
master branch it would not get lost.

The formerly mentioned "not polluting the refs/tags namespace"
is applicable to mergetags, that are a side tangent to signing
the commit vs creating a tag?

Now as Jakub mentions that signed commits came before the
mergetags were introduced, the existence of signed commits
sort of makes sense, as they were there first, but now are
superseded by more powerful tools.

> It is entirely reasonable to sign a merge commit that merges a
> signed tag.  They serve two different and unrelated purposes.

The signed tag that gets merged certifies the intent of the lieutenant
to ask for this specific content to be pulled and integrated, whereas
the signing of the commit certifies that the integrator intends to create
the merge commit as-is and e.g. resolve the merge conflicts as recorded.

Thanks,
Stefan

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)
  2017-03-06 19:59 [Request for Documentation] Differentiate signed (commits/tags/pushes) Stefan Beller
  2017-03-06 22:13 ` Junio C Hamano
@ 2017-03-07  7:16 ` Matthieu Moy
  2017-03-07  9:23 ` Jeff King
  2 siblings, 0 replies; 13+ messages in thread
From: Matthieu Moy @ 2017-03-07  7:16 UTC (permalink / raw)
  To: Stefan Beller; +Cc: tom, git@vger.kernel.org, Junio C Hamano

Stefan Beller <sbeller@google.com> writes:

> What is the difference between signed commits and tags?
> (Not from a technical perspective, but for the end user)

In addition to what the others already said:

If you use GitHub, then in the web interface you get a "Verified" stamp
for each signed commits:
https://help.github.com/articles/signing-commits-using-gpg/

It's not a Git feature but a GitHub one, but given the popularity of
GitHub, this probably led some users to believe that signed commits are
more convenient than signed tags.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)
  2017-03-06 19:59 [Request for Documentation] Differentiate signed (commits/tags/pushes) Stefan Beller
  2017-03-06 22:13 ` Junio C Hamano
  2017-03-07  7:16 ` Matthieu Moy
@ 2017-03-07  9:23 ` Jeff King
  2017-03-07  9:45   ` Tom Jones
  2017-03-07 22:19   ` Stefan Beller
  2 siblings, 2 replies; 13+ messages in thread
From: Jeff King @ 2017-03-07  9:23 UTC (permalink / raw)
  To: Stefan Beller; +Cc: tom, Matthieu Moy, git@vger.kernel.org, Junio C Hamano

On Mon, Mar 06, 2017 at 11:59:24AM -0800, Stefan Beller wrote:

> What is the difference between signed commits and tags?
> (Not from a technical perspective, but for the end user)

I think git has never really tried to assign any _meaning_ to the
signatures. It implements the technical bits and leaves it up to the
user and their workflows to decide what a given signature means.

People generally seem to take tag signatures to mean one (or both) of:

  1. Certifying that the tree contents at that tag are the official,
     signed release contents (i.e., this is version 1.0, and I'm the
     maintainer, so believe me).

  2. Certifying that all the history leading up to that tag is
     "official" in some sense (i.e., I'm the maintainer, and this was
     the tip of my git tree at the time I tagged the release).

Signing individual commits _could_ convey meaning (2), but "all history
leading up" part is unlikely to be something that the signer needs to
enforce on every commit.

In my opinion, the most useful meaning for commit-signing is simply to
cryptographically certify the identity of the committer. We don't
compare the GPG key ident to the "committer" field, but IMHO that would
be a reasonable optional feature for verify-commit (I say optional
because we're starting to assign semantics now).

I think one of the reasons kernel (and git) developers aren't that
interested in signed commits is that they're not really that interesting
in a patch workflow. You're verifying the committer, who in this project
is invariably Junio, and we just take his word that whatever is in the
"author" field is reasonable.

But for a project whose workflow is based around pushing and pulling
commits, I think it does make sense. The author field may not always
match the committer (e.g., in a cherry-pick), but it still lets you
trace that attestation of the author back to the committer. And it's up
to UI to make that distinction clear (e.g., if you push a signed
cherry-pick to GitHub, the commit is labeled with something like "A U
Thor committed with C O Mitter", and then you get a little "Verified"
tag for C O Mitter that gives you more information about the signature).

So I don't think it's just a checkbox feature. It's a useful thing for
certain workflows that really want to be able to attribute individual
commits with cryptographic strength.

-Peff

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)
  2017-03-07  9:23 ` Jeff King
@ 2017-03-07  9:45   ` Tom Jones
  2017-03-07 22:19   ` Stefan Beller
  1 sibling, 0 replies; 13+ messages in thread
From: Tom Jones @ 2017-03-07  9:45 UTC (permalink / raw)
  To: Jeff King
  Cc: Stefan Beller, Matthieu Moy, git@vger.kernel.org, Junio C Hamano

We use git to manage a config management repository for some
servers.  We have tens of signed commits a day; all get deployed.
The logic on each host is roughly "is signed by sysadmin key and
is more recent than currently-deployed version".

Also, what is all this about "GPG"?  The protocol is OpenPGP.  A 
particular implementation is GnuPG / gpg.  It is completely mad
that this implementation detail is in the interface specs for git,
such as --gpg-sign for git-commit(1).

It is an indictment of a lack of appreciation of the relationship
between interfaces and implementations, and the importance of
proper treatment thereof.

If Bob creates Bob's git compatible program, and he happens to use
Bob's OpenPGP implementation, his compatible option for git-commit(1)
still has to be called "--gpg-sign".  Madness.

  Tom.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)
  2017-03-07  9:23 ` Jeff King
  2017-03-07  9:45   ` Tom Jones
@ 2017-03-07 22:19   ` Stefan Beller
  2017-03-08  5:41     ` Jeff King
  1 sibling, 1 reply; 13+ messages in thread
From: Stefan Beller @ 2017-03-07 22:19 UTC (permalink / raw)
  To: Jeff King; +Cc: tom, Matthieu Moy, git@vger.kernel.org, Junio C Hamano

On Tue, Mar 7, 2017 at 1:23 AM, Jeff King <peff@peff.net> wrote:
> On Mon, Mar 06, 2017 at 11:59:24AM -0800, Stefan Beller wrote:
>
>> What is the difference between signed commits and tags?
>> (Not from a technical perspective, but for the end user)
>
> I think git has never really tried to assign any _meaning_ to the
> signatures. It implements the technical bits and leaves it up to the
> user and their workflows to decide what a given signature means.

That is a nihilistic approach? ;)

As a user I would like to know what I can do with such a signed commit.
And I happen to be an experienced user in the sense that I know
about git tag --sign as well as git verify-tag; further reading of
these two man pages tells me I can even use git-tag to verify a
tag. So looking for the verify option in git-commit for signed commits...
well, no.  Ah! git-verify-commit it is.

I assumed to have most discussion in git-tag or at least a pointer
from there to further reading.

In an ideal world we might have a manpage git-trust-model(7),
that explains different workflows and when certain signing
mechanisms make sense and what they protect us from.
I might write such a man page (after I get the gitmodules
page done).

Off list I was told
"just look at Documentation/technical/signature-format.txt;
it explains all different things that you can sign or have signed
stuff". But as an end user I refuse to look at that. ;)

>
> People generally seem to take tag signatures to mean one (or both) of:
>
>   1. Certifying that the tree contents at that tag are the official,
>      signed release contents (i.e., this is version 1.0, and I'm the
>      maintainer, so believe me).
>
>   2. Certifying that all the history leading up to that tag is
>      "official" in some sense (i.e., I'm the maintainer, and this was
>      the tip of my git tree at the time I tagged the release).
>
> Signing individual commits _could_ convey meaning (2), but "all history
> leading up" part is unlikely to be something that the signer needs to
> enforce on every commit.

I was told signed commits could act as a poor mans
push certificate (again off list :/).

> In my opinion, the most useful meaning for commit-signing is simply to
> cryptographically certify the identity of the committer. We don't
> compare the GPG key ident to the "committer" field, but IMHO that would
> be a reasonable optional feature for verify-commit (I say optional
> because we're starting to assign semantics now).

So the signed commit focuses on the committer instead of the content
(which is what tags are rather used for) ?

> I think one of the reasons kernel (and git) developers aren't that
> interested in signed commits is that they're not really that interesting
> in a patch workflow. You're verifying the committer, who in this project
> is invariably Junio, and we just take his word that whatever is in the
> "author" field is reasonable.

Well in such a workflow Junio could also sign the tip-commits of
pu/next before pushing, such that we can trust it was really him doing
the maintenance work and not his evil twin.

> But for a project whose workflow is based around pushing and pulling
> commits, I think it does make sense. The author field may not always
> match the committer (e.g., in a cherry-pick), but it still lets you
> trace that attestation of the author back to the committer. And it's up
> to UI to make that distinction clear (e.g., if you push a signed
> cherry-pick to GitHub, the commit is labeled with something like "A U
> Thor committed with C O Mitter", and then you get a little "Verified"
> tag for C O Mitter that gives you more information about the signature).
>
> So I don't think it's just a checkbox feature. It's a useful thing for
> certain workflows that really want to be able to attribute individual
> commits with cryptographic strength.

"certain workflows". :(

See, I really like reading e.g. the "On Re-tagging" section of git-tag
as it doesn't hand wave around the decisions to make.

Now as a user I may already have a workflow that I like. And I might
want to "bring in more security". Then I have to figure out possible
attack scenarios and which sort of signing can prevent such an attack.

And each organisation has to do that themselves, but we as the provider
of the tool might have this knowledge because we implemented all
these shiny "sign here, please" parts.

Thanks for the lively discussion,
Stefan

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)
  2017-03-07 22:19   ` Stefan Beller
@ 2017-03-08  5:41     ` Jeff King
  0 siblings, 0 replies; 13+ messages in thread
From: Jeff King @ 2017-03-08  5:41 UTC (permalink / raw)
  To: Stefan Beller; +Cc: tom, Matthieu Moy, git@vger.kernel.org, Junio C Hamano

On Tue, Mar 07, 2017 at 02:19:19PM -0800, Stefan Beller wrote:

> On Tue, Mar 7, 2017 at 1:23 AM, Jeff King <peff@peff.net> wrote:
> > On Mon, Mar 06, 2017 at 11:59:24AM -0800, Stefan Beller wrote:
> >
> >> What is the difference between signed commits and tags?
> >> (Not from a technical perspective, but for the end user)
> >
> > I think git has never really tried to assign any _meaning_ to the
> > signatures. It implements the technical bits and leaves it up to the
> > user and their workflows to decide what a given signature means.
> 
> That is a nihilistic approach? ;)

To some degree. :) I think it is less that we believe in nothing, but
that Git has traditionally been a toolkit on which you could build a
variety of workflows. We wouldn't want to constrain the low-level tools
by building too much policy logic into them. And IMHO, nobody has really
written the high-level tools for signing.

I would be happy if somebody wanted to do so. Either separate tools, or
a suite of options and config that could be used to make the existing
tools help enforce certain policies. E.g., if "git log --show-signature"
were to complain that the signer id does not match the committer ident,
when a certain config option is set.

Having a git-trust-model(7) manpage is probably a good idea, but I think
it's nicer still if users can adopt the trust model with the flip of a
switch.

> Off list I was told
> "just look at Documentation/technical/signature-format.txt;
> it explains all different things that you can sign or have signed
> stuff". But as an end user I refuse to look at that. ;)

I agree that end users should not have to look at it. But I also think
it doesn't actually discuss the policy options (i.e., what the
signatures could "mean"). AFAIK there is not a good discussion of that
anywhere.

> > Signing individual commits _could_ convey meaning (2), but "all history
> > leading up" part is unlikely to be something that the signer needs to
> > enforce on every commit.
> 
> I was told signed commits could act as a poor mans
> push certificate (again off list :/).

Yeah, they could. But you should probably just use push certificates.
Which _also_ are missing the high-level workflow bits; I'd be happy to
get GitHub to start recording push signatures somewhere if people know
what they would want to do with them.

The idea was discussed of sticking them in git-notes. But I wonder if it
would be useful to hand them out during upload-pack, so that somebody
fetching has a cryptographic chain back to the original pusher (rather
than trusting the intermediate server).

I think that is slightly complicated because each push certificate only
mentions the refs that were pushed. So verifying the ref state for N
refs might involve up to N separate push certificates (i.e., the last
one that touched each ref, not just the last one overall).

> > In my opinion, the most useful meaning for commit-signing is simply to
> > cryptographically certify the identity of the committer. We don't
> > compare the GPG key ident to the "committer" field, but IMHO that would
> > be a reasonable optional feature for verify-commit (I say optional
> > because we're starting to assign semantics now).
> 
> So the signed commit focuses on the committer instead of the content
> (which is what tags are rather used for) ?

I think it's more subtle than that, and gets into the "is a commit a
snapshot or a diff" question. We all know that technically the commit
object points to a snapshot of the tree. But it also points to a parent,
and I think what is interesting here is the change between the parent's
tree and the commit's tree.

So I would take a commit signature to mean that you are the author of
the changes moving from $commit^ to $commit, without making any specific
attestation of the content in $commit^. IOW, you are really signing the
changes and your commit message.

> > I think one of the reasons kernel (and git) developers aren't that
> > interested in signed commits is that they're not really that interesting
> > in a patch workflow. You're verifying the committer, who in this project
> > is invariably Junio, and we just take his word that whatever is in the
> > "author" field is reasonable.
> 
> Well in such a workflow Junio could also sign the tip-commits of
> pu/next before pushing, such that we can trust it was really him doing
> the maintenance work and not his evil twin.

Yes, he could. He could also force-push a tag for the current value
(although git does not handle tag-overwriting very well). That's sort of
what push-certificates were meant to do a better job of.

> > So I don't think it's just a checkbox feature. It's a useful thing for
> > certain workflows that really want to be able to attribute individual
> > commits with cryptographic strength.
> 
> "certain workflows". :(
> 
> See, I really like reading e.g. the "On Re-tagging" section of git-tag
> as it doesn't hand wave around the decisions to make.

OK, less hand-waving. Imagine you are a company with a finite set of
developers, and you issue each developer a gpg key. They all turn on
commit.gpgsign. They all clone from a central GitHub repository, push
back to topic branches in that repository, and then merge via the
website.

What do the commit signatures buy you? If you treat them as "I certify
that I made the changes in this commit", then it gives you a
cryptographic audit trail. When you later find a backdoor in the
software, you are not left guessing as to who pushed it (since they
could easily forge the committer ident in the object header), or even
whether it entered the repository via a push or if somebody broke in to
the server and modified the repository. You find which commit introduced
it and check the signature.

Of course a clever attacker would just not sign the backdoor commit. So
you'd probably want some policy to notice unsigned commits early
(e.g., perhaps reject them on push and fetch).

> Now as a user I may already have a workflow that I like. And I might
> want to "bring in more security". Then I have to figure out possible
> attack scenarios and which sort of signing can prevent such an attack.
> 
> And each organisation has to do that themselves, but we as the provider
> of the tool might have this knowledge because we implemented all
> these shiny "sign here, please" parts.

Sure. I absolutely think we need better documentation and tools here.

-Peff

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2017-03-08  5:42 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-06 19:59 [Request for Documentation] Differentiate signed (commits/tags/pushes) Stefan Beller
2017-03-06 22:13 ` Junio C Hamano
2017-03-06 22:52   ` Stefan Beller
2017-03-07  0:08     ` Junio C Hamano
2017-03-07  0:58       ` Stefan Beller
2017-03-06 23:03   ` Junio C Hamano
2017-03-06 23:59   ` Jakub Narębski
2017-03-07  0:16     ` Junio C Hamano
2017-03-07  7:16 ` Matthieu Moy
2017-03-07  9:23 ` Jeff King
2017-03-07  9:45   ` Tom Jones
2017-03-07 22:19   ` Stefan Beller
2017-03-08  5:41     ` Jeff King

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).