Pushes und die Committer-Regel
Autor und Committer eines Commits sind Text, den die committende Person in ihre Git-Konfiguration schreibt: Jeder kann dort jeden Namen und jede Adresse eintragen. Was fremforge sicher weiß, ist, wer gepusht hat: das Konto, dessen HTTPS-Token, OAuth-Token oder SSH-Schlüssel die Verbindung geöffnet hat. Darauf bauen zwei Dinge auf:
- Zuordnung zum Pusher. Jeder Push in ein Repository deiner Organisation wird mit diesem Konto erfasst, unabhängig davon, wie die unten beschriebene Regel eingestellt ist.
- Die Committer-Regel. Sie kann verlangen, dass jeder für das Repository neue Commit eine Committer-Adresse hat, die der pushenden Person gehört.
Der Nachweis, wer gepusht hat
fremforge erfasst jede Ref-Aktualisierung in einem Push:
- den Pusher: das Konto, das sich authentifiziert hat;
- wie es sich authentifiziert hat: HTTPS (ein Personal Access Token oder das OAuth-Token aus dem Git Credential Manager), ein SSH-Schlüssel, ein Deploy-Key mit seiner Schlüssel-ID oder ein Job-Token von Actions;
- die Ref sowie ihren alten und neuen Commit;
- in einem Repository, dessen Committer-Regel auf Warnen oder Blockieren steht, die Commits, die für das Repository neu waren;
- die Entscheidung der Committer-Regel.
Der Nachweis stammt aus der eigenen Authentifizierung von Forgejo, nie aus etwas, das der Client sendet. Commits, die fremforge selbst erstellt, werden nicht erfasst: Merges, die Merge-Queue und Bearbeitungen im Web-Editor.
Du findest ihn in der Konsole unter Sicherheit › Push-Schutz › Pushes und die Committer-Regel. Die Seite zeigt die letzten Pushes und eine Suche, die den Push findet, der einen bestimmten Commit gebracht hat. Mit der API:
# Recent pushes, or those to one repository
curl -H "Authorization: Bearer $TOKEN" \
"https://frem.sh/_app/api/v1/orgs/acme/push-protection/push-records?repository=web"
# Which push brought this commit?
curl -H "Authorization: Bearer $TOKEN" \
"https://frem.sh/_app/api/v1/orgs/acme/push-protection/push-records?commit=<full commit id>"Die Suche findet einen Commit unter den ersten 500 neuen Commits jeder Ref-Aktualisierung, in Repositorys, deren Committer-Regel beim Push auf Warnen oder Blockieren stand. Bei ausgeschalteter Regel wird ein Push mit seinen Refs und seinem Pusher erfasst, aber ohne seine Commits, damit die Erfassung einen Push nie verlangsamt. Jeder Push steht außerdem im Audit-Log als git.push, bei einem Push mit Deploy-Key mit dessen ID.
Die Committer-Regel
Die Regel lautet Committer muss dem Pusher entsprechen. Jeder für das Repository neue Commit muss eine Committer-Adresse haben, die entweder
- eine der bestätigten E-Mail-Adressen des Pushers auf frem.sh ist (Einstellungen › Konto). Eine Adresse, die hinzugefügt, aber nie bestätigt wurde, zählt nicht;
- oder die No-Reply-Adresse des Pushers ist,
<login>@noreply.frem.sh, die nur dieses Konto verwenden kann.
| Modus | Was passiert |
|---|---|
| Aus (Standard für Organisationen, die vor dem 2026-10-27 angelegt wurden) | Pushes werden erfasst; nichts wird geprüft. |
| Warnen (Standard für Organisationen, die am oder nach dem 2026-10-27 angelegt wurden) | Der Push wird angenommen, und der Pusher erfährt, welche Commits nicht passen. |
| Blockieren | Der Push wird abgewiesen, bis jeder neue Commit passt. |
Eine Organisation, die am oder nach dem 2026-10-27 angelegt wurde, startet mit Warnen: Kein Push wird je abgewiesen, und ein Pusher, dessen Commit eine Adresse trägt, die er nicht bestätigt hat, erfährt das. Ein Owner kann die Regel jederzeit ausschalten oder auf Blockieren stellen. Mit Warnen wartet ein Push auf die Prüfung: gemessen am 2026-10-27 im Median etwa 90 ms.
Geprüft werden nur Commits, die für das Repository neu sind. Ein Commit, der bereits auf einem anderen Branch liegt, wurde bei seinem ersten Eintreffen geprüft. Wenn du also main in deinen Branch mergst, musst du nicht für die Commits anderer geradestehen.
Ein abgewiesener Push nennt die Commits und Adressen:
remote: fremforge: push refused: the committer of 1 new commit is not one of your verified email addresses.
remote: 3f2a9c1b8e7d someone@example.com
remote: Set user.email to one of them, rewrite these commits (git rebase -i, or git commit --amend --reset-author), and push again.Was nicht geprüft wird
- Pushes mit einem Job-Token von Actions. Ein Workflow pusht als Job, nicht als Person.
- Plattform-Bots. Das sind die Konten, die fremforge selbst betreibt, etwa die Bots für Sicherheitskorrekturen und Renovate.
- Ausgenommene Nutzer, die du in der Regel aufführst, zum Beispiel ein Dienstkonto, das als es selbst pusht.
- Deploy-Keys. Ein Deploy-Key hat keine Person und keine bestätigte Adresse. Seine Pushes werden mit der Schlüssel-ID erfasst und nicht geprüft, es sei denn, du wählst Pushes mit Deploy-Key im Blockiermodus abweisen, wodurch sie abgewiesen werden, solange die Regel auf Blockieren steht.
- Commits, die fremforge erstellt: Merges, die Merge-Queue und Web-Bearbeitungen.
Wenn die Prüfung nicht laufen kann
Kann fremforge die Prüfung nicht ausführen (zum Beispiel, weil der Dienst, der sie beantwortet, nicht innerhalb von 2 Sekunden antwortet), wird der Push in jedem Modus angenommen. Er wird als Nicht geprüft erfasst, und im Blockiermodus werden die Betreiber von fremforge alarmiert. Würde jeder Push abgewiesen, sobald eine Prüfung nicht verfügbar ist, stünde die Arbeit deiner Teams still. Die Regel ist daher fail-open, und der Ausfall bleibt sichtbar: im Push-Log und für die Betreiber. Suche in den Push-Einträgen nach der Entscheidung Nicht geprüft.
Einstellen
In der Konsole legt Sicherheit › Push-Schutz › Pushes und die Committer-Regel die Regel der Organisation fest. Ein Repository kann eine eigene Regel haben, die für dieses Repository die der Organisation ersetzt. Diese setzt du mit der API:
# The organisation's rule
curl -X PUT -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"mode": "block", "refuse_deploy_keys": false, "exempt_users": ["acme-release-bot"]}' \
"https://frem.sh/_app/api/v1/orgs/acme/push-protection/committer-rule"
# One repository's own rule, and back to the organisation's
curl -X PUT -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"mode": "warn"}' "https://frem.sh/_app/api/v1/orgs/acme/push-protection/committer-rule/repos/legacy-import"
curl -X DELETE -H "Authorization: Bearer $TOKEN" \
"https://frem.sh/_app/api/v1/orgs/acme/push-protection/committer-rule/repos/legacy-import"Eine Regel zu ändern erfordert den Scope policy:write, und jede Änderung steht im Audit-Log als push-protection.committer-rule.updated. Eine Regel, die du einschaltest oder änderst, gilt innerhalb von 60 Sekunden für Pushes.
Bevor du Blockieren einschaltest
- Lass Warnen eine Weile laufen und suche im Push-Log nach Zeilen mit Gewarnt. Sie zeigen, wer mit einer Adresse committet, die er nicht bestätigt hat.
- Bitte die Leute, die Adresse aus ihrer Git-Konfiguration zu bestätigen oder
user.emailauf ihre No-Reply-Adresse zu setzen. - Das Importieren von Historie (das Pushen eines bestehenden Projekts mit Commits anderer) scheitert im Blockiermodus, weil diese Commits für das Repository neu sind und von anderen committet wurden. Importiere im Warnmodus oder nimm die importierende Person für den Import aus. Mehr als 5000 neue Commits in einem Push werden im Blockiermodus abgewiesen, weil die Regel höchstens 5000 prüft; pushe die Historie in Teilen.
Vergleich mit GitHub
GitHub hat dieselbe Regel, „Committer must match pusher", in einer eingeschränkten Preview für GitHub Enterprise (2026-10-12). GitHub erfasst den Pusher pro Commit. fremforge erfasst den Pusher pro Ref-Aktualisierung, mit den neuen Commits, wo die Regel eingeschaltet ist, und bietet eine Suche nach Commit.