{"thread":{"id":"45302","subject":"[Request for Documentation] Differentiate signed (commits/tags/pushes)","startedAt":"2017-03-06T19:59:55Z","lastAt":"2017-03-08T05:42:13Z","messageCount":13,"participants":["Stefan Beller","Junio C Hamano","Jakub Narębski","Jeff King","Matthieu Moy","Tom Jones"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"313353","messageId":"CAGZ79kYxD9B_+3vBgO+Z-wh2GMg_REazA-xpTSAqe3_64VMV3w@mail.gmail.com","threadId":"45302","inReplyTo":null,"subject":"[Request for Documentation] Differentiate signed (commits/tags/pushes)","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-03-06T19:59:24Z","receivedAt":"2017-03-06T19:59:55Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"When discussing migrating to a new hashing function, I tried to learn\nabout the subtleties of the different things that can be gpg-signed in\nGit.\n\nWhat is the difference between signed commits and tags?\n(Not from a technical perspective, but for the end user)\n\nBoth of them certify that a given tree is the desired\ncontent for your repository, but git-tag seems to be designed for\nconveying a trusted state to collaborators, whereas git-commit\nis primarily designed to just record a state.\n\nSo in which case would I want to use a signed commit?\n(which then overlaps with signed pushes)\n\nA signed push can certify that a given payload (consisting\nof multiple commits on possibly multiple branches) was transmitted\nto a remote, which can be recorded by the remote as e.g. a proof\nof work.\n\nThe man page of git-commit doesn't discuss gpg signing at all,\ngit-tag has some discussion on how to properly use tags. Maybe\nthere we could have a discussion on when not to use tags, but\nrather signed commits?\n\nOff list I was told gpg-signed commits are a \"checkbox feature\",\ni.e. no real world workflow would actually use it. (That's a bold\nstatement, someone has to use it as there was enough interest\nto implement it, no?)\n\nThanks,\nStefan\n"},{"id":"313377","messageId":"xmqqshmqm4ur.fsf@junio-linux.mtv.corp.google.com","threadId":"45302","inReplyTo":"CAGZ79kYxD9B_+3vBgO+Z-wh2GMg_REazA-xpTSAqe3_64VMV3w@mail.gmail.com","subject":"Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-03-06T22:13:00Z","receivedAt":"2017-03-06T22:13:48Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Stefan Beller <sbeller@google.com> writes:\n\n> What is the difference between signed commits and tags?\n> (Not from a technical perspective, but for the end user)\n\nWhen you \"commit -s\", you are signing the bytes in the commit\nobject, which means that you are attesting the fact that the tree\nyou wanted to record is one of the 47 other colliding tree objects\nthat happen to share that 40-hex hash value, and also the fact that\nthe commits you wanted to record as its parents have certain SHA-1\nhash values.  As you are relying on the resistance to preimage\nattack against SHA-1 at least locally around that signed commit,\nthere wouldn't be meaningful difference between a 50-commit series\neach of which is individually signed with \"commit -s\", such a\n50-commit series, only the top of which is signed with \"commit -s\",\nand the same 50-commit series, on the top of which is signed with\n\"tag -s\".\n\n\"tag -s\" also has the benefit of being retroactive.  You can create\ncommit, think about it for a week and then later tag it.  And ask\nothers to also tag the same one.  You cannot do so with \"commit -s\".\n\n> A signed push can certify that a given payload (consisting\n> of multiple commits on possibly multiple branches) was transmitted\n> to a remote, which can be recorded by the remote as e.g. a proof\n> of work.\n\nA signed push is _NOT_ about certifying the objects in the history\nDAG.  It is about certifying the _intent_ of pointing _REFS_ into\npoints in the object graph.  \"This is a commit I made to add feature\nfrotz\" is something you might say with \"commit -s\" and \"these\ncommits behind this point are for upcoming 2.13 release\" is\nsomething you might say with \"tag -s v2.13-rc0\".  But \"I made it\"\nand \"I made it for this purpose\" are different things.  I may not\nwant the \"feature frotz\" commit included in the maintenance track,\nso it would be a mistake for push a history that contains it to\nupdate refs/heads/maint ref.  A push certificate can protect hosting\nsites like GitHub, when I complain to them saying \"you guys are\npointing at a wrong commit with refs/heads/maint\", by allowing them\nto respond with \"well, you made the push to perform that update and\nhere is what you GPG signed\".\n\n> Off list I was told gpg-signed commits are a \"checkbox feature\",\n> i.e. no real world workflow would actually use it. (That's a bold\n> statement, someone has to use it as there was enough interest\n> to implement it, no?)\n\nI'd agree with that \"checkbox\" description, except that you need to\nremember that a project can enforce _any_ workflow to its developer,\neven if it does not make much sense, and at that point, the workflow\nwould become a real-world workflow.  The word \"real world workflow\"\ndoes not make any assurance if that workflow is sensible.\n\nHistorically, \"tag -s\" came a lot earlier.  When a project for\nwhatever reason wants signature for each and every commit so that\nthey somehow can feel good, without \"commit -s\", it would have made\nus unnecessary work to scale tag namespace only because there will\nbe tons of pointless tags.  \"commit -s\" was a remedy for that.\n"},{"id":"313382","messageId":"CAGZ79kZU+-5D0bHSA1duRLnvjb+P67AzGhESS6J1z5qtO8SXsQ@mail.gmail.com","threadId":"45302","inReplyTo":"xmqqshmqm4ur.fsf@junio-linux.mtv.corp.google.com","subject":"Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-03-06T22:52:37Z","receivedAt":"2017-03-06T22:59:23Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Mon, Mar 6, 2017 at 2:13 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Stefan Beller <sbeller@google.com> writes:\n>\n>> What is the difference between signed commits and tags?\n>> (Not from a technical perspective, but for the end user)\n>\n> When you \"commit -s\", you are signing the bytes in the commit\n> object, which means that you are attesting the fact that the tree\n> you wanted to record is one of the 47 other colliding tree objects\n> that happen to share that 40-hex hash value, and also the fact that\n> the commits you wanted to record as its parents have certain SHA-1\n> hash values.  As you are relying on the resistance to preimage\n> attack against SHA-1 at least locally around that signed commit,\n> there wouldn't be meaningful difference between a 50-commit series\n> each of which is individually signed with \"commit -s\", such a\n> 50-commit series, only the top of which is signed with \"commit -s\",\n> and the same 50-commit series, on the top of which is signed with\n> \"tag -s\".\n>\n> \"tag -s\" also has the benefit of being retroactive.  You can create\n> commit, think about it for a week and then later tag it.  And ask\n> others to also tag the same one.  You cannot do so with \"commit -s\".\n\nok, so there is *no* advantage of signing a commit over tags?\nI'll see if I can write a patch that enhances Documentation/git-commit.txt\npointing to git-tag instead.\n\n>> A signed push can certify that a given payload (consisting\n>> of multiple commits on possibly multiple branches) was transmitted\n>> to a remote, which can be recorded by the remote as e.g. a proof\n>> of work.\n>\n> A signed push is _NOT_ about certifying the objects in the history\n\nYes that is my understanding, though I was unclear in writing it.\n\n> I'd agree with that \"checkbox\" description, [...]\n>  \"commit -s\" was a remedy for that.\n\nOut of curiosity: Does (did) such a project exist? Can I read up on that\nand their best practices?\n\nThanks,\nStefan\n"},{"id":"313385","messageId":"47ad8b6d-0a65-2f8c-dcc5-49a8a8d5ab2a@gmail.com","threadId":"45302","inReplyTo":"xmqqshmqm4ur.fsf@junio-linux.mtv.corp.google.com","subject":"Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)","fromName":"Jakub Narębski","fromEmail":"jnareb@gmail.com","sentAt":"2017-03-06T23:59:10Z","receivedAt":"2017-03-07T00:00:37Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"W dniu 06.03.2017 o 23:13, Junio C Hamano pisze:\n> Stefan Beller <sbeller@google.com> writes:\n> \n>> What is the difference between signed commits and tags?\n>> (Not from a technical perspective, but for the end user)\n[...]\n>> Off list I was told gpg-signed commits are a \"checkbox feature\",\n>> i.e. no real world workflow would actually use it. (That's a bold\n>> statement, someone has to use it as there was enough interest\n>> to implement it, no?)\n> \n> I'd agree with that \"checkbox\" description, except that you need to\n> remember that a project can enforce _any_ workflow to its developer,\n> even if it does not make much sense, and at that point, the workflow\n> would become a real-world workflow.  The word \"real world workflow\"\n> does not make any assurance if that workflow is sensible.\n> \n> Historically, \"tag -s\" came a lot earlier.  When a project for\n> whatever reason wants signature for each and every commit so that\n> they somehow can feel good, without \"commit -s\", it would have made\n> us unnecessary work to scale tag namespace only because there will\n> be tons of pointless tags.  \"commit -s\" was a remedy for that.\n\nAlso from what I remember signed commits came before mergetags, that\nis the result of merging a signed tag (storing the signature of\none of parents of the merge commit to not pollute tag namespace).\n\nAnd this workflow, from what I know, is quite useful.\n\n-- \nJakub Narębski\n \n\n"},{"id":"313386","messageId":"xmqq4lz6ymlt.fsf@junio-linux.mtv.corp.google.com","threadId":"45302","inReplyTo":"CAGZ79kZU+-5D0bHSA1duRLnvjb+P67AzGhESS6J1z5qtO8SXsQ@mail.gmail.com","subject":"Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-03-07T00:08:46Z","receivedAt":"2017-03-07T00:10:19Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Stefan Beller <sbeller@google.com> writes:\n\n>> \"tag -s\" also has the benefit of being retroactive.  You can create\n>> commit, think about it for a week and then later tag it.  And ask\n>> others to also tag the same one.  You cannot do so with \"commit -s\".\n>\n> ok, so there is *no* advantage of signing a commit over tags?\n\nDid I say anything that remotely resembles that?  Puzzled.\n\nIf the reason you want to have GPG signature on a commit is not\nbecause you want to mark some meaningful place in the history, but\nyou are signing each and every ones out of some random reason, there\nis no reason why you would want \"tag -s\" them, so you can see it as\nan advantage of \"commit -s\" over \"tag -s\", because to such a\nproject, all commits that are not tagged look the same and there is\nno \"landmark\" value to use \"tag -s\" for each and every one of them.\n"},{"id":"313389","messageId":"xmqqzigyx7o5.fsf@junio-linux.mtv.corp.google.com","threadId":"45302","inReplyTo":"47ad8b6d-0a65-2f8c-dcc5-49a8a8d5ab2a@gmail.com","subject":"Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-03-07T00:16:42Z","receivedAt":"2017-03-07T00:29:47Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jakub Narębski <jnareb@gmail.com> writes:\n\n> Also from what I remember signed commits came before mergetags, that\n> is the result of merging a signed tag (storing the signature of\n> one of parents of the merge commit to not pollute tag namespace).\n>\n> And this workflow, from what I know, is quite useful.\n\nThe \"commit -s\" on a merge commit lets you as the integrator to\nattest that you made that merge.  The \"mergetag\" records the\nsignature by the contributor that says the tip that was merged was\nwhat the contributor wanted to get merged.  \n\nIt is entirely reasonable to sign a merge commit that merges a\nsigned tag.  They serve two different and unrelated purposes.\n\n\n\n"},{"id":"313392","messageId":"xmqq8toiypn0.fsf@junio-linux.mtv.corp.google.com","threadId":"45302","inReplyTo":"xmqqshmqm4ur.fsf@junio-linux.mtv.corp.google.com","subject":"Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-03-06T23:03:15Z","receivedAt":"2017-03-07T01:00:43Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Stefan Beller <sbeller@google.com> writes:\n>\n>> What is the difference between signed commits and tags?\n>> (Not from a technical perspective, but for the end user)\n> ...\n>> A signed push can certify that a given payload (consisting\n>> of multiple commits on possibly multiple branches) was transmitted\n>> to a remote, which can be recorded by the remote as e.g. a proof\n>> of work.\n> ...\n> A signed push is _NOT_ about certifying the objects in the history\n> DAG.  It is about certifying the _intent_ of pointing _REFS_ into\n> points in the object graph.\n> ...\n> Historically, \"tag -s\" came a lot earlier.  When a project for\n> whatever reason wants signature for each and every commit so that\n> they somehow can feel good, without \"commit -s\", it would have made\n> us unnecessary work to scale tag namespace only because there will\n> be tons of pointless tags.  \"commit -s\" was a remedy for that.\n\nWhile we are enumerating them, it is worth mentioning the mergetag\nheader of a commit object.\n\nThis is added to a (merge) commit object when you merged a signed\ntag that points at a commit, and the intent is to eliminate the need\nto _keep_ the ref around that is created only for the purpose of\n\"please pull from me, I tagged and signed the tip of the history I\nwant you to pull\" request.  From that point of view, you could say\nit is also reducing the load on refs/tags/ namespace, but more\nimportantly by not requiring the ref around, it allows you to verify\nthat the merge commit merged the correct tag with _only_ the commit\nobject by reproducing the payload of the signed tag that was merged\nin the commit object in full.\n"},{"id":"313393","messageId":"CAGZ79kYaUsyU9toKjiCahtUC2Ze7KnZ+iMByu6woyZEnH_10kA@mail.gmail.com","threadId":"45302","inReplyTo":"xmqq4lz6ymlt.fsf@junio-linux.mtv.corp.google.com","subject":"Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-03-07T00:58:16Z","receivedAt":"2017-03-07T01:08:54Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Mon, Mar 6, 2017 at 4:08 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Stefan Beller <sbeller@google.com> writes:\n>\n>>> \"tag -s\" also has the benefit of being retroactive.  You can create\n>>> commit, think about it for a week and then later tag it.  And ask\n>>> others to also tag the same one.  You cannot do so with \"commit -s\".\n>>\n>> ok, so there is *no* advantage of signing a commit over tags?\n>\n> Did I say anything that remotely resembles that?  Puzzled.\n\nWell that was brain having a short circuit.\n\n>\n> If the reason you want to have GPG signature on a commit is not\n> because you want to mark some meaningful place in the history, but\n> you are signing each and every ones out of some random reason,\n\nand I am looking for these \"some random reason\"s.\nIf it is e.g. a ISO9001 requirement, I'll happily accept that as such.\n\nBy signing things, you certify your intent, i.e. by signing a commit,\nyou certify that you intent to create the commit as-is in some repository\non some branch (unlike the push certificate that specifies the repo and\nbranch).\n\n> there\n> is no reason why you would want \"tag -s\" them, so you can see it as\n> an advantage of \"commit -s\" over \"tag -s\", because to such a\n> project, all commits that are not tagged look the same and there is\n> no \"landmark\" value to use \"tag -s\" for each and every one of them.\n\nOkay. They are two different things, but to me they seem to archive\nthe same thing, with a tag having more niceties provided.\ne.g. when you make a new release, you could just bump the version\nin the versions file and sign the commit. As the commit is part of the\nmaster branch it would not get lost.\n\nThe formerly mentioned \"not polluting the refs/tags namespace\"\nis applicable to mergetags, that are a side tangent to signing\nthe commit vs creating a tag?\n\nNow as Jakub mentions that signed commits came before the\nmergetags were introduced, the existence of signed commits\nsort of makes sense, as they were there first, but now are\nsuperseded by more powerful tools.\n\n> It is entirely reasonable to sign a merge commit that merges a\n> signed tag.  They serve two different and unrelated purposes.\n\nThe signed tag that gets merged certifies the intent of the lieutenant\nto ask for this specific content to be pulled and integrated, whereas\nthe signing of the commit certifies that the integrator intends to create\nthe merge commit as-is and e.g. resolve the merge conflicts as recorded.\n\nThanks,\nStefan\n"},{"id":"313403","messageId":"20170307092353.ibirvitsxhzn3apz@sigill.intra.peff.net","threadId":"45302","inReplyTo":"CAGZ79kYxD9B_+3vBgO+Z-wh2GMg_REazA-xpTSAqe3_64VMV3w@mail.gmail.com","subject":"Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2017-03-07T09:23:54Z","receivedAt":"2017-03-07T09:25:37Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Mar 06, 2017 at 11:59:24AM -0800, Stefan Beller wrote:\n\n> What is the difference between signed commits and tags?\n> (Not from a technical perspective, but for the end user)\n\nI think git has never really tried to assign any _meaning_ to the\nsignatures. It implements the technical bits and leaves it up to the\nuser and their workflows to decide what a given signature means.\n\nPeople generally seem to take tag signatures to mean one (or both) of:\n\n  1. Certifying that the tree contents at that tag are the official,\n     signed release contents (i.e., this is version 1.0, and I'm the\n     maintainer, so believe me).\n\n  2. Certifying that all the history leading up to that tag is\n     \"official\" in some sense (i.e., I'm the maintainer, and this was\n     the tip of my git tree at the time I tagged the release).\n\nSigning individual commits _could_ convey meaning (2), but \"all history\nleading up\" part is unlikely to be something that the signer needs to\nenforce on every commit.\n\nIn my opinion, the most useful meaning for commit-signing is simply to\ncryptographically certify the identity of the committer. We don't\ncompare the GPG key ident to the \"committer\" field, but IMHO that would\nbe a reasonable optional feature for verify-commit (I say optional\nbecause we're starting to assign semantics now).\n\nI think one of the reasons kernel (and git) developers aren't that\ninterested in signed commits is that they're not really that interesting\nin a patch workflow. You're verifying the committer, who in this project\nis invariably Junio, and we just take his word that whatever is in the\n\"author\" field is reasonable.\n\nBut for a project whose workflow is based around pushing and pulling\ncommits, I think it does make sense. The author field may not always\nmatch the committer (e.g., in a cherry-pick), but it still lets you\ntrace that attestation of the author back to the committer. And it's up\nto UI to make that distinction clear (e.g., if you push a signed\ncherry-pick to GitHub, the commit is labeled with something like \"A U\nThor committed with C O Mitter\", and then you get a little \"Verified\"\ntag for C O Mitter that gives you more information about the signature).\n\nSo I don't think it's just a checkbox feature. It's a useful thing for\ncertain workflows that really want to be able to attribute individual\ncommits with cryptographic strength.\n\n-Peff\n"},{"id":"313405","messageId":"vpqpohtpnet.fsf@anie.imag.fr","threadId":"45302","inReplyTo":"CAGZ79kYxD9B_+3vBgO+Z-wh2GMg_REazA-xpTSAqe3_64VMV3w@mail.gmail.com","subject":"Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2017-03-07T07:16:10Z","receivedAt":"2017-03-07T10:52:59Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Stefan Beller <sbeller@google.com> writes:\n\n> What is the difference between signed commits and tags?\n> (Not from a technical perspective, but for the end user)\n\nIn addition to what the others already said:\n\nIf you use GitHub, then in the web interface you get a \"Verified\" stamp\nfor each signed commits:\nhttps://help.github.com/articles/signing-commits-using-gpg/\n\nIt's not a Git feature but a GitHub one, but given the popularity of\nGitHub, this probably led some users to believe that signed commits are\nmore convenient than signed tags.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"313414","messageId":"20170307094549.GB23052@dufour.oxix.org","threadId":"45302","inReplyTo":"20170307092353.ibirvitsxhzn3apz@sigill.intra.peff.net","subject":"Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)","fromName":"Tom Jones","fromEmail":"tom@oxix.org","sentAt":"2017-03-07T09:45:50Z","receivedAt":"2017-03-07T14:01:39Z","isPatch":false,"sender":{"key":"tom@oxix.org","avatar":"https://avatars.githubusercontent.com/u/1994887?v=4"},"body":"We use git to manage a config management repository for some\nservers.  We have tens of signed commits a day; all get deployed.\nThe logic on each host is roughly \"is signed by sysadmin key and\nis more recent than currently-deployed version\".\n\nAlso, what is all this about \"GPG\"?  The protocol is OpenPGP.  A \nparticular implementation is GnuPG / gpg.  It is completely mad\nthat this implementation detail is in the interface specs for git,\nsuch as --gpg-sign for git-commit(1).\n\nIt is an indictment of a lack of appreciation of the relationship\nbetween interfaces and implementations, and the importance of\nproper treatment thereof.\n\nIf Bob creates Bob's git compatible program, and he happens to use\nBob's OpenPGP implementation, his compatible option for git-commit(1)\nstill has to be called \"--gpg-sign\".  Madness.\n\n  Tom.\n\n"},{"id":"313469","messageId":"CAGZ79kb=ZwaMeGAu_R1Bjt4KyxKHYnP4U-RgA1of7F05E5CCQg@mail.gmail.com","threadId":"45302","inReplyTo":"20170307092353.ibirvitsxhzn3apz@sigill.intra.peff.net","subject":"Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-03-07T22:19:19Z","receivedAt":"2017-03-08T00:14:46Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Tue, Mar 7, 2017 at 1:23 AM, Jeff King <peff@peff.net> wrote:\n> On Mon, Mar 06, 2017 at 11:59:24AM -0800, Stefan Beller wrote:\n>\n>> What is the difference between signed commits and tags?\n>> (Not from a technical perspective, but for the end user)\n>\n> I think git has never really tried to assign any _meaning_ to the\n> signatures. It implements the technical bits and leaves it up to the\n> user and their workflows to decide what a given signature means.\n\nThat is a nihilistic approach? ;)\n\nAs a user I would like to know what I can do with such a signed commit.\nAnd I happen to be an experienced user in the sense that I know\nabout git tag --sign as well as git verify-tag; further reading of\nthese two man pages tells me I can even use git-tag to verify a\ntag. So looking for the verify option in git-commit for signed commits...\nwell, no.  Ah! git-verify-commit it is.\n\nI assumed to have most discussion in git-tag or at least a pointer\nfrom there to further reading.\n\nIn an ideal world we might have a manpage git-trust-model(7),\nthat explains different workflows and when certain signing\nmechanisms make sense and what they protect us from.\nI might write such a man page (after I get the gitmodules\npage done).\n\nOff list I was told\n\"just look at Documentation/technical/signature-format.txt;\nit explains all different things that you can sign or have signed\nstuff\". But as an end user I refuse to look at that. ;)\n\n>\n> People generally seem to take tag signatures to mean one (or both) of:\n>\n>   1. Certifying that the tree contents at that tag are the official,\n>      signed release contents (i.e., this is version 1.0, and I'm the\n>      maintainer, so believe me).\n>\n>   2. Certifying that all the history leading up to that tag is\n>      \"official\" in some sense (i.e., I'm the maintainer, and this was\n>      the tip of my git tree at the time I tagged the release).\n>\n> Signing individual commits _could_ convey meaning (2), but \"all history\n> leading up\" part is unlikely to be something that the signer needs to\n> enforce on every commit.\n\nI was told signed commits could act as a poor mans\npush certificate (again off list :/).\n\n> In my opinion, the most useful meaning for commit-signing is simply to\n> cryptographically certify the identity of the committer. We don't\n> compare the GPG key ident to the \"committer\" field, but IMHO that would\n> be a reasonable optional feature for verify-commit (I say optional\n> because we're starting to assign semantics now).\n\nSo the signed commit focuses on the committer instead of the content\n(which is what tags are rather used for) ?\n\n> I think one of the reasons kernel (and git) developers aren't that\n> interested in signed commits is that they're not really that interesting\n> in a patch workflow. You're verifying the committer, who in this project\n> is invariably Junio, and we just take his word that whatever is in the\n> \"author\" field is reasonable.\n\nWell in such a workflow Junio could also sign the tip-commits of\npu/next before pushing, such that we can trust it was really him doing\nthe maintenance work and not his evil twin.\n\n> But for a project whose workflow is based around pushing and pulling\n> commits, I think it does make sense. The author field may not always\n> match the committer (e.g., in a cherry-pick), but it still lets you\n> trace that attestation of the author back to the committer. And it's up\n> to UI to make that distinction clear (e.g., if you push a signed\n> cherry-pick to GitHub, the commit is labeled with something like \"A U\n> Thor committed with C O Mitter\", and then you get a little \"Verified\"\n> tag for C O Mitter that gives you more information about the signature).\n>\n> So I don't think it's just a checkbox feature. It's a useful thing for\n> certain workflows that really want to be able to attribute individual\n> commits with cryptographic strength.\n\n\"certain workflows\". :(\n\nSee, I really like reading e.g. the \"On Re-tagging\" section of git-tag\nas it doesn't hand wave around the decisions to make.\n\nNow as a user I may already have a workflow that I like. And I might\nwant to \"bring in more security\". Then I have to figure out possible\nattack scenarios and which sort of signing can prevent such an attack.\n\nAnd each organisation has to do that themselves, but we as the provider\nof the tool might have this knowledge because we implemented all\nthese shiny \"sign here, please\" parts.\n\nThanks for the lively discussion,\nStefan\n"},{"id":"313483","messageId":"20170308054155.yad4hetg5twxf4u3@sigill.intra.peff.net","threadId":"45302","inReplyTo":"CAGZ79kb=ZwaMeGAu_R1Bjt4KyxKHYnP4U-RgA1of7F05E5CCQg@mail.gmail.com","subject":"Re: [Request for Documentation] Differentiate signed (commits/tags/pushes)","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2017-03-08T05:41:55Z","receivedAt":"2017-03-08T05:42:13Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Mar 07, 2017 at 02:19:19PM -0800, Stefan Beller wrote:\n\n> On Tue, Mar 7, 2017 at 1:23 AM, Jeff King <peff@peff.net> wrote:\n> > On Mon, Mar 06, 2017 at 11:59:24AM -0800, Stefan Beller wrote:\n> >\n> >> What is the difference between signed commits and tags?\n> >> (Not from a technical perspective, but for the end user)\n> >\n> > I think git has never really tried to assign any _meaning_ to the\n> > signatures. It implements the technical bits and leaves it up to the\n> > user and their workflows to decide what a given signature means.\n> \n> That is a nihilistic approach? ;)\n\nTo some degree. :) I think it is less that we believe in nothing, but\nthat Git has traditionally been a toolkit on which you could build a\nvariety of workflows. We wouldn't want to constrain the low-level tools\nby building too much policy logic into them. And IMHO, nobody has really\nwritten the high-level tools for signing.\n\nI would be happy if somebody wanted to do so. Either separate tools, or\na suite of options and config that could be used to make the existing\ntools help enforce certain policies. E.g., if \"git log --show-signature\"\nwere to complain that the signer id does not match the committer ident,\nwhen a certain config option is set.\n\nHaving a git-trust-model(7) manpage is probably a good idea, but I think\nit's nicer still if users can adopt the trust model with the flip of a\nswitch.\n\n> Off list I was told\n> \"just look at Documentation/technical/signature-format.txt;\n> it explains all different things that you can sign or have signed\n> stuff\". But as an end user I refuse to look at that. ;)\n\nI agree that end users should not have to look at it. But I also think\nit doesn't actually discuss the policy options (i.e., what the\nsignatures could \"mean\"). AFAIK there is not a good discussion of that\nanywhere.\n\n> > Signing individual commits _could_ convey meaning (2), but \"all history\n> > leading up\" part is unlikely to be something that the signer needs to\n> > enforce on every commit.\n> \n> I was told signed commits could act as a poor mans\n> push certificate (again off list :/).\n\nYeah, they could. But you should probably just use push certificates.\nWhich _also_ are missing the high-level workflow bits; I'd be happy to\nget GitHub to start recording push signatures somewhere if people know\nwhat they would want to do with them.\n\nThe idea was discussed of sticking them in git-notes. But I wonder if it\nwould be useful to hand them out during upload-pack, so that somebody\nfetching has a cryptographic chain back to the original pusher (rather\nthan trusting the intermediate server).\n\nI think that is slightly complicated because each push certificate only\nmentions the refs that were pushed. So verifying the ref state for N\nrefs might involve up to N separate push certificates (i.e., the last\none that touched each ref, not just the last one overall).\n\n> > In my opinion, the most useful meaning for commit-signing is simply to\n> > cryptographically certify the identity of the committer. We don't\n> > compare the GPG key ident to the \"committer\" field, but IMHO that would\n> > be a reasonable optional feature for verify-commit (I say optional\n> > because we're starting to assign semantics now).\n> \n> So the signed commit focuses on the committer instead of the content\n> (which is what tags are rather used for) ?\n\nI think it's more subtle than that, and gets into the \"is a commit a\nsnapshot or a diff\" question. We all know that technically the commit\nobject points to a snapshot of the tree. But it also points to a parent,\nand I think what is interesting here is the change between the parent's\ntree and the commit's tree.\n\nSo I would take a commit signature to mean that you are the author of\nthe changes moving from $commit^ to $commit, without making any specific\nattestation of the content in $commit^. IOW, you are really signing the\nchanges and your commit message.\n\n> > I think one of the reasons kernel (and git) developers aren't that\n> > interested in signed commits is that they're not really that interesting\n> > in a patch workflow. You're verifying the committer, who in this project\n> > is invariably Junio, and we just take his word that whatever is in the\n> > \"author\" field is reasonable.\n> \n> Well in such a workflow Junio could also sign the tip-commits of\n> pu/next before pushing, such that we can trust it was really him doing\n> the maintenance work and not his evil twin.\n\nYes, he could. He could also force-push a tag for the current value\n(although git does not handle tag-overwriting very well). That's sort of\nwhat push-certificates were meant to do a better job of.\n\n> > So I don't think it's just a checkbox feature. It's a useful thing for\n> > certain workflows that really want to be able to attribute individual\n> > commits with cryptographic strength.\n> \n> \"certain workflows\". :(\n> \n> See, I really like reading e.g. the \"On Re-tagging\" section of git-tag\n> as it doesn't hand wave around the decisions to make.\n\nOK, less hand-waving. Imagine you are a company with a finite set of\ndevelopers, and you issue each developer a gpg key. They all turn on\ncommit.gpgsign. They all clone from a central GitHub repository, push\nback to topic branches in that repository, and then merge via the\nwebsite.\n\nWhat do the commit signatures buy you? If you treat them as \"I certify\nthat I made the changes in this commit\", then it gives you a\ncryptographic audit trail. When you later find a backdoor in the\nsoftware, you are not left guessing as to who pushed it (since they\ncould easily forge the committer ident in the object header), or even\nwhether it entered the repository via a push or if somebody broke in to\nthe server and modified the repository. You find which commit introduced\nit and check the signature.\n\nOf course a clever attacker would just not sign the backdoor commit. So\nyou'd probably want some policy to notice unsigned commits early\n(e.g., perhaps reject them on push and fetch).\n\n> Now as a user I may already have a workflow that I like. And I might\n> want to \"bring in more security\". Then I have to figure out possible\n> attack scenarios and which sort of signing can prevent such an attack.\n> \n> And each organisation has to do that themselves, but we as the provider\n> of the tool might have this knowledge because we implemented all\n> these shiny \"sign here, please\" parts.\n\nSure. I absolutely think we need better documentation and tools here.\n\n-Peff\n"}]}