vole
Clone
Read only, no credentials:
https://rodent.software/vole.git
Write over SSH with a registered key:
git clone ssh://git@rodent.software:2222/vole.git
A free and open-source forge that lives in your Git repo.
Validate the configuration and harden what a deployment creates
ed1812123cd9e9df0f34fdaf0d2511a340c2aaa6 · Keenan Nemetz · 13d ago · parent 13cff33f
Validate the configuration and harden what a deployment creates Two ways an instance used to run in a state it should have refused. The configuration was never checked. `dev_login` was guarded only by a loopback listener, so a proxy that rewrites Host to 127.0.0.1 inherited a credential-free session; open registration could be enabled on a plain-HTTP origin WebAuthn would never accept; a public_url could carry a path or credentials; a size could be negative. Config.Validate now runs before anything is opened and reports every problem at once, and dev_login requires an explicit dev_only opt-in next to a loopback listener with no public address. The per-request check no longer trusts Host at all: it must name the configured listener, and a request carrying a forwarding header gets no session. The files were never checked either. directories were created 0755 and the audit log 0644, and a file keeps the mode it was created with, so an upgraded instance stayed exposed. internal/secure creates secrets at 0600 in directories at 0700, tightens what an existing install left, keeps group access for a shared backup group, and refuses to start when a mode cannot be changed. Every audit writer and the account backup go through it. The service unit drops all capabilities, sets UMask=0027, disables core dumps, hides other processes and devices, and restricts address families; docs/operations.md now states the production baseline.
forge/config/config.go +8−3
| @@ -107,10 +107,14 @@ type Config struct { | |||
| 107 | 107 | // print a link to something it just created. | |
| 108 | 108 | PublicURL string `toml:"public_url"` | |
| 109 | 109 | // DevLogin is a development-only escape hatch: when set to an account name, | |
| 110 | // a browser request from loopback is signed in as that account. It is refused | ||
| 111 | // unless http_addr is itself a loopback address, and the instance logs a | ||
| 112 | // warning at startup. Never enable it on a shared instance. | ||
| 110 | // a browser request from loopback is signed in as that account. It requires | ||
| 111 | // dev_only, a loopback http_addr, and no public_url or https_addr, and the | ||
| 112 | // instance logs a warning at startup. Never enable it on a shared instance. | ||
| 113 | 113 | DevLogin string `toml:"dev_login"` | |
| 114 | // DevOnly acknowledges that this instance is a development instance. It is what | ||
| 115 | // makes dev_login an explicit decision rather than a setting somebody copied | ||
| 116 | // from an example: without it, dev_login is refused at startup. | ||
| 117 | DevOnly bool `toml:"dev_only"` | ||
| 114 | 118 | ||
| 115 | 119 | // Path is the file Load was asked to read. Loaded reports whether it found a | |
| 116 | 120 | // non-empty file there; false means the built-in defaults are in use, which | |
| @@ -278,6 +282,7 @@ ssh_addr = "127.0.0.1:2222" | |||
| 278 | 282 | ||
| 279 | 283 | # Development only: sign loopback browser requests in as this account. Refused | |
| 280 | 284 | # unless http_addr is a loopback address. Never enable this on a shared instance. | |
| 285 | # dev_only = true | ||
| 281 | 286 | # dev_login = "you" | |
| 282 | 287 | ||
| 283 | 288 | # Let anyone create an account by registering a passkey. New accounts have no | |