Summary
Add a pre-receive hook that resolves each commit's author/committer email against user_emails and rejects the push if the email is not linked to any proxy user. Spun out of #15 Phase 4.
Motivation
CheckUserPushPermissionHook already gates whether a user is allowed to push at all. This hook adds a second check: whether the committer identity in the commits matches the authenticated user's registered emails. Without this, an authenticated user can push commits attributed to someone else.
What to build
IdentityVerificationHook (in jgit-proxy-core)
- Implements
GitProxyHook, order ~150 (authz range, after RepositoryWhitelistHook, before content filters)
- For each
RevCommit in the push:
- Resolve
committer.emailAddress via UserEmailStore.resolveByEmail()
- If unresolved → accumulate error, reject push with
rp.sendMessage() + block
- If resolved → verify the resolved
ProxyUser.username matches the authenticated HTTP Basic principal from PushIdentityResolver
- Mismatch → reject with a clear message:
"committer email foo@example.com is registered to user X, but you authenticated as user Y"
- Honour a config flag
commit.identity-verification: strict | warn | off (default warn to avoid breaking existing deployments)
Config
commit:
identity-verification: strict # strict | warn | off
Wiring
IdentityVerificationHook registered in StoreAndForwardReceivePackFactory alongside existing hooks
- Equivalent
IdentityVerificationFilter for the transparent proxy path (same logic, accumulates into ValidationSummaryFilter)
Depends on
Acceptance criteria
- Push with a committer email not in
user_emails → rejected in strict mode, warning sideband message in warn mode
- Push where committer email belongs to a different user → rejected in
strict mode
- Push where committer email matches the authenticated user → passes
off mode → hook is a no-op
- Unit tests for all three modes
Summary
Add a pre-receive hook that resolves each commit's author/committer email against
user_emailsand rejects the push if the email is not linked to any proxy user. Spun out of #15 Phase 4.Motivation
CheckUserPushPermissionHookalready gates whether a user is allowed to push at all. This hook adds a second check: whether the committer identity in the commits matches the authenticated user's registered emails. Without this, an authenticated user can push commits attributed to someone else.What to build
IdentityVerificationHook(injgit-proxy-core)GitProxyHook, order ~150 (authz range, afterRepositoryWhitelistHook, before content filters)RevCommitin the push:committer.emailAddressviaUserEmailStore.resolveByEmail()rp.sendMessage()+ blockProxyUser.usernamematches the authenticated HTTP Basic principal fromPushIdentityResolver"committer email foo@example.com is registered to user X, but you authenticated as user Y"commit.identity-verification: strict | warn | off(defaultwarnto avoid breaking existing deployments)Config
Wiring
IdentityVerificationHookregistered inStoreAndForwardReceivePackFactoryalongside existing hooksIdentityVerificationFilterfor the transparent proxy path (same logic, accumulates intoValidationSummaryFilter)Depends on
UserEmailStore,LinkedIdentityAuthorizationService,PushIdentityResolver(all already in place)Acceptance criteria
user_emails→ rejected instrictmode, warning sideband message inwarnmodestrictmodeoffmode → hook is a no-op