Hello, thank you so much for actually reading this (and the script) and writing back. It always give me warm feelings when the bottomless abyss called Guix mailing list responds. :)
45mg <45mg.wri...@gmail.com> writes: > Hi Tomas, > >> In the end more steps were required than I expected. And the signing sadly >> required patching git-authenticate.scm in the fork. I put together a script >> that automates this process, maybe it will be useful to others as well: > > Thanks a lot for sharing this! > > I'm also interested in maintaining my own fork, so I spent some time > going through the script [0]. It's well-written and quite sophisticated; > I spent a lot of time reading the Guile manual :) I was even hoping that > we could have something like it in Guix itself. It could really help > reduce the frustration from slow patch review, as Felix pointed out in > response to mine [1] - people who need unmerged functionality can simply > apply the patches to their own forks and pull from them until their > patches are applied. > > However, your patch to git-authenticate.scm [2] gave me pause. In trying > to understand why it was necessary, I read the 'Securing Updates' Guix > blog post [3], and was reminded of the /authorization invariant/ that > git-authenticate relies on. Quoting the blog post: > >> A commit is considered authentic if and only if it is signed by one of >> the keys listed in the .guix-authorizations file of each of its >> parents. This is the authorization invariant. > > Now the reason I bring this up is this - it looks like the patch you're > relying on breaks the authorization invariant. Yes, it breaks it. > And further, I don't see any way to have an authenticated local fork > without breaking it! For this very reason. It simply is not possible to have authenticated fork for a project secured by guix-authenticate. > > I'm hoping to be wrong about this; I was hoping you could check my > understanding here. > > From the patch message: > >> When Guix fork is created (from commit A), new commit (authorizing the new >> signing key K) is created (I). Later, when update from Guix proper (U) is >> merged, new merge commit is created (M): >> >> M >> / \ >> I U >> \ / >> A >> >> The M is signed with the K. However since the K is allowed by only one >> parent (I), it will not be in the set of authorized keys (intersection of >> keys >> from I and U). > > This is the authorization invariant in action. > >> Solution is to reverse the direction of the check (Guix proper checks from >> newest to oldest) and use all keys from already authenticated parents. I am >> pretty sure the security guarantees are the same, and we will be able to >> successfully authenticate merge commits like M. > > Now, I could be misunderstanding this, but the idea I'm getting from > reading the diff that follows is that any key that was previously used > to sign any commit will be considered as a valid key to sign other > commits - it need not be present in the .guix-authorizations of every > parent. Which violates the invariant. I think you are slightly misunderstanding the invariant. Quoting the relevant part: > if it is signed by one of the keys listed in the .guix-authorizations > file of *each of its parents*" Emphasis is mine. These "parents" are parents in the git sense of the word, which is well defined. Copying the example from above: M / \ I U \ / A M has exactly two parents, I and U. It has 3 *ancestors*, I, U and A. The intention in the code is to use the parents of M (so I, U) and do an union instead of an intersection of keys valid in both parents. > > I was hoping that maybe it's actually OK to do this, as you suggested; > but unfortunately I thought of a problem - it would mean that once > someone has a single signed commit in the Guix repo, their ability to > make authenticated commits can never be revoked. Even if their key is > removed from .guix_authorizations, their key will always make it into > the set of valid keys via `authenticated-commits`. There are probably > more possible attacks. Were you actually able to demonstrate this attack? I did quick test and was not able to reproduce. The thought process behind the change is that since you check the keys from the parents, and those parents are already authenticated, all keys should be equally valid and acceptable to be used for signing the child commit. I still *think* that should be fully safe. I spent quite some time trying to come up with attacks against my version back when I wrote it, and did not figure out anything. However! It is always possible there are bugs (either in the code or in my understanding). It would be great if you are able to demonstrate that this attack is possible. It would allow me to correct my understanding and fix the code. > > And this brings me (finally!) to the point of my message - > I do not see any way to have an authenticated local fork, given the > current design of `guix git authenticate`. > As long as we have the authorization invariant, we won't be able to > merge upstream Guix into our own master branch and preserve > authentication Yeah, I agree. That is the reason why I wrote the script and carry the patch. I just was not able to find any other way to get it working. > (unless, of course, we're authorized committers ourselves). My cynical take is that this is the very reason this issue is not taken seriously. For all "people in charge" it works, even in private forks. > > So, what do you think? Does this make sense? If it does, I'll CC > guix-devel on this; I think we do need a way for people to have their > own forks going forward, and it would be a shame if we have to give up > authentication to do it. I agree, but I already raised the issue in my original thread, and there was no action from the committers, I am not sure this is high enough on the priority list. But your are of course free to try, maybe this time there will be takers. ^_^ > > [0] https://git.wolfsden.cz/guix/tree/etc/fork-guix > [1] https://lists.gnu.org/archive/html/guix-devel/2025-01/msg00072.html > [2] > https://git.wolfsden.cz/guix/tree/etc/0001-git-authenticate-Trust-all-keys-from-already-authent.patch > [3] https://guix.gnu.org/en/blog/2020/securing-updates/ Have a nice 2025, Tomas -- There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors.
signature.asc
Description: PGP signature