● zegit · proves
The Gateway
The gateway verifies every pushed commit's AoV against the Root CA and enforces Tag Request quorum on release tags — rejecting anything that fails. It is also a post-receive forwarder: accepted refs are mirrored to GitHub and Gitea via uploaded git bundles, with the zegit-gateway GitHub App as the sole writer to origin/master.
What it does
The production deployment is z-gateway-server, a standalone SSH git server. On every push it runs a pre-receive gate: it verifies the AoV for each commit against the Root CA and checks revocation; on release tags it enforces quorum. Accepted refs are then forwarded post-receive to GitHub (via the zegit-gateway GitHub App, the sole writer to origin/master) and Gitea via uploaded git bundles. It calls the Control Plane for policy, revocation, and quorum, but does the signature and hash math locally for low latency.
Deployed mode
The production deployment is z-gateway-server, a standalone SSH git server. GitHub SaaS is live via the zegit-gateway GitHub App (sole writer to origin/master). Gitea and GitLab self-managed hook-based installs are also supported.
Prerequisites
- The
z-gatewaybinary on the Git host (e.g./usr/local/bin/z-gateway), executable. - Your Root CA certificate (e.g.
/etc/zegit/root.crt). - The Control Plane URL (e.g.
https://zegit.io). - Outbound HTTPS to the Control Plane — the hook fails closed if the CP is unreachable.
Install on Gitea
Drops a pre-receive.d/zegit hook without touching Gitea's own hooks. Add --dry-run to preview.
z-gateway install gitea \
--hooks-dir /var/lib/gitea/.../<repo>.git/hooks \
--bin /usr/local/bin/z-gateway \
--trust-root /etc/zegit/root.crt \
--cp-url https://zegit.io
z-gateway status gitea --hooks-dir /var/lib/gitea/.../<repo>.git/hooksGitea must have DISABLE_GIT_HOOKS = false in app.ini under [security], or the hook never runs.
Install on GitLab self-managed
GitLab uses global server hooks on the Gitaly node(s). Install once per node — and repeat on every Gitaly node.
z-gateway install gitlab \
--hooks-dir /var/opt/gitlab/gitaly/custom_hooks \
--bin /usr/local/bin/z-gateway \
--trust-root /etc/zegit/root.crt \
--cp-url https://zegit.ioStatus & uninstall
z-gateway status reports each hook as present [zegit], present [foreign], or absent. z-gateway uninstall removes only ZeGit-installed hooks — it refuses to delete hooks lacking the ZeGit marker.
Pre-receive exit codes
| Code | Meaning |
|---|---|
0 | All refs accepted. |
1 | At least one ref rejected — the push is blocked. |
2 | Configuration error. |
Transport & authorization
Gateway transport auth uses CA-signed OpenSSH user certificates (sshd TrustedUserCAKeys + KRL revocation) — no authorized_keys. Authorize a pusher by enrolling their identity in the Control Plane; revoke via POST /admin/ssh-revoke and the gateway rebuilds its KRL within 60s.
Troubleshooting
| Symptom | Likely cause |
|---|---|
| All pushes rejected right after install | Hook can't reach the CP (fail-closed), or the wrong Root CA. |
| Hook doesn't run on Gitea | DISABLE_GIT_HOOKS=true, or the binary isn't executable. |
| Works on one GitLab node, not another | The hook isn't installed on every Gitaly node. |
Authoritative reference, generated from the component repos. Spot something stale? Tell us.