gitbay

module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 26, 2026 License: 0BSD

README

#+title: gitbay
#+author: Christian Cleberg

[[https://gitbay.org/krz/gitbay/builds][file:https://gitbay.org/krz/gitbay/badge/build.svg]]

A CLI-first git forge. One binary, SQLite, and the system =git= — designed
so the command line is the product and the web UI is a rendering of state
the CLI already manages. Runs at [[https://gitbay.org]].

* Design

SSH is the API. The server authenticates by public key, then dispatches the
requested command: =git-upload-pack= / =git-receive-pack= stream the git
transport, anything else is a control command. The control plane is fully
usable from stock OpenSSH with no client installed:

#+begin_src sh
ssh git@gitbay.org repo create you/project --private
ssh git@gitbay.org issue create you/project --title "bug" --file - < body.md
ssh git@gitbay.org repo log you/project --json
#+end_src

The =gitbay= CLI is ergonomics on top — instance profiles, repo inference
from the origin remote, =$EDITOR= for long text — never a requirement. A
registry test enforces that every command stays reachable over bare ssh.

Properties that follow from the design:

- pushing is SSH-only. HTTPS and =git://= serve anonymous reads of public
  repositories; a push over HTTPS is answered with a pkt-line ERR that
  every git version prints as =remote error:= — no credential prompt,
  ever. Private repositories answer 404/not-found identically to
  nonexistent ones on every surface.
- commit signatures (OpenPGP and SSHSIG) are verified against registered
  keys and verified emails, with six distinct states — =verified=,
  =signed_unknown_key=, =signed_email_mismatch=, =signed_key_expired=,
  =signed_key_revoked=, =bad_signature=, =unsigned= — cached and
  invalidated by a global key epoch, so registering a key retroactively
  verifies old commits.
- there is no server signing key. Server-created commits (web edits,
  merge/squash/rebase commits) display honestly as unsigned, and branches
  with =require_signed_commits= accept only fast-forward merges of
  verified commits — enforced at push time and merge time.
- the web UI is server-rendered with no JavaScript required. In
  =view_only= mode the mutating routes are never registered on the mux;
  browser sessions, where enabled, are minted over SSH (=web login=) —
  there are no passwords.

* Features

- repositories with per-branch protection, forks, and organizations
  (shared owner namespace, membership-derived access)
- issues and merge requests (fast-forward, merge-commit, squash, rebase)
  entirely over ssh, with reviews that go stale on force-push
- merge request heads are fetched /into/ the target repository, so an MR
  survives deletion of its source fork
- =repo import= mirrors from any http(s)/git URL, tokens via stdin only
- registration modes: =closed= (admin creates users), =invite=, =open=
  with SMTP email verification
- signed outbound webhooks with retries, dead-lettering, and SSRF
  guarding; a JSON API (=POST /api/v1/cmd=) fronting the same command
  registry, with bearer tokens mintable only over SSH
- built-in ACME (Let's Encrypt) TLS; =admin backup= produces one
  restore-tested archive (database snapshot first, then repositories)

* Server quickstart

#+begin_src sh
# /etc/gitbay/config.toml
[server]
root = "/var/lib/gitbay"
site_url = "https://forge.example.org"

[http]
acme_email = "you@example.org"
#+end_src

#+begin_src sh
gitbayd --config /etc/gitbay/config.toml check-config
gitbayd --config /etc/gitbay/config.toml admin user create you \
    --key ~/.ssh/id_ed25519.pub --email you@example.org --verified --admin
gitbayd --config /etc/gitbay/config.toml serve
#+end_src

The embedded SSH listener takes port 22 (move the host sshd, or set
=ssh.mode = "system"= to run under it via =AuthorizedKeysCommand=). See
=deploy/= for a cloud-init file, hardened systemd unit, and nightly
backup timer.

* Client quickstart

#+begin_src sh
gitbay remote add myforge forge.example.org --default
gitbay auth whoami
gitbay repo create you/project
gitbay repo clone you/project && cd project
gitbay issue create --title "first issue"   # repo inferred from origin
gitbay mr checkout 4                        # fetches refs/merge-requests/4/head
#+end_src

Every read command takes =--json=; stdout is data, stderr is messages;
exit codes are stable (0 ok, 2 usage, 3 not found, 4 denied). Man pages
via =gitbay man=, completions via =gitbay completion <shell>=.

* Documentation

Docs live in [[https://gitbay.org/krz/gitbay/wiki][the wiki]] — itself a git repository
(=git clone ssh://git@gitbay.org/krz/gitbay.wiki.git=), dogfooding the
wiki feature:

- [[https://gitbay.org/krz/gitbay/wiki/Users][user guide]] — accounts, keys, verified commits, repos, issues, MRs, scripting
- [[https://gitbay.org/krz/gitbay/wiki/Admin][admin guide]] — install, full configuration reference, backup/restore, security
- [[https://gitbay.org/krz/gitbay/wiki/API][API and webhooks]] — the JSON API contract, tokens, webhook payloads and HMAC
- [[https://gitbay.org/krz/gitbay/wiki/Roadmap][roadmap]] — status, phased plan, and what is deliberately not planned
- [[https://gitbay.org/krz/gitbay/wiki/Threat-Model][threat model]] — what the forge trusts and never does

* Contributing

See [[file:CONTRIBUTING.org][CONTRIBUTING]]. Development happens on gitbay.org itself.

* Development

#+begin_src sh
go build ./...
go test ./...        # e2e drives real git, ssh, sshd, and gpg binaries
#+end_src

Layout: =cmd/gitbay= (CLI), =cmd/gitbayd= (daemon, hooks, admin),
=internal/control= (command registry — the single source of truth fronted
by ssh and the JSON API), =internal/sshd= / =httpd= / =gitd= (transports),
=internal/sig= (signature verification), =internal/policy= (access rules),
=internal/store= (SQLite, migrations), =e2e/= (integration tests).

* License

0BSD.

Directories

Path Synopsis
cmd
gitbay command
forge is the client CLI.
forge is the client CLI.
gitbay-runner command
gitbay-runner executes CI builds queued by a gitbay server.
gitbay-runner executes CI builds queued by a gitbay server.
gitbayd command
gitbayd is the forge server daemon.
gitbayd is the forge server daemon.
internal
autolink
Package autolink rewrites cross-references in rendered HTML: #N and !N to the repository's issues and merge requests, owner/name#N (and !N) across repositories, and @user to owner pages.
Package autolink rewrites cross-references in rendered HTML: #N and !N to the repository's issues and merge requests, owner/name#N (and !N) across repositories, and @user to owner pages.
ci
Package ci parses .gitbay/ci.yml, the per-repo build configuration:
Package ci parses .gitbay/ci.yml, the per-repo build configuration:
cliconfig
Package cliconfig manages the client-side configuration: named forge instances at ~/.config/forge/config.toml, and parsing of origin remote URLs so commands run inside a clone need no --repo argument.
Package cliconfig manages the client-side configuration: named forge instances at ~/.config/forge/config.toml, and parsing of origin remote URLs so commands run inside a clone need no --repo argument.
config
Package config loads and validates the gitbayd server configuration.
Package config loads and validates the gitbayd server configuration.
control
Package control implements the forge control commands executed over SSH.
Package control implements the forge control commands executed over SSH.
gitd
Package gitd implements the anonymous git:// protocol listener.
Package gitd implements the anonymous git:// protocol listener.
gitutil
Package gitutil wraps the system git binary.
Package gitutil wraps the system git binary.
hookd
Package hookd is the unix-socket bridge between git hooks and the daemon.
Package hookd is the unix-socket bridge between git hooks and the daemon.
httpd
Package httpd serves the HTTP listener: anonymous smart-HTTP git reads for public repositories, and (from M5) the web UI.
Package httpd serves the HTTP listener: anonymous smart-HTTP git reads for public repositories, and (from M5) the web UI.
lfs
Package lfs implements Git LFS server storage and authorization.
Package lfs implements Git LFS server storage and authorization.
mail
Package mail sends transactional email over SMTP: verification codes and invites.
Package mail sends transactional email over SMTP: verification codes and invites.
mirror
Package mirror synchronizes repositories with foreign remotes: push mirrors propagate local refs outward after each receive, pull mirrors keep a local copy fresh from an upstream.
Package mirror synchronizes repositories with foreign remotes: push mirrors propagate local refs outward after each receive, pull mirrors keep a local copy fresh from an upstream.
notify
Package notify drains the notification queue: activity mail with the same bounded-retry discipline as webhook delivery, so a flaky relay delays feedback instead of losing it.
Package notify drains the notification queue: activity mail with the same bounded-retry discipline as webhook delivery, so a flaky relay delays feedback instead of losing it.
policy
Package policy holds access-control and naming rules.
Package policy holds access-control and naming rules.
protocol
Package protocol defines the wire contract shared by the CLI and server: exit codes, the JSON response envelope, and (later) the SSH command tokenizer.
Package protocol defines the wire contract shared by the CLI and server: exit codes, the JSON response envelope, and (later) the SSH command tokenizer.
sig
Package sig verifies OpenPGP and SSHSIG signatures on git commits and tags, and maps them to the forge's trust states.
Package sig verifies OpenPGP and SSHSIG signatures on git commits and tags, and maps them to the forge's trust states.
sshd
Package sshd implements the embedded SSH listener: public-key auth against registered keys, then dispatch to git transport or control commands.
Package sshd implements the embedded SSH listener: public-key auth against registered keys, then dispatch to git transport or control commands.
store
Package store owns SQLite access and schema migrations.
Package store owns SQLite access and schema migrations.
web
Package web holds the server-rendered templates and static assets for the read-only UI.
Package web holds the server-rendered templates and static assets for the read-only UI.
webhook
Package webhook delivers events to registered endpoints: HMAC-signed JSON POSTs with bounded retries, exponential backoff, and dead-lettering.
Package webhook delivers events to registered endpoints: HMAC-signed JSON POSTs with bounded retries, exponential backoff, and dead-lettering.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL