{"thread":{"id":"28516","subject":"Signed push progress?","startedAt":"2011-09-28T07:50:54Z","lastAt":"2011-09-29T11:50:09Z","messageCount":4,"participants":["Robin H. Johnson","Junio C Hamano","Dmitry Ivankov"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"176388","messageId":"20110928075054.GA13727@orbis-terrarum.net","threadId":"28516","inReplyTo":null,"subject":"Signed push progress?","fromName":"Robin H. Johnson","fromEmail":"robbat2@gentoo.org","sentAt":"2011-09-28T07:50:54Z","receivedAt":"2011-09-28T07:50:54Z","isPatch":false,"sender":{"key":"robbat2@gentoo.org","avatar":"https://avatars.githubusercontent.com/u/373898?v=4"},"body":"I haven't seen anything about the status of signed push since earlier in\nthe month, even the what's cooking report marked it as stalled.\n\nWhile I'd previously noted my concerns re the use of SHA1, that's not\npresently a solvable problems, whereas signed-push does improve security\ntoday.\n\nAdditionally, in the ever ongoing discussion about Gentoo's conversion\nfrom CVS to Git (we're very close now), we've decided that the signed\npushes will provide better security than our plan of previous plan of\nusing signed notes, so we'd like to see signed pushes succeed.\n\n-- \nRobin Hugh Johnson\nGentoo Linux: Developer, Trustee & Infrastructure Lead\nE-Mail     : robbat2@gentoo.org\nGnuPG FP   : 11AC BA4F 4778 E3F6 E4ED  F38E B27B 944E 3488 4E85\n"},{"id":"176430","messageId":"7v62kc1v7m.fsf@alter.siamese.dyndns.org","threadId":"28516","inReplyTo":"20110928075054.GA13727@orbis-terrarum.net","subject":"Re: Signed push progress?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-28T16:35:09Z","receivedAt":"2011-09-28T16:35:09Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Robin H. Johnson\" <robbat2@gentoo.org> writes:\n\n> from CVS to Git (we're very close now), we've decided that the signed\n> pushes will provide better security than our plan of previous plan of\n> using signed notes, so we'd like to see signed pushes succeed.\n\nCould you elaborate on your \"previous plan\" a bit? What is a signed note,\nhow would it help validate the authenticity, how do developers interact\nusing it and what do you perceive as weaknesses compared to the signed\npush that we discussed a few weeks ago?\n"},{"id":"176473","messageId":"7vfwjgui8s.fsf_-_@alter.siamese.dyndns.org","threadId":"28516","inReplyTo":"7v62kc1v7m.fsf@alter.siamese.dyndns.org","subject":"What's next for \"signed push\"?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-29T03:42:27Z","receivedAt":"2011-09-29T03:42:27Z","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> \"Robin H. Johnson\" <robbat2@gentoo.org> writes:\n>\n>> from CVS to Git (we're very close now), we've decided that the signed\n>> pushes will provide better security than our plan of previous plan of\n>> using signed notes, so we'd like to see signed pushes succeed.\n>\n> Could you elaborate on your \"previous plan\" a bit? What is a signed note,\n> how would it help validate the authenticity, how do developers interact\n> using it and what do you perceive as weaknesses compared to the signed\n> push that we discussed a few weeks ago?\n\nI was hoping that I could get another food-for-thought from people who\nthought about signed commits before sending this out, but here is my\ncurrent thinking (I retitled your \"Signed push progress\" as there is\nnothing to \"progress\" on without an active discussion).\n\nOriginally, I very much wanted to like the approach of v3 that was meant\nto be simpler by having the logic to record the signed push certificate\nonly on the sending end. At the mechanism level, v3 looked simpler to me,\nbut from the point of view of end users, I doubt that it is simpler than\nthe approach of v2, where the sender prepares a push record, signs and\nsends it, and the receiver records it to its notes tree to publish so that\nothers can fetch and verify.\n\nHere are some of the issues, from end users' point of view, that v3 would\nhave that v2 would not, off the top of my head:\n\n - Unless you are pushing into a repository solely for your own push, you\n   have to first fetch the notes ref from where you are about to push to,\n   then hope that your push does not conflict with others. If your push is\n   rejected for non-fast-forward of the signed-push notes tree (but not\n   for your real branches), you would have to rewind the push certificate\n   the failed \"git push\" prepared (you could probably add a patch to the\n   v3 to do so automatically, but I haven't looked closely for all\n   possible failure cases), run \"git fetch\", and then run \"git push -s\"\n   again which would create a new push record for you to sign. Because the\n   \"signed-push\" namespace for notes is meant to cover all the branches,\n   this will not work on a busy site that uses CVS/SVN style \"shared\n   central repository\" workflow at all.\n\n - If you are pushing into multiple places, you would somehow need to\n   configure your end to keep one signed-push notes tree per remote that\n   you intend to push to with signature, to avoid contaminating remote\n   repositories of records of your push into other remote repositories.\n   It could be worked around by even more code on the sending end, but the\n   need for configuring alone is already an additional mental burden.\n\n - It also was hoped that pre-receive or pre-update hook on the receiving\n   end can be used to authenticate and authorize the push itself with the\n   approach by v3, but when the check happens, the signed-notes tree to be\n   used for verification is not connected to any ref in the refs/notes/\n   hierarchy yet (otherwise it won't be pre-* hook). The query interface\n   \"git notes show\" needs to be updated so that it takes not just a ref\n   via the GIT_NOTES_REF interface, which is defined to specify a ref\n   because some subcommands of \"git notes\" need to create a new commit and\n   update it, but a bare notes tree commit object name [*1*]. We may need\n   to update \"git notes\" (at least \"show\" subcommand) for the use of\n   receiving end; v3 is no longer a simpler \"sender only\" solution.\n\nI've shown how both v2 and v3 models would look to the end users with\nworking code, thought about the pros and cons probably longer than anybody\nelse, and at this point, if I were to choose between the two approaches\n[*2*], I am inclined to suggest that we go with the v2 model [*3*].\n\nEither that, or we will see follow-up patches to work around the above\n(and there may be others we may later discover) issues from people who\nstill think v3 is a better approach.\n\nWhether we go with v2 or v3, for people who want to verify the commits\nagainst signed push certificates stored in notes tree:\n\n - We need a wrapper like \"tag --verify\".\n\n - We also need a way to merge these signed pushed certificates [*4*]. I\n   think the default notes merge is to concatenate, which would result in\n   duplicates of the records that was present in the common ancestor (and\n   no, \"union\" merge is not a safe way to remove these duplicates).\n\nBut see footnote *2* below.\n\n\n[Footnotes]\n\n*1* I wouldn't be surprised if it already worked when you give the object\nname of the notes-tree commit to GIT_NOTES_REF when running \"git show\",\nbut that is not really a documented interface and working by accident. The\nenvironment variable was designed to take a name of the ref.\n\n*2* I say \"if I were to choose between the two\" for a reason. It will make\nthings simpler if we drop \"add signature separately to notes\" altogether,\nand instead adopt a \"signed commit\" approach.  Embed GPG signature in a\ncommit object, and allow the receiving end of the \"push\" to be configured\nto reject a push that tries to place a non-signed commit at the tip of a\nref. The same \"tip of a ref must be a signed commit\" check can be done for\n\"fetch\".\n\nThe most attractive part of the \"signed commit\" approach is that it does\nnot force Linus to fetch push-signature notes trees from his lieutenants,\nand merge them to his push-signature notes tree, which is an unnecessary\nchore. The most likely thing to happen, especially under v3 design, would\nbe that higher level maintainers will not bother to fetch/verify/merge the\nsigned-push notes trees from their feeders, and the final publishing site\nwill only have the push certificates from the owner of the repository at\nthe top-level, without downstream contributors' signature.  The v2 design\nalready relies on the final verifier to independently collect signed-push\nnotes from publishing repositories of Linus and all the key repositories\nLinus pulled from before verification, which feels more cumbersome, but\nthe same needs to be done in v3 if the higher level maintainers do not buy\nin the fetch/verify/merge overhead for the push-signature notes tree.\n\nIf signatures are embeded in the commits themselves, the issue of merging\npush-signature notes tree disappears. Whenever the top level maintainer\npulls from his lieutenants, his fetch can (and should) check the signature\nof these lieutenants, and their signatures stay in the history the top\nlevel maintainer integrates and eventually pushes out with his own\nsignature.\n\nAs to the embedding of the signature in the commit, I am inclined to put\nthe lines of GPG detached signature in new header lines, after the\nstandard tree/parent/author/committer headers, instead of tucking it at\nthe end of the commit log message text, for multiple reasons:\n\n - The signature won't clutter output from \"git log\" and friends if it is\n   in the extra header. If we place it at the end of the log message, we\n   would need to teach \"git log\" and friends to strip the signature block\n   with an option.\n\n - Teaching new versions of \"git log\" and \"gitk\" to optionally verify and\n   show signatures is cleaner if we structurally know where the signature\n   block is (instead of scanning in the commit log message).\n\n - The signature needs to be stripped upon various commit rewriting\n   operations, e.g. rebase, filter-branch, etc. They all already ignore\n   unknown headers, but if we place signature in the log message, all of\n   these tools (and third-party tools) also need to learn how a signature\n   block would look like.\n\n - When we added the optional encoding header, all the tools (both in tree\n   and third-party) that acts on the raw commit object should have been\n   fixed to ignore headers they do not understand, so it is not like that\n   new header would be more likely to break than extra text in the commit.\n\n*3* Honestly speaking, I myself was disturbed by the v2 model where the\nsigned-push is recorded primarily at the receiver. At the philosophical\nlevel, the approach seems to go very much against the \"distributed\" nature\nof Git. Sending what you want to be committed to the server and having the\nserver make a commit feels so very SVN/CVS. The usual \"push\" workflow for\nGit users is to fetch first to come close to the other end, integrate your\nwork to prepare what you push out contains all of what the other end has,\nand then pushing the result out, hoping that you are the latest and nobody\nelse had a chance to update the same thing.\n\nBut after thinking about it a bit more, I came to realize that the record\nof push is quite unlike the branches you and others work on. First of all,\nyou are recording what happens at the receiving end, \"I updated these refs\nto these values in this repository\". Making the record at the receiving\nend is more natural than writing \"I plan to update these refs\", sending it\nover to a dumb receiver and hoping it will fast-forward.\n\nDon't get me wrong. The offline distributed workflow is a great enabler in\na distributed system like Git. The work you do on your branches can be\nfully asynchronous to outside world, and being able to have local history\nthat can later be merged in order to avoid losing work by others while\nstill allowing us to be asynchronous is a great thing to have, but the act\nof pushing the end result and recording the fact you pushed them into a\nrepository is inherently a synchronous event---you and the receiving\nrepository have to be connected when your \"push\" happens. I do not see a\nneed to be dogmatic and insist that everything we do is asynchronous.\n\n*4* For the purpose of pushing things out, even with the v3 design, a\npusher does not have to worry about merging the signed-push notes tree\n(there is no merge issue for pushers with the v2 model), I think.\n\n\"git push -s\" will add a push record to the notes tree, and if the result\ndoes not fast forward, \"git fetch $remote +refs/notes/signed-push\" (or use\nper-remote signed-push hierarchy \"+refs/notes/$remote/signed-push\") that\ndiscards the single failed push record would be all that is needed before\nattempting \"git push -s\" again without losing any information.\n"},{"id":"176480","messageId":"loom.20110929T134216-159@post.gmane.org","threadId":"28516","inReplyTo":"7vfwjgui8s.fsf_-_@alter.siamese.dyndns.org","subject":"Re: What's next for \"signed push\"?","fromName":"Dmitry Ivankov","fromEmail":"divanorama@gmail.com","sentAt":"2011-09-29T11:50:09Z","receivedAt":"2011-09-29T11:50:09Z","isPatch":false,"sender":{"key":"divanorama@gmail.com","avatar":"https://avatars.githubusercontent.com/u/158999?v=4"},"body":"Junio C Hamano <gitster <at> pobox.com> writes:\n\n>  - It also was hoped that pre-receive or pre-update hook on the receiving\n>    end can be used to authenticate and authorize the push itself with the\n>    approach by v3, but when the check happens, the signed-notes tree to be\n>    used for verification is not connected to any ref in the refs/notes/\n>    hierarchy yet (otherwise it won't be pre-* hook). The query interface\n>    \"git notes show\" needs to be updated so that it takes not just a ref\n>    via the GIT_NOTES_REF interface, which is defined to specify a ref\n>    because some subcommands of \"git notes\" need to create a new commit and\n>    update it, but a bare notes tree commit object name [*1*]. We may need\n>    to update \"git notes\" (at least \"show\" subcommand) for the use of\n>    receiving end; v3 is no longer a simpler \"sender only\" solution.\n> \n> *1* I wouldn't be surprised if it already worked when you give the object\n> name of the notes-tree commit to GIT_NOTES_REF when running \"git show\",\n> but that is not really a documented interface and working by accident. The\n> environment variable was designed to take a name of the ref.\nThere's also my old request for comments on refs/notes/ ([RFC] plumbing git-\nnotes, link below). Unexpected thing is that \"refs/notes/commits^\" is silently \naccepted, but notes aren't displayed at all.\n\n\nhttp://thread.gmane.org/gmane.comp.version-control.git/178149\n"}]}