Repository navigation
Conversation
77b6399 to
5157125
Compare
|
Do you want to review this by itself, or in the context of the entire keys add/rm/validation functionality? We do not plan other changes to this signing of the commits part. |
|
Hey, sorry I've been quite disrupted lately. Yes, this would be better with the entire thing. With only this it doesn't enable a lot while creating more failure opportunities so I'm wary of merging it without the rest. I'll do a quick review though. |
61f814d to
ec2e986
Compare
MichaelMure
left a comment
There was a problem hiding this comment.
Hey, thanks for all that. Sorry for the lengthy review :)
| } | ||
|
|
||
| if keyAddArmoredFile == "" && keyAddArmored == "" { | ||
| keyAddArmored, err = input.IdentityVersionKeyEditorInput(backend, "") |
There was a problem hiding this comment.
what about generating a new key instead ? Ideally using git-bug, even with signature, should not require for the user to learn PGP or even knowing what that is. Power user should still be allowed to input their own keys but that's their choice to go the hard way.
There was a problem hiding this comment.
Generating a new key means the private key has to be stored in a file, and to be used with gpg it has to be imported. Can be done, but we can live without it.
There was a problem hiding this comment.
Storing the private key in the git config, even is it's not perfect seems like an OK solution to me. It would be nice to be entirely independent of a gpg binary, but I don't know if that's possible without migrating to go-git.
There was a problem hiding this comment.
Can be done, but can also be added later?
There was a problem hiding this comment.
Well, I'm not going to refuse this useful contribution because it doesn't meet 100% of what I think should happen but I'm considering that a requirement for an actual release.
I'm also saying that because it looks like that you are going on a more complicated path but I may be wrong.
There was a problem hiding this comment.
We do need gpg and the private key to be in the gpg keyring to be able to create signed (non-git-bug) commits with git.
There was a problem hiding this comment.
I see. I'll be happy when I can ditch the git CLI exec repo, it cause so many problems :(
There was a problem hiding this comment.
I mean the private key will be used also when signing the normal commits in the repository, so gpg will be used since creating those commits will be done with git, not with anything git-bug or go-git.
| defer backend.Close() | ||
| interrupt.RegisterCleaner(backend.Close) | ||
|
|
||
| id, args, err := _select.ResolveUser(backend, args) |
There was a problem hiding this comment.
you should only be able to add a key on a user you are allowed to control. There is two scenario where this is the case:
- the identity has no key yet ("unprotected")
- you have the private key of one of the public key present in the last version
This rules should be implemented in the Validate() function of Identity so they are checked 1) before a commit and 2) when merging remote data.
There was a problem hiding this comment.
If the user loses the private key, the identity can't be used anylonger.
(In our case, we trust everybody to add/remove keys to anybody. The server ("when merging remote data"?) would run a custom check to make sure the keyring is valid and that everything originates from one key.)
There was a problem hiding this comment.
Is there a notion of "admin identity"?
There was a problem hiding this comment.
If the user loses the private key, the identity can't be used any longer.
Yes, that's the kind of hard rules you end up having with distributed applications. Some sort of backup or trust system could be imagined but for now that looks like the good way to go to me.
The server ("when merging remote data"?) would run a custom check to make sure the keyring is valid and that everything originates from one key.)
Why do you need code server side ? I understand you have different requirements, but is there a way for you to implement those extra requirements while staying close to git-bug's design as a distributed app ? It would help both of us if we can manage that.
Is there a notion of "admin identity"?
Not yet but that would be nice. To reach that point the plan is:
- have a shared project config data structure (valid labels , .... )
- store in that new structure who is admin, with the mechanism to update it
- implement this admin role as rules to check when accepting new data (bugs + project config at least)
There was a problem hiding this comment.
If the user loses the private key, the identity can't be used any longer.
Yes, that's the kind of hard rules you end up having with distributed applications. Some sort of backup or trust system could be imagined but for now that looks like the good way to go to me.
What would be the problem with trusting everybody to make changes to identities?
The server ("when merging remote data"?) would run a custom check to make sure the keyring is valid and that everything originates from one key.)
Why do you need code server side ? I understand you have different requirements, but is there a way for you to implement those extra requirements while staying close to git-bug's design as a distributed app ? It would help both of us if we can manage that.
The problem is the users can push anything working around the local validation done when they use git-ticket. The pre-receive server-side git hook prevents merging bad changes.
There was a problem hiding this comment.
What would be the problem with trusting everybody to make changes to identities?
In the general case people that have a write access to a git repo are trustworthy but that's not always the case. Git support signature to be able to prove that someone made something and improve the trust you can have in the system, but if someone is able to change the valid keys of anyone else, this signature system is worth nothing.
In a similar fashion, this identity system will be the base of the role management. Some users will be admin of a project (or more complex roles) and some not. If you can tamper the keys of anyone, this system is equally useless.
If everyone is trustworthy it's all good and you don't even have to bother with keys and you can leave your identity unprotected. When it's not the case, you should be protected from abuse.
The problem is the users can push anything working around the local validation done when they use git-ticket. The pre-receive server-side git hook prevents merging bad changes.
Why is that the case ? If your user use git ticket pull (which is much simpler than manually merging remote hidden branches), data will be checked. Everything that doesn't follow the rules will be discarded.
My point is, even if a malicious user manage to push bad changes, those changes will not propagate. A non-malicious user should not be able to create bad data as it is checked before writing to git.
Now I agree that its not perfect and a server side hook to control the data is useful. Would you share the one you have ?
There was a problem hiding this comment.
Huhu sorry, reading myself again, I realize I rewrote what you were saying.
There was a problem hiding this comment.
The signatures are useful to prove the changes have not been made by an authorized user pretending to be some other authorized user.
The valid keys can be changed by any authorized user, but it will be obvious who changed them, since the server shall not accept forced pushes.
The malicious authorized users can work around the local validation, but they shall not be allowed to push, because we can. :) Yes, I'll share the validator!
There was a problem hiding this comment.
The valid keys can be changed by any authorized user, but it will be obvious who changed them, since the server shall not accept forced pushes.
Yes, you can do forensics to find out who dropped the ball, but it would be better to actually prevent it, no ?
There was a problem hiding this comment.
Thinking out loud, there should probably be a Keystore interface somewhere with multiple implementations:
- git config
- gpg
- some centralized system that allow recovery for "corporate" environment
Maybe even an implementation that allow to have multiple sub-keystore for example git config + gpg.
|
cc'ing from #383 "DOC,UBY: What do I specify for avatarURL? Gravatar? W3C DID?" https://www.w3.org/TR/did-core/ ::
https://github.com/topics/decentralized-identifiers?l=go https://github.com/decentralized-identity/github-did#what-can-i-do-with-my-did
|
|
... GPG keyservers could also solve for PKI in a centralized way. GitHub and GitLab already expose SSH and GPG public keys if they're added to a username:
GitLab
Keybase |
|
@MichaelMure I'm not sure what verification logic would be common to git-bug and git-ticket (hah, good thing the name is different). I pushed the verification logic we'll use so you can have a look. It's not yet merged in git-ticket. If there is something common and reusable, I could separate the logic from this 3rd commit. I introduced go-git to be able to read the commits to be verified. The go-git repo is added as The very first commit in the identities history is very important. It is of course a commit which creates a new identity. The validation logic requires the newly created identity to have a key and be signed with that key. As long as the commits are signed, it's not strictly necessary for the key to be introduced in the very first commit, but I changed When checking a git reference in the main repo, the key introduced by the first commit guarantees that everything is coming from us. I made a small change to The validate logic then sorts the identity versions by lamport time and iterates them. A keyring is built gradually and used to verify each commit before applying the key changes to the keyring. The keyring is built as an When building the keyring, the time of the commit adding the key ends up in I had to expose private fields such as TODO: I should move at least We could have used key fingerprints instead of key ids to identify the keys, but it seemed simpler to use the key id. The key fingerprint is composed of the key id and some other bits. TL;DR: The first two commits would make sense to merge into git-bug, maybe also some common part of validate functionality if any. Please have a look. Any requests? |
|
@MichaelMure In light of our validation logic which will never make it into git-bug, could you please comment on the first two commits if they are roughly ok and could be merged in git-bug? Thanks. |
|
Hey @aleb this is a pretty big change to review, it might take time for me to go through it. As a preamble, I find that some of this code doesn't follow the architecture design ans "leak" through the layers. Two things comes to mind:
Speaking of this Validator thing, I'm a bit confused tbh, what is it for ? When is it supposed to run ? What should happen if the validation fail ? Why not stay with the
Unless I'm mistaken, both share a very similar need here, or at least we can find a common ground from where you can build your extra validations without breaking everything at each rebase. It seems to me that you want a different set of data/operations (Bug vs ticket) but the "framework" part could be largely shared.
git-bug will keep allowing identities without keys, but a flag somewhere to have a mode where they need to have at least one is entirely possible. Useful for both.
Hmmm, when I originally thought about this the idea was, to add a key to an identity, add the private key in the version as well as a signature for the previous data. Here you are adding the signature in the commit itself, which is a bit different and tie git-bug more to git itself. Not sure what is the best way really. I need to think more about this.
Adding ordering to identities is fine, but that needs to be a distinct Lamport clock to not mess with the bugs. It looks like it's time to update the // ClockedRepo is a Repo that also has Lamport clocks
type ClockedRepo interface {
Repo
GetClock(name string) Clock
}
type Clock interface {
Time() lamport.Time
Increment() (lamport.Time, error)
Witness(time lamport.Time) error
}And yes, it seems that LoadClocks and WriteClocks are never used outside of GitRepo itself so they should not be part of the interface. Cleanup time ! |
So I think this boils down to the question of whether or not rebase are needed. If the commit is signed by the author, rebasing and rearranging the commits is not possible anymore without invalidating the signature. If the data is signed, we are still free to do that. In other words, if the commit is signed, the whole history is signed. If the data is signed, only this specific piece of data is signed, which only prove authorship (which is really nice already). The problem is that at the moment, git-bug does make rebase when changes are pulled. Most of the time people use a unique central git repo so it could work because the commit that are rebased are your own, so you could sign them again. But as soon as you use more than one remote or push/pull directly this model fall apart. What I was thinking about in #212 was to replace the rebase with merges to do the conflict resolution. This would make the data model entirely immutable and would combine very well with signing the commits. So, short of doing this #212 (which would be awesome but a lot of work), the choice end up being either:
I think option 2 make the most sense here. What do you think ? |
|
Sorry for the late reply.
I cherry-picked your commit and fix the issues.
Sounds good. Done.
An identity can't fully validate itself if we want to allow others to make changes to an identity. A separate validator is needed to keep track of what keys have been added and removed and when. (It would have been simpler if only the keys added by the identity can sign the identity's changes, like you wanted(?), but we wanted something more flexible.) The
The more that can be shared, the better.
What would be a good place to store this flag in the repo?
I don't completely follow. Why add the private key in the version? I'm thinking the commits need to be signed anyway, so then we use those signatures. The whole point for us is to have every commit signed (with the "valid keys").
Ok, let me see.. |
It would be good to use git's signatures system if possible, to keep things simple.
We'll use a single remote, so it would work for us. Good to know about the local rebasing when changes are pulled.
We are not interested in the fully decentralized workflow. I'm not sure about the data signing benefits, but it sounds complicated. Option 2 sounds great since we'll be able to use it already and when the data model is reworked we'll be compatible. |
I still don't really get what you want to achieve, I going to guess you want to have some sort of centralized authority for identities. If so, why not have this centralized create the identities with 2 keys, one private to this authority, one given to the user. If you want to prevent the user to make changes to the identity, we could have two list of keys in an identity:
Or maybe we should go all in already and encode that with capabilities on each keys. That would be more extensible for the future. That's a little change that could enable nice new usecases. On a side note, maybe those keys should have an optional name ? That might help for complex schemes.
100%. It seems that we are aiming for a sort of framework to build decentralized app on top of git, where git-bug itself would just be an example. That's awesome.
For now, a hard-coded flag in the code would be good so we don't conflict each other. Later this could also be included in the project settings for optional enabling in git-bug.
Not the private keys. I was thinking about adding the signature of the previous version with one of the valid keys but that's a flawed model. Your idea is better. So to recap, the current idea is:
Sounds good to you? |
Option 2 it is! |
|
FYI, I'm working on the architecture/framework changes that will make this and adding new entities (PR, config ...) easier. It also happen to make the creation of forked tool like git-ticket easier. Have a look at #411 Following closely will be a WIP PR for a go-git repository implementation, which would make signing way easier. |
|
go-git repo PR: #412 |
|
@aleb FYI, something similar to your last changes already now exist in master: https://github.com/MichaelMure/git-bug/blob/master/repository/repo.go#L108 |
87d8bf5 to
2104d6b
Compare
|
Yes, I noticed too late because I started a while ago.. I rebased and I think I don't have other changes planned at the moment. Anything we should be aware of if merging this in git-ticket, so we remain compatible with upstream? |
|
.. other than the failing test. :D EDIT: done |
Yes. I've been increasingly convinced that the good way to go to ultimately implement all those features (identities, signatures, ACL ...) is to:
In addition, more refactoring is need in the Identity, to store one time reference per entity (see https://github.com/MichaelMure/git-bug/blob/master/identity/version.go#L24-L27). This is so that it can be possible to say what version of an identity is valid for what element of an entity (Bug's operation, Ticket's operation, Config, PullRequest ...). With all that we should have something that allow git-bug to grow with more entities, let git-ticket implement its own entities with minimal conflict and have an easier time implementing signatures for everyone. Btw, thanks for spearheading this effort, it helped a lot to define what was necessary and what needed to change. |
|
What do you think of this plan btw? |
Great!
IIUC the system credential storage would be used to get the private keys for signing commits created by git-bug. When creating normal commits in the repo, the
Sounds good.
In this case sorting all the Identity Versions with I think we could work with this. |
Yes.
Not sure why you need that. Versions within an identity already have an implied logical order defined by the order of the commits in git. It would be possible to order identities by creation or edition by adding two extra Lamport clocks there but I don't see much the use of that. |
We could add more ways of specifying a key, such as picking one from the adopted identity, but for now with this change we allow users who know what they are doing to sign their bug changes. By simply passing "-S" to `git commit-tree` when "commit.gpgsign" is "true", we use git's mechanism for key choosing which is either by the configured user name and email OR by whatever is specified in "user.signingkey".
This assures the versions have a strict order.
We need to be able to sort the Versions across all Identities. This way it's possible to check each version has been created by somebody with a valid key at the time. I think we'll try with a lamport clock used only for |
|
Anything from here you can use upstream at this point? |
|
Sorry it took me a while to digest all that and figure out what would be the right thing to do.
Make sense to me. That would be similar to the edit Lamport time for bugs. Might as well throw another for the creation to mirror Bug.
Yes, but not as it is currently I'm afraid (sorry about that). There is a lot of good things though. As you can see in #412, the go-git repo is pretty much ready to be merged (one missing thing is a migration for the bridge credentials in https://github.com/MichaelMure/git-bug-migration/, so nothing that concern you). Notably this repo will allow for a much more native and direct access to everything signature related. Hopefully this also allow to do less in git-bug and delegate to go-git and openpgp. Additionally, something I'd like changed in this PR is how things are located. As of now the signature validation code is built around the core instead of integrating with it. That is, have signature validation available within
Does that make sense to you? (also ideally this would be done in smaller digestible PRs that can be merged along the way to this goal) |
|
|
||
| // the cache of commits | ||
| muCommit sync.RWMutex | ||
| commits map[repository.Hash]*object.Commit |
There was a problem hiding this comment.
Is that really useful? Maybe I'm missing something but it looks to me that once a commit is read for validation, it's not useful anymore as it won't be shared with any other identities.
| } | ||
| } | ||
|
|
||
| func NewIdentityFull(name string, email string, login string, avatarUrl string) *Identity { |
There was a problem hiding this comment.
I think a key change for the identities would be to have a KeyringAtTime(time lamport.Time) openpgp.EntityList in identity.Interface. This could be used later with gogit's Commit.Verify function to let them figure out the correct key from the possible candidate valid at that time.
There was a problem hiding this comment.
I did introduce a lamport clock for identity versions, but for the regular commits we don't have any lamport time. This could be used only when checking the Identity/Version commits.
|
@aleb FYI, #532 bring a major update to the data model that should interest you:
This should make your adventure with git-ticket much easier if you migrate as well. As such, I'll close this PR. Even if your code here has not been merged, it has been a very useful contribution and what is in master now is better because of it. Thank you. |
We could add more ways of specifying a key, such as picking one from the
adopted identity, but for now with this change we allow users who know what
they are doing to sign their bug changes.
By simply passing "-S" to
git commit-treewhen "commit.gpgsign" is "true", weuse git's mechanism for key choosing which is either by the configured user
name and email OR by whatever is specified in "user.signingkey".