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.
Delete the instance signing key
5d6db0240d02ffd70acff6ee98b3a1d521353e85 · Keenan Nemetz · 17d ago · parent 22528ac3
Delete the instance signing key The key existed to sign run records, and runner signing made it pointless — but deleting it is not tidying. An instance-signed anything can only be checked by trusting the instance, so a mirror or a third party cannot verify it: trust would sit on the box. With users, runners and approvers each holding a key, trust sits on the parties, and the server is a relay that can withhold service but cannot forge a result. That is a property worth having, and the key was the one thing contradicting it. So: `internal/signing` is gone, `Config.InstanceKey()` is gone, the server no longer loads a key at boot, and `/healthz` reports only the user count instead of a fingerprint nothing verifies. The host key is now the only secret the instance holds, which is what the backup section of the README says. `go mod tidy` changes nothing: the package only used the standard library. Verified: scripts/ci.sh green (gofmt, vet, build, markdown links, go test -race ./..., including TestHealthzReportsUsers against the new body and the full end-to-end suite that starts the server from a fresh data directory).
internal/server/server.go +2−9
| @@ -19,7 +19,6 @@ import ( | |||
| 19 | 19 | "github.com/rodent-software/vole/internal/pages" | |
| 20 | 20 | "github.com/rodent-software/vole/internal/repo" | |
| 21 | 21 | "github.com/rodent-software/vole/internal/runs" | |
| 22 | "github.com/rodent-software/vole/internal/signing" | ||
| 23 | 22 | "github.com/rodent-software/vole/internal/sshserver" | |
| 24 | 23 | "github.com/rodent-software/vole/internal/transport" | |
| 25 | 24 | "github.com/rodent-software/vole/internal/web" | |
| @@ -37,7 +36,6 @@ type Server struct { | |||
| 37 | 36 | Pages *pages.Server | |
| 38 | 37 | Proxy *transport.Proxy | |
| 39 | 38 | SSH *sshserver.Server | |
| 40 | Key *signing.Key | ||
| 41 | 39 | Web *web.Web | |
| 42 | 40 | Log *slog.Logger | |
| 43 | 41 | mux *http.ServeMux | |
| @@ -70,11 +68,6 @@ func New(cfg *config.Config, binPath string, log *slog.Logger) (*Server, error) | |||
| 70 | 68 | } else if n > 0 { | |
| 71 | 69 | log.Info("hooks installed", "repos", n) | |
| 72 | 70 | } | |
| 73 | key, err := signing.LoadOrCreate(cfg.InstanceKey()) | ||
| 74 | if err != nil { | ||
| 75 | return nil, fmt.Errorf("instance key: %w", err) | ||
| 76 | } | ||
| 77 | |||
| 78 | 71 | proxy := transport.New(transport.Config{ | |
| 79 | 72 | Root: cfg.ReposDir(), | |
| 80 | 73 | Open: rs.Open, | |
| @@ -109,7 +102,7 @@ func New(cfg *config.Config, binPath string, log *slog.Logger) (*Server, error) | |||
| 109 | 102 | ||
| 110 | 103 | s := &Server{ | |
| 111 | 104 | Cfg: cfg, Repos: rs, Identity: ident, Runs: runStore, Index: ix, LFS: lfsStore, | |
| 112 | Proxy: proxy, SSH: ssh, Key: key, Web: wp, Log: log, | ||
| 105 | Proxy: proxy, SSH: ssh, Web: wp, Log: log, | ||
| 113 | 106 | } | |
| 114 | 107 | // Sites are opt-in: without a pages domain there is no host to serve them on, | |
| 115 | 108 | // and an instance that never wanted them pays no processes for the idea. | |
| @@ -161,7 +154,7 @@ func (s *Server) routes() *http.ServeMux { | |||
| 161 | 154 | ||
| 162 | 155 | mux.HandleFunc("GET /healthz", func(rw http.ResponseWriter, r *http.Request) { | |
| 163 | 156 | rw.Header().Set("Content-Type", "text/plain") | |
| 164 | fmt.Fprintf(rw, "ok\nkey=%s\nusers=%d\n", s.Key.Fingerprint(), s.Identity.Snapshot().Count) | ||
| 157 | fmt.Fprintf(rw, "ok\nusers=%d\n", s.Identity.Snapshot().Count) | ||
| 165 | 158 | }) | |
| 166 | 159 | ||
| 167 | 160 | // Anonymous, read-only git. Registered without a method so git's POSTs reach it. | |