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.
Add browser auth, contributor access, and gated CI
6c84d387e5f608360e30484a1a5b1cff41076850 · Keenan Nemetz · 16d ago · parent c36d5073
Add browser auth, contributor access, and gated CI Browser sign-in now uses passkeys. Enrollment links are one-time, sessions are hashed in users.db, and issue/comment/approval writes use the session account. HTTPS public_url is required for WebAuthn. Add the contributor role between read and maintain. Contributors can discuss and open change requests, and may push only refs/heads/contrib/<account-id>/. Contributor CI is held per commit until a maintainer allows the exact tip from the repository page. Rename the write role to maintain. write remains accepted as the historical spelling, and access.Write remains as a Go alias so existing callers and ACL rows keep working. Update the web, CLI, queue schema, and guides for the new flows, and cover the role, namespace, auth, and CI-gating paths in tests.
docs/operations.md +16−10
| @@ -9,7 +9,7 @@ These are the tasks that keep an instance healthy. | |||
| 9 | 9 | Back up three things: | |
| 10 | 10 | ||
| 11 | 11 | ```sh | |
| 12 | vole admin user backup backup/users.db # accounts, keys, rules, admins, locks | ||
| 12 | vole admin user backup backup/users.db # accounts, keys, passkeys, sessions, rules, locks | ||
| 13 | 13 | cp data/ssh_host_ed25519_key backup/ # the only secret on the machine | |
| 14 | 14 | cp data/audit.log backup/ 2>/dev/null # history of admin actions | |
| 15 | 15 | ``` | |
| @@ -18,9 +18,10 @@ cp data/audit.log backup/ 2>/dev/null # history of admin actions | |||
| 18 | 18 | `users.db` by hand can miss recent changes that have not been written to the main | |
| 19 | 19 | database file yet. | |
| 20 | 20 | ||
| 21 | If you lose the user database, you need to recreate accounts with their keys | ||
| 22 | again. You do not lose repositories. Nothing in the user database is secret, so a | ||
| 23 | copied backup does not expose anything. | ||
| 21 | If you lose the user database, you need to recreate accounts and re-enroll their | ||
| 22 | passkeys. You do not lose repositories. The backup contains account metadata, | ||
| 23 | public keys, and hashes of session and enrollment tokens; it does not contain a | ||
| 24 | usable password or a plaintext session token. Treat it as private anyway. | ||
| 24 | 25 | ||
| 25 | 26 | Repositories are ordinary Git repositories under `data/repos/`. You can back them | |
| 26 | 27 | up by copying or cloning. Issues, change requests, releases, and CI records travel | |
| @@ -31,7 +32,9 @@ with them because they are stored in Git. | |||
| 31 | 32 | 1. Restore `data/users.db`, `data/ssh_host_ed25519_key`, and `data/audit.log`. | |
| 32 | 33 | 2. Restore the repositories under `data/repos/`. | |
| 33 | 34 | 3. Run `vole admin index rebuild`. | |
| 34 | 4. Start `vole serve`. | ||
| 35 | 4. Run `vole admin user revoke-sessions --all` so sessions from the restored copy | ||
| 36 | cannot outlive their cookies. | ||
| 37 | 5. Start `vole serve`. | ||
| 35 | 38 | ||
| 36 | 39 | Large files, CI logs, and build artifacts live in `data/lfs/`. Back that directory | |
| 37 | 40 | up too if you need those files. `vole admin gc` treats files reachable from a | |
| @@ -63,20 +66,23 @@ storage only grows when someone pushes files. | |||
| 63 | 66 | vole admin index rebuild | |
| 64 | 67 | ``` | |
| 65 | 68 | ||
| 66 | `data/runs.db` holds the CI queue and run index. Deleting it loses attempts that | ||
| 69 | `data/runs.db` holds the CI queue, run index, and contributor-branch CI approvals. Deleting it loses attempts that | ||
| 67 | 70 | were in progress. Vole queues current branch and tag tips again from Git, and | |
| 68 | 71 | `vole admin index rebuild` restores finished history from the run records on each | |
| 69 | 72 | repository's `vole` branch. | |
| 70 | 73 | ||
| 71 | 74 | ## Security notes | |
| 72 | 75 | ||
| 73 | - The SSH host key is the only secret Vole stores. Keep it readable only by the | ||
| 74 | Vole user (`0600`). | ||
| 76 | - The SSH host key is the only long-term secret Vole stores. Keep it readable | ||
| 77 | only by the Vole user (`0600`). Browser session and enrollment tokens are | ||
| 78 | stored as hashes. | ||
| 75 | 79 | - Nothing Vole writes is signed: not pushes, not approvals, not CI results. Vole | |
| 76 | 80 | relies on the SSH key at the connection, the checks before a push is accepted, | |
| 77 | 81 | and the audit log. | |
| 78 | - The web interface is read-only. There is no password store, login, or session | ||
| 79 | token. | ||
| 82 | - The web interface is read-only for anonymous visitors. Passkey login enables | ||
| 83 | issue, comment, and approval writes; HTTP Git clone remains read-only. There is | ||
| 84 | no password store. Restoring an old `users.db` should be followed by | ||
| 85 | `vole admin user revoke-sessions --all`. | ||
| 80 | 86 | - Remote administration uses the same SSH listener and key. Only active instance | |
| 81 | 87 | admins can run it, and every admin command is audited. | |
| 82 | 88 | - Private repositories return `404` on the web and over HTTP, so visitors cannot | |