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

Committer verification #2770

Closed
IlyaBelitser opened this issue Oct 23, 2017 · 17 comments · Fixed by #9793
Closed

Committer verification #2770

IlyaBelitser opened this issue Oct 23, 2017 · 17 comments · Fixed by #9793
Labels
issue/confirmed Issue has been reviewed and confirmed to be present or accepted to be implemented type/feature Completely new functionality. Can only be merged if feature freeze is not active.
Milestone

Comments

@IlyaBelitser
Copy link

Git and distributed version control have many benefits out of the box, but controlling access and workflows isn’t one of them. For example, without a Git management tool, a developer can push commits that others have written to the central repository.

This creates problems for organizations with strict security and compliance requirements.
It is necessary to add a new committer verification hook, which enforces that only the author of a commit can push those changes back to Gogs Server. We can sleep easy knowing that only authorized code changes can make it to your repositories.

BitBucket has added this feature.

https://www.atlassian.com/blog/bitbucket/enterprise-devops-bitbucket-server-5-bamboo-6

committer-verification

And GitLab adds too.

https://gitlab.com/gitlab-org/gitlab-ee/issues/1802

@lafriks lafriks added the type/feature Completely new functionality. Can only be merged if feature freeze is not active. label Oct 23, 2017
@lafriks lafriks added this to the 1.x.x milestone Oct 23, 2017
@sapk
Copy link
Member

sapk commented Oct 24, 2017

From git point, I would recommend you to use gpg commit verification (allready implemented) that allow a "pusher" to push commit from another "commiter" and still be able to verify that the commit hasn't be tempered or that the identity of the commiter ins't falsify. This type of verification is totally decentralized and verification can also be done locally and is supported natively by git.

This solution, doesn't cover the part of only allowing to push commit from the logged user that maybe needed for your corporation (this would block cherry-pick and some git flow if enable).

If the gpg method doesn't fully comply with your need, gitea support server-side hook but those need to be added manually via git cli. More generaly, we could provide a way to apply predifined list of server-side hooks.

EDIT: it is also possible to edit the pre-receive hook via web interface.

@lunny
Copy link
Member

lunny commented Oct 27, 2017

So maybe we could have an option on repository setting to deny all push gpg verify failed.

@stale
Copy link

stale bot commented Feb 11, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs during the next 2 weeks. Thank you for your contributions.

@stale stale bot added the issue/stale label Feb 11, 2019
@lunny lunny added issue/confirmed Issue has been reviewed and confirmed to be present or accepted to be implemented and removed issue/stale labels Feb 11, 2019
@Sebazzz
Copy link

Sebazzz commented Nov 10, 2019

Does gitea pass any user info through environmental variables? That would allow these hooks to work.

@zeripath
Copy link
Contributor

Yes it does.

gitea/cmd/serv.go

Lines 187 to 195 in ee1d64d

os.Setenv(models.EnvRepoIsWiki, strconv.FormatBool(results.IsWiki))
os.Setenv(models.EnvRepoName, results.RepoName)
os.Setenv(models.EnvRepoUsername, results.OwnerName)
os.Setenv(models.EnvPusherName, results.UserName)
os.Setenv(models.EnvPusherID, strconv.FormatInt(results.UserID, 10))
os.Setenv(models.ProtectedBranchRepoID, strconv.FormatInt(results.RepoID, 10))
os.Setenv(models.ProtectedBranchPRID, fmt.Sprintf("%d", 0))
os.Setenv(models.EnvIsDeployKey, fmt.Sprintf("%t", results.IsDeployKey))
os.Setenv(models.EnvKeyID, fmt.Sprintf("%d", results.KeyID))

However read my comments on #8584

It can be done we just need to do a bit more work.

@Sebazzz
Copy link

Sebazzz commented Nov 12, 2019

For simple committer verification this works work well in Gitea v1.9.5:

#!/bin/sh
err(){
    >&2 echo "Pre-receive validation: $*"
}

hasErr = 0
while read oldrev newrev ref
do
	if [[ "$oldrev" == "0000000000000000000000000000000000000000" ]]; then
		#create new branch
		continue;
	fi
	
	export committers="$(git log --format="%H %ce" $oldrev..$newrev)"
	
	while IFS=' ' read -r commitHash committerEmail;
	do
		if [[ "$committerEmail" != "$GITEA_PUSHER_EMAIL" ]]; then
			err "You are not $GITEA_PUSHER_EMAIL! You pushed commit $commitHash as $committerEmail"
			exit -1
		fi
	done <<< $committers
done

exit 0

This verifies every pushed commit against the Gitea users e-mail address. Indeed, gpg signing might be more perfect, but this does work.

Delta compression using up to 16 threads
Compressing objects: 100% (9/9), done.
Writing objects: 100% (9/9), 1.02 KiB | 1.02 MiB/s, done.
Total 9 (delta 3), reused 0 (delta 0)
remote: ./hooks/pre-receive.d/enforce-author: line 8: hasErr: command not found
remote: Pre-receive validation: You are not [email protected]! You pushed commit edb3fc3b808fdaea26fd43a128a40e3457021ac6 as [email protected]
To https://git.[redacted]/[user]/test2
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.[redacted]/[user]/test2'

@guillep2k
Copy link
Member

@Sebazzz there seems to be a typo in your example:

remote: ./hooks/pre-receive.d/enforce-author: line 8: hasErr: command not found

I think you need to change:

hasErr = 0

to

hasErr=0

@Sebazzz
Copy link

Sebazzz commented Nov 12, 2019 via email

@Sebazzz
Copy link

Sebazzz commented Nov 12, 2019 via email

@zeripath
Copy link
Contributor

So Gitea won't be able to pass the committer name as a variable as that's in the commits themselves - you'd need to examine the commit and then interrogate Gitea over the API to do it.

I am aware of how to go about adding this to Gitea's protected branch stuff but I've not had time. If you're willing and understand what I've written in #8584 this could be a good PR.

@Sebazzz
Copy link

Sebazzz commented Nov 13, 2019 via email

@zeripath
Copy link
Contributor

Ah, I'd forgotten what this issue was asking for.

Yeah we don't put the full name or email address in the environment because we don't use it - however you can easily get that from the Gitea API with a sufficiently powerful token (if you need to override hide email address) at /api/v1/users/{user}

Yeah it's a little slow to have to send an API request but it's not overly long.

@6543
Copy link
Member

6543 commented Jan 16, 2020

If I understand correct #9708 close this?
and I created a PR for docs update: #9793

@lunny lunny modified the milestones: 1.x.x, 1.12.0 Jan 16, 2020
@Jackenmen
Copy link

Not entirely sure, but I think "Verified Committer" on comparison page in docs should have a tick for Gitea? https://docs.gitea.io/en-us/comparison/#code-management

@6543
Copy link
Member

6543 commented Feb 26, 2020

I think this will be a "tick" when #10425 is merged @zeripath ?

@zeripath
Copy link
Contributor

I'm gonna make it "/" because if we're gonna say we do this I think we will need to do it properly.

@go-gitea go-gitea locked and limited conversation to collaborators Nov 24, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
issue/confirmed Issue has been reviewed and confirmed to be present or accepted to be implemented type/feature Completely new functionality. Can only be merged if feature freeze is not active.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants