Allow SSH key to be used for commit signatures #14429

Closed
opened 2025-11-02 11:12:43 -06:00 by GiteaMirror · 10 comments
Owner

Originally created by @brtwrst on GitHub (Apr 30, 2025).

Feature Description

To make gitea sign commits generated by the app itself (merge commits, crud actions, repo init ...) users are required to correctly install a gpg signing key in the correct location. The relevant part in the documentation basically says: Go find out how to set that up yourself which has been a pain point for many users over the years and for myself as well.

Now that commit signing with SSH keys has been available for some time, would it be possible to use SSH keys for these commit signatures as well? Could be as simple as putting a private key in a specific .folder (maybe %(APP_DATA_PATH)/home/.ssh ) along with a "use ssh key for commit signing" setting under the [repository.signing] section in the app.ini.

Thoughts?

Originally created by @brtwrst on GitHub (Apr 30, 2025). ### Feature Description To make gitea sign commits generated by the app itself (merge commits, crud actions, repo init ...) users are required to **correctly** install a gpg signing key in the correct location. The relevant part in the documentation basically says: [Go find out how to set that up yourself](https://docs.gitea.com/next/administration/signing#installing-and-generating-a-gpg-key-for-gitea) which has been a pain point for many users over the years and for myself as well. Now that commit signing with SSH keys has been available for some time, would it be possible to use SSH keys for these commit signatures as well? Could be as simple as putting a private key in a specific .folder (maybe `%(APP_DATA_PATH)/home/.ssh` ) along with a "use ssh key for commit signing" setting under the `[repository.signing]` section in the app.ini. Thoughts?
GiteaMirror added the type/proposal label 2025-11-02 11:12:43 -06:00
Author
Owner

@brtwrst commented on GitHub (Apr 30, 2025):

Ok so important update,
After reading this in the docs:
The default option will interrogate git config for commit.gpgsign option
I did some testing and found out, that you can already make gitea sign these commits with an SSH key and it's quite simple.
Issue is now that it will show the commit without a green lock in the interface when you view it:
Image
I did confirm that this commit is signed by the SSH key I added though.

Here is what I did.

  • Exec into the container
  • run mkdir /data/gitea/home/.ssh
  • Run ssh-keygen and create a keypair in /data/gitea/home/.ssh
  • Run chown -R 1000:1000 /data/gitea/home/.ssh
  • Edit /data/gitea/home/.gitconfig and add the following (add to section if it already exists):
[user]
    signingKey = /data/gitea/home/.ssh/id_ed25519.pub
[commit]
    gpgsign = true
[gpg]
    format = ssh
  • Finally add the following to the app.ini
[repository.signing]
SIGNING_KEY=default
SIGNING_NAME=Gitea
SIGNING_EMAIL=git@domain.com
WIKI=always
CRUD_ACTIONS=always
MERGES=always

(not sure if SIGNING_NAME and SIGNING_EMAIL do anything in this case)

This will make gitea sign Merge/CRUD/init commit but sadly gitea will not accept it as a valid signign key and show the commits without a green lock symbol.
Is there a way already to tell gitea that this key should be "trusted" ?

@brtwrst commented on GitHub (Apr 30, 2025): Ok so important update, After reading this in the docs: `The default option will interrogate git config for commit.gpgsign option` I did some testing and found out, that **you can already make gitea sign these commits with an SSH key and it's quite simple**. Issue is now that it will show the commit without a green lock in the interface when you view it: ![Image](https://github.com/user-attachments/assets/92e3d6a3-08a1-4d60-b4bd-7525f5f36812) I did confirm that this commit is signed by the SSH key I added though. Here is what I did. * Exec into the container * run `mkdir /data/gitea/home/.ssh` * Run `ssh-keygen` and create a keypair in `/data/gitea/home/.ssh` * Run `chown -R 1000:1000 /data/gitea/home/.ssh` * Edit `/data/gitea/home/.gitconfig` and add the following (add to section if it already exists): ``` [user] signingKey = /data/gitea/home/.ssh/id_ed25519.pub [commit] gpgsign = true [gpg] format = ssh ``` * Finally add the following to the app.ini ``` [repository.signing] SIGNING_KEY=default SIGNING_NAME=Gitea SIGNING_EMAIL=git@domain.com WIKI=always CRUD_ACTIONS=always MERGES=always ``` (not sure if SIGNING_NAME and SIGNING_EMAIL do anything in this case) This will make gitea sign Merge/CRUD/init commit but sadly gitea will not accept it as a valid signign key and show the commits without a green lock symbol. Is there a way already to tell gitea that this key should be "trusted" ?
Author
Owner

@ChristopherHX commented on GitHub (Apr 30, 2025):

Is there a way already to tell gitea that this key should be "trusted" ?

Add the ssh public key to an existing user?

@ChristopherHX commented on GitHub (Apr 30, 2025): > Is there a way already to tell gitea that this key should be "trusted" ? Add the ssh public key to an existing user?
Author
Owner

@brtwrst commented on GitHub (Apr 30, 2025):

Yeah that might work but doesn't seem like the "correct way".
Should be some central list that contains the trusted keys.
The canonical place would be a allowed_signers file somewhere.

I tried creating an allowed signers file in the home folder with the key inside and added

[gpg "ssh"]
        allowedSignersFile "/data/gitea/home/allowed_signers"

to the .gitconfig file - but this changes nothing. Gitea seems not to be able to use this yet.

@brtwrst commented on GitHub (Apr 30, 2025): Yeah that might work but doesn't seem like the "correct way". Should be some central list that contains the trusted keys. The canonical place would be a [allowed_signers](https://www.man7.org/linux/man-pages/man1/ssh-keygen.1.html#ALLOWED_SIGNERS) file somewhere. I tried creating an allowed signers file in the home folder with the key inside and added ``` [gpg "ssh"] allowedSignersFile "/data/gitea/home/allowed_signers" ``` to the .gitconfig file - but this changes nothing. Gitea seems not to be able to use this yet.
Author
Owner

@ChristopherHX commented on GitHub (Apr 30, 2025):

Seems like this is more complicated.., I also try to figure out how this works.

The first time I used the wrong .gitconfig, my docker image had two of them...

@ChristopherHX commented on GitHub (Apr 30, 2025): Seems like this is more complicated.., I also try to figure out how this works. The first time I used the wrong .gitconfig, my docker image had two of them...
Author
Owner

@ChristopherHX commented on GitHub (Apr 30, 2025):

Yeah that might work but doesn't seem like the "correct way".
Should be some central list that contains the trusted keys.
The canonical place would be a allowed_signers file somewhere.

I checked the source code and debugger, this does only work correctly for a single user instance of Gitea. Very fragile.

ssh signed commit can only be verified if

  1. committer email is known to an instance user
  2. that exact user has the ssh public key explicitly added (allowedSignersFile is not used git cat-file commit sha is used to extract the signature and verify without git)
  3. the public key of the user has been "verified" using the button in settings ( I missed this )

With the setup you described 2. can not be satisfied for more than one user...., so indeed we need changes to gitea. However not sure how to proceed.

  • make gitea not use the current user as committer and use user Gitea or instance admin or user defined (so they show up similar to GitHub signed commits on gitea.com, that committer is GitHub not the user) works see next comment
  • allow to configure a ssh private key per user in settings and database (can not be backported to 1.24), could be an complex enhancement
@ChristopherHX commented on GitHub (Apr 30, 2025): > Yeah that might work but doesn't seem like the "correct way". > Should be some central list that contains the trusted keys. > The canonical place would be a [allowed_signers](https://www.man7.org/linux/man-pages/man1/ssh-keygen.1.html#ALLOWED_SIGNERS) file somewhere. I checked the source code and debugger, this does only work correctly for a single user instance of Gitea. Very fragile. ssh signed commit can only be verified if 1. committer email is known to an instance user 2. that exact user has the ssh public key explicitly added (allowedSignersFile is not used `git cat-file commit sha` is used to extract the signature and verify without git) 3. the public key of the user has been "verified" using the button in settings ( I missed this ) With the setup you described 2. can not be satisfied for more than one user...., ~~so indeed we need changes to gitea. However not sure how to proceed.~~ - make gitea not use the current user as committer and use user Gitea or instance admin or user defined (so they show up similar to GitHub signed commits on gitea.com, that committer is GitHub not the user) **works see next comment** - allow to configure a ssh private key per user in settings and database (can not be backported to 1.24), **could be an complex enhancement** - maybe allow to auto generate one where the user do not need the private key - **EDIT** _SSH Trust could be extended here <https://github.com/go-gitea/gitea/blob/e67f74efc86116936aa8097ddfa7c835de4d6d48/services/asymkey/commit.go#L363>_ - using a global signing key here is not practicable to add to other forges, for Gitea this would be a security problem as we can not only allow commit validation without granting push
Author
Owner

@ChristopherHX commented on GitHub (Apr 30, 2025):

  • make gitea not use the current user as committer and use user Gitea or instance admin or user defined (so they show up similar to GitHub signed commits on gitea.com, that committer is GitHub not the user)

I found how to resolve this part in Gitea 1.23

DEFAULT_TRUST_MODEL = committer

So I now have

[repository.signing]
SIGNING_KEY = default
INITIAL_COMMIT = always
CRUD_ACTIONS = always
WIKI = always
MERGES = always
DEFAULT_TRUST_MODEL = committer

Maybe collaboratorcommitter is better here, need to look around.

I don't think it is a problem to create a user called Gitea that has the signing key verified.

@ChristopherHX commented on GitHub (Apr 30, 2025): > * make gitea not use the current user as committer and use user Gitea or instance admin or user defined (so they show up similar to GitHub signed commits on gitea.com, that committer is GitHub not the user) I found how to resolve this part in Gitea 1.23 ``` DEFAULT_TRUST_MODEL = committer ``` So I now have ``` [repository.signing] SIGNING_KEY = default INITIAL_COMMIT = always CRUD_ACTIONS = always WIKI = always MERGES = always DEFAULT_TRUST_MODEL = committer ``` Maybe collaboratorcommitter is better here, need to look around. I don't think it is a problem to create a user called Gitea that has the signing key verified.
Author
Owner

@ChristopherHX commented on GitHub (Apr 30, 2025):

Image

looks good on my end now, thanks for pointing me to the correct git home.

@ChristopherHX commented on GitHub (Apr 30, 2025): ![Image](https://github.com/user-attachments/assets/2f5be516-3e8e-4c12-bb14-b20fd8fc48db) looks good on my end now, thanks for pointing me to the correct git home.
Author
Owner

@brtwrst commented on GitHub (May 1, 2025):

Nice find,
It still bugs me that I'd have to create a "dummy" user for this and also that the name of this user is not changeable.
Feels like a bad hack what we're doing here so for now I'll wait on some official Word from the maintainers on how they think this should work.

@brtwrst commented on GitHub (May 1, 2025): Nice find, It still bugs me that I'd have to create a "dummy" user for this and also that the name of this user is not changeable. Feels like a bad hack what we're doing here so for now I'll wait on some official Word from the maintainers on how they think this should work.
Author
Owner

@ChristopherHX commented on GitHub (May 1, 2025):

the name of this user is not changeable.

It is changeable or do I miss something?, both username and email.

in /data/gitea/home/.gitconfig (of docker image)
Should be the following values for SIGNING_KEY = default without SIGNING_EMAIL and SIGNING_NAME (for default they are read from git config)

[user]
    email = 
    name =

Yes you are correct, I didn't change both values.

I used a debugger and looking at the source code, IMHO this needs documentation

@ChristopherHX commented on GitHub (May 1, 2025): > the name of this user is not changeable. It is changeable or do I miss something?, both username and email. in /data/gitea/home/.gitconfig (of docker image) Should be the following values for SIGNING_KEY = default without SIGNING_EMAIL and SIGNING_NAME (for default they are read from git config) ``` [user] email = name = ``` Yes you are correct, I didn't change both values. _I used a debugger and looking at the source code, IMHO this needs documentation_
Author
Owner

@brtwrst commented on GitHub (May 1, 2025):

Thanks for your time.
So this is barely usable and definitely needs documentation and/or some work done to make it easier and more robust.
I still think a solution which doesn't require the creation of another account would be a lot better.

@brtwrst commented on GitHub (May 1, 2025): Thanks for your time. So this is barely usable and definitely needs documentation and/or some work done to make it easier and more robust. I still think a solution which doesn't require the creation of another account would be a lot better.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/gitea#14429