Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Phase 1: a working git remote with access control

653e0cfc227c992e5b26ea10057aa0b424b6ce4f · Keenan Nemetz · 18d ago · parent c5626f1b

Phase 1: a working git remote with access control

Vole is now a functioning forge foundation: one CGO-free binary that serves
real git over smart HTTP and enforces per-repo policy in pre-receive.

What is in:

- internal/transport drives `git http-backend` as a CGI subprocess. Chunked
  uploads are spooled to learn CONTENT_LENGTH (git's default client config
  produces them), spool files are cleaned on error and abort, and a janitor
  sweeps anything a crash left behind. Pushes are capped by size and
  serialised behind a semaphore, because Phase 0 measured 1.13 GB of git RSS
  for a single 1 GiB push.
- internal/acl stores roles on refs/vole/acl inside each repository, so
  access rules travel with a clone. One evaluation function is shared by the
  hook and the web layer.
- internal/hook enforces policy in pre-receive: authentication, write role,
  protected refs, per-blob size limits, and a refusal to accept pushes to
  refs/vole/* - without that last check a writer could push their own
  acl.json and grant themselves admin.
- internal/auth holds users, personal access tokens and web sessions in
  SQLite. Passwords use PBKDF2-SHA256; tokens are 256-bit random values and
  are stored as SHA-256 hashes, since there is no low-entropy secret to grind.
- internal/index is the derived read model, rebuildable from disk and refs.
- internal/repo owns the bare-repo store and the metadata ref CAS helper.
- internal/web is the browse surface: repo list, tree, blob, raw, history,
  login, and per-repo settings for access rules, rename and delete.
- internal/signing creates the instance ed25519 key at first boot for the
  Phase 7 work.

Every Phase 1 exit criterion has a test that would fail if it regressed:
clone/push against a real listener, read-only and anonymous rejection with the
ref proven unmoved, rebuild-from-refs compared against the actual acl ref, a
spool file proven absent after an aborted chunked upload, and two pushes
completing through a single-slot semaphore. scripts/ci.sh runs gofmt, vet,
build, a markdown link check and the race-enabled suite.

Verified by hand as well: a clean `vole init` -> user -> token -> push ->
clone cycle, web login and browse, and a 256 MiB chunked push killed
mid-flight leaving no ref, no spool file and no orphaned git processes.

README.md +47

@@ -16,3 +16,50 @@ Vole turns a git repo into a fully functional software forge.
16 16
17 17 See [docs/roadmap.md](docs/roadmap.md) for the phased implementation plan.
18 18
19 ## Status
20
21 **Phase 1 is implemented.** Vole is a working git remote with access control.
22
23 Working today:
24
25 - Smart HTTP clone / push / fetch with a stock `git` client
26 - Users, personal access tokens, and web sessions
27 - Per-repo roles (read / write / admin) stored *in the repository* at
28 `refs/vole/acl`, so access rules travel with a clone
29 - Policy enforced in `pre-receive`, so a rejected push moves no refs at all
30 - Protected refs, per-blob size limits, push size cap, push concurrency limit
31 - Repo create / rename / delete, and a web browser for files and history
32 - A derived SQLite index that can be deleted and rebuilt from the repos
33 - An instance ed25519 key generated at first boot (used for metadata signing in
34 Phase 7)
35
36 Not yet: issues, change requests, CI, LFS, static sites, signature verification.
37
38 ## Try it
39
40 ```sh
41 go build -o vole ./cmd/vole
42
43 ./vole init -dir . # writes vole.toml
44 VOLE_PASSWORD=correct-horse ./vole user create you
45 ./vole repo create demo -owner you
46 ./vole serve # http://127.0.0.1:8080
47 ```
48
49 Create a token to use as your git password:
50
51 ```sh
52 ./vole user token you -scope write
53 git clone http://you:<token>@127.0.0.1:8080/git/demo.git
54 ```
55
56 A single-user instance treats that user as the instance admin, so a fresh
57 install is usable without editing config. On a multi-user instance, list
58 admins under `admin_users` in `vole.toml`.
59
60 Run everything before pushing:
61
62 ```sh
63 ./scripts/ci.sh
64 ```
65