docs

  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-gateway binary 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.

terminalbash
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/hooks

Gitea 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.

terminalbash
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.io

Status & 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

CodeMeaning
0All refs accepted.
1At least one ref rejected — the push is blocked.
2Configuration 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

SymptomLikely cause
All pushes rejected right after installHook can't reach the CP (fail-closed), or the wrong Root CA.
Hook doesn't run on GiteaDISABLE_GIT_HOOKS=true, or the binary isn't executable.
Works on one GitLab node, not anotherThe hook isn't installed on every Gitaly node.

Authoritative reference, generated from the component repos. Spot something stale? Tell us.