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.
Let an account be a bot
29a795b9d5b79cf5c8f2b7f3b4f6572f7cdff444 · Keenan Nemetz · 7d ago · parent e7aa0785
Let an account be a bot An automation needs an identity: something to assign an issue to, mention in a comment, and name in an approval and the audit log. An account already gives all of that, so this adds only the invariants a bot needs and the word for it. A bot is created with `vole admin account create --bot`, with the repository role the admin decides it should have. It has no browser sign-in — `account invite` and adding a passkey are refused — and it cannot hold the instance-admin role, because Admin reaches every repository and every instance surface while a bot is a repository automation. It is marked as a bot in the user directory and on its profile. Everything else is deliberately unchanged. A bot obeys the rules of its role: a contribute bot pushes only its own contributor branch and its CI waits for a maintainer to allow the tip; a maintain bot pushes shared branches, runs CI immediately, and its approval counts. The kind is fixed at creation, like the name, and a roster that predates it reads every account as a person. This is the first of three slices of #165. The per-run credential that lets a workflow act as a bot without a long-lived key in a repository secret is next; this slice changes no push rule and no permission.
docs/accounts-and-access.md +39
| @@ -21,6 +21,45 @@ Names are never reused: because the account row outlives retirement, retiring | |||
| 21 | 21 | someone keeps their name attached to them. An old reference can never silently | |
| 22 | 22 | point at a different person. | |
| 23 | 23 | ||
| 24 | ## Bot accounts | ||
| 25 | |||
| 26 | An automation can have an account of its own, so the work it does is attributable | ||
| 27 | to it and it can be assigned an issue or named in a comment like anyone else. A bot | ||
| 28 | is created by an instance admin with the repository role it should have: | ||
| 29 | |||
| 30 | ```sh | ||
| 31 | vole admin account create coding-agent --bot --key agent.pub --role contribute | ||
| 32 | ``` | ||
| 33 | |||
| 34 | The kind is fixed at creation, like the name. A bot differs from a person in three | ||
| 35 | ways, and only three: | ||
| 36 | |||
| 37 | - **No browser sign-in.** A bot cannot be given a passkey or an enrollment link, | ||
| 38 | because it has no browser, and a link it could never use is a secret in the roster | ||
| 39 | for no reason. `account invite` and adding a passkey are refused for a bot. | ||
| 40 | - **No instance admin.** A bot is a repository automation, and the Admin role reaches | ||
| 41 | every repository and every instance surface, so it is refused when the account is | ||
| 42 | created and when its role is changed later. | ||
| 43 | - **It is shown as a bot** in the user directory and on its profile, so a reader | ||
| 44 | knows a machine wrote what they are reading. | ||
| 45 | |||
| 46 | Everything else is the same, and deliberately so: a bot is subject to the rules of | ||
| 47 | whatever role it holds. A `contribute` bot may push only | ||
| 48 | `refs/heads/contrib/<name>/`, and CI on that tip waits for a maintainer to allow it, | ||
| 49 | exactly as for a person. A `maintain` bot may push shared branches, its pushes run | ||
| 50 | CI immediately, it receives the secrets its workflows declare, and its approval | ||
| 51 | counts when it is not the author. Granting a role is the trust decision, and the | ||
| 52 | audit log and every approval name the bot. | ||
| 53 | |||
| 54 | A bot acts by holding a key, like a person. A short-lived credential that the | ||
| 55 | instance issues for one run and revokes when it ends is not available yet, so a | ||
| 56 | workflow that acts as a bot today holds the account's key in a repository secret, | ||
| 57 | with the exposure that implies: any job that declares the secret can read it. | ||
| 58 | |||
| 59 | Retiring a bot revokes it immediately: its key stops resolving, and a queued job it | ||
| 60 | was a runner for is no longer owed. Its name stays attached to its history, like | ||
| 61 | anyone else's. | ||
| 62 | |||
| 24 | 63 | ## Profiles and the user directory | |
| 25 | 64 | ||
| 26 | 65 | Account names are public on an instance. `/u` lists everyone who has an account, | |