Commit signing does not travel with the forge credential: signed-commit forges are unworkable via madtea #424
Labels
No labels
breaking
bug
documentation
enhancement
epic
good first issue
help wanted
refactoring
resolution/duplicate
resolution/invalid
resolution/wontfix
security
severity/critical
severity/high
severity/low
severity/medium
status/abandoned
status/blocked
status/needs-decision
status/needs-info
status/needs-verification
testing
upstream
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
sixfold-space/madtea#424
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
madtea resolves the auth TOKEN per forge host from its secure backend and injects it via GIT_ASKPASS for clone/push/API, so authentication travels automatically with the repo.
Commit SIGNING does not travel. On a forge madtea treats as requiring signed commits,
madt_commitandmadt_finishrefuse:madtea holds the token, not a signing key, so it can authenticate but cannot sign. A fresh
madt_cloneof such a forge is then unworkable through the madtea flow: the operator must hand-configurecommit.gpgsign/user.signingkey/gpg.formatper clone, with a key already registered to the forge account. Auth is seamless; signing is manual and per-clone.Observations
GET /repos/<owner>/<repo>/branch_protectionson a repo on that host returns[](no rule requires signed commits there), yet the guard still blocks every commit in the clone.not_signed_commit). So the repo currently accepts unsigned commits, while the local guard refuses to make one.Enhancement
Let the signing identity travel with the forge credential, the way the token does. Candidate directions, and the security design behind them is still open:
commit.gpgsign/user.signingkey/gpg.format) on clone or before the first commit.Notes
This is a security-design question, and the three directions differ mainly in where the signing key ends up living:
My lean is (c) as the immediate fix, because it stops the guard blocking commits the forge would accept, and it moves no key material anywhere new. (a) is the longer-term convenience, and it is the option that puts a signing key into madtea's secure backend, which is a real widening of what that backend holds. I want that part settled deliberately before any of it is built.
madt_repos editlacks fast-forward-only + rebase-explicit merge flags and mislabelsallow_rebase_update#432Decided: madtea does not custody signing keys. It stays inside git's standard model and fixes the guard.
Standard git keeps the private signing key in an agent, the OS store, or hardware, and points git config at it (
user.signingkey,gpg.format); the forge verifies the uploaded public key. Since git 2.34, SSH signing with an existing key is the common default. madtea holds the token because it must present that bearer secret on every request; it does not need to hold a signing key, because git already delegates signing.So option (c), extended:
user.signingkey, an ssh-agent key, or a gpg key) and offer to set the clone'sgpg.format/user.signingkey/commit.gpgsignto it.End state: signed commits that work through madtea, using the operator's own key held where git expects it. This unblocks #425 items 2-3.
Recorded in the design of record: ADR 0013 amendment (2026-09-08), merged in PR #471. This issue stays open for the guard rework and the configure-from-existing-key implementation.