Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Import GPG public key #14782

Open
yonas opened this issue Feb 24, 2021 · 8 comments
Open

Feature: Import GPG public key #14782

yonas opened this issue Feb 24, 2021 · 8 comments

Comments

@yonas
Copy link

yonas commented Feb 24, 2021

Description

After forking a git repo, I'd like to import their GPG key so that Gitea can verify their signed commits.

Gitea currently displays "No known key found for this signature in database"

Screenshot from 2021-02-23 21-45-19

I don't want to add their GPG key to my account, since the key doesn't belong to me.

For testing this example, Kyle Harding's key (FD3EB16D2161895A) can be found using the GitHub API:
https://api.github.com/users/klutchell/gpg_keys

@zeripath
Copy link
Contributor

OK there are a few things we can do here.

  1. Gitea could have a setting on the repo which provides a public keyring of keys that it is happy to verify against. This would then be another trust model. The keyring would need to be downloadable at something like https://gitea/owner/repo/keyring.gpg
  2. The public keyring could be stored on the master branch of the repository - this would be a little more difficult to use and safely manage.
  3. Gitea could query github users for their keys
  4. Gitea could query keys.openpgp.net or the sks keyserver pool to check for keys that match the committer address and mark as verified.

I think 1. is probably best - I would have already looked at it and attempted to implement it but for other things.

There are however a few questions that need to be resolved:

  • How do we store the keyring in the db?
    • I guess we would just have to have another table.
    • Do we need to explode the keys into separate gpg_keys and hence the additional table is [key_id, repo_id] rather than [repo_id, keyring_text]?
  • How do we handle forks?
    • Do Forks just get a copy of the public keyring from the original repo? If so are they allowed to add to it? Remove from it? Do changes get propagated? Should they?
    • We don't really want to end up with large numbers of keys duplicated in the db
    • This suggests a need to explode the keyring rather than dumping the keyring plain into the db
  • If we explode we'll need to allow users to claim their own key and activate it in future. Similarly a user removing their key or deleting themselves from the gitea system needs consideration - does this remove it from other repos keyrings?
  • If we explode we'll need to be able to clean up and remove keys that no longer have a repo attached <- this means that we will need to be careful with the order of table locking in transactions.

We need to think through carefully the effects of this. It's not just as simple as just add the keyring to repo and use that. How to handle forks is a significant issue.

@lunny
Copy link
Member

lunny commented Apr 29, 2021

@yonas I assume fork you mentioned in fact means migrate from external git service.

We can have an check option on the migrations to allow migrate public gpg keys. All the keys we can migrate includes two parts. One is it's a github generated public gpg key for those commits submitted from Github's web editor, another is the keys users uploaded to github.

For the first one, we can download https://github.com/web-flow.gpg to store into some place on gitea server.
For the second keys, we have to know every commit's github user name before download it from github's server. A possible method is search the public key via the commit email address from public gpg servers rather than get them from github .

@dsseng
Copy link
Contributor

dsseng commented Apr 11, 2023

Somewhat related to my idea #24010. Other Git servers could also be treated as keyservers, keys will get imported into Gitea based on contributor list using built-in mechanisms like https://github.com/sh7dm.gpg useful for GitHub and Gitea.

Also Gitea could itself act as a readonly keyserver resolving emails into GPG keys for others to be able to import them this way and use for verifying cloned repos' signatures.

I don't think that it's appropriate to allow users to import GPG keys from untrusted sources. At least we shouldn't mark it as Verified, since user could just use a mock server which claims to know fake key owners. IMO admin should explicitly allow to mirror keys from certain services (like github.com, gitlab.freedesktop.org etc) to ensure Gitea doesn't mark questionable commits as verified.

Example:

  • Admin allows importing repo keys from GitHub
  • User mirrors a GH repo, Gitea adds keys of contributors to global trust. On each mirror pull it checks for new contributors and trusts each one's keys (since admin allowed GH as a trusted key identity source)
  • User clones a repo from git.unknown.com, which is their own crafted server which doesn't check key ownership (like Gitea asking to sign a nonce or keys.openpgp.org sending an email). They have added a bad key which their instance claims to be associated with some unrelated user.
  • That repo holds some commits signed with the key in question (with corresponding email and name added). Boom! After that import, our instance claims those commits are original (people might even pull that key and believe it's original.

So, even if we use some local trust confined to a repo or org, we must clearly sign that that key belongs to username as received from git.example.com (belongs to a user imported from ... etc). I believe we shouldn't do so anyway, but instead let admins add known-good services to an allowlist (in case service or a keyserver really does assert the ownership)

@dsseng
Copy link
Contributor

dsseng commented Apr 11, 2023

#20521 is also relevant to the topic of trusted GPG key sources

@dsseng
Copy link
Contributor

dsseng commented Apr 11, 2023

We can fetch GitHub contributors list (probably should 99% match the signers) and import them initially, re-checking on each sync for new contributors. Also, we can search users by email and then get GPG/SSH keys.

To avoid such issues when mirroring from Gitea, hosting a GPG readonly keyserver should be considered.

@eggdropsoap
Copy link

eggdropsoap commented May 21, 2023

I'm running a small private Gitea instance. As the Admin, I solved this for all repos by creating a user named GitHub, assigning GitHub's public key to the user, and editing the user to be Activated: false, Disable sign in: true, Max repos: 0, and have https://github.com as their website.

This makes the account only a local place on the Gitea server to store the key as @lunny suggested. All repos can access the key to verify GitHub-signed commits. It's lightweight and doesn't require Gitea to become a keyserver or to add logic to import keys into individual repos.

As a code solution proposal, Gitea could automate this through a key-centric admin UI.

I imagine it would operate like this:

  • add a type of user that is a "Remote Public Key Holder" which cannot be logged into (new column in user table)
  • add a "Remote Public Key Registration" panel in the Administration settings, which allows adding and deleting public key files, and under the covers is managing these keys via creating and deleting key-holder accounts
  • a special-case page-rendering view for this type of user that portrays them as an external signer, not a local user at all (this is so that clicking on the signing username in commits histories leads to an explanation, not a 404 or a "mystery user named GitHub" that might cause confusion or alarm)

Allowing administrators to manually add the public signing keys used by major repository services would cover 99% of the problems with Gitea showing signed commits by those services as "unknown". It wouldn't raise any security or trust issues, as there is no local ability to sign commits and there is no masquerading being done. This only does signature verification via public keys and honestly identifies the owners of those keys, which (in the context of git logs) is their only purpose.

Automation of key imports could be added on top of this solution later, but it would be a nice-to-have instead of a necessity. This relatively simple manual admin feature would be relatively simple to implement and serve the majority of use cases.

Thoughts?

@Mikaela
Copy link
Contributor

Mikaela commented May 22, 2023

It wouldn't address the issue of individuals keys and if admin added their key to an account, would they be able to add their key to their own account in case they register on the instance?

@brandonkal
Copy link

brandonkal commented Jun 22, 2024

Note that creating the GitHub user as @eggdropsoap suggested is an improvement but the user is still untrusted as the admin cannot verify the GPG key (I don't have external users' private GPG keys to sign the challenge token in the webUI). In the UI that means the commits show as untrusted and yellow, instead of green.

It should be possible to trust github.com as a keyserver for external users. OneDev supports this functionality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants