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/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.

Name branches after the account, and labels after the display

474a812d199a109ba894124cd6f26be12c73285d · Keenan Nemetz · 16d ago · parent ade6107e

Name branches after the account, and labels after the display

A contributor's folder was `refs/heads/contrib/<account-id>/`, which told a
reader nothing without decoding a ULID. It is now the account name,

    refs/heads/contrib/<name>/<branch>

and the name is therefore fixed at creation: renaming an account would strand
every ref under its old folder, so `vole admin user rename` is gone and the
users row itself — kept after retirement — is what stops a name being reissued.

What people see is now a separate, mutable display name, validated by the same
rules wherever it is set (CLI, remote admin, registration, `/account`) and shown
on pages, approvals, listings and refusals. Nothing is authorized by it and
nothing on disk is keyed by it: metadata authors stay account names because the
push boundary resolves them for ownership, and approvals stay account ids.

`user_names`, `Snapshot.Reserved` and `Account.Former` are dropped: with a fixed
name there are no former names to remember, and the UNIQUE column already does
the reserving. Opening an older roster adds the `display` column and drops the
alias table in place; contributor refs written under the old id namespace are
left where they are, readable, and landable by a maintainer.

docs/users-and-access.md +34−19

@@ -5,18 +5,25 @@ Vole has no password database. An account has two kinds of credential:
5 5 - an **SSH key** for Git over SSH and remote administration;
6 6 - a **passkey** for signing in to the browser.
7 7
8 Both resolve to the same permanent account id, so access rules, approvals, and
9 audit records do not care which one you used.
8 Both resolve to the same account, so access rules, approvals, and audit records
9 do not care which one you used.
10 10
11 11 ## Accounts and keys
12 12
13 An account has a permanent id and a name you can change. Access rules and
14 approvals are attached to the permanent id, so renaming an account does not break
15 anything.
13 An account has three names, and they are not interchangeable:
16 14
17 Names are never reused. When you retire an account, its keys stop working and its
18 name stays reserved. An old reference can never silently point at a different
19 person.
15 - the **name**, chosen when the account is created and fixed for good. It is what
16 your contributor branches are named after (`refs/heads/contrib/<name>/`), so a
17 rename would strand every ref and every author field already written. Keep it.
18 - the **display name**, an optional label shown next to your account on requests,
19 issues, approvals and user listings. It can be anything printable and can be
20 changed at any time. Nothing is authorized by it.
21 - the **id**, a ULID Vole assigns internally. Access rules and approval files are
22 keyed by it.
23
24 Names are never reused: because the account row outlives retirement, retiring
25 someone keeps their name attached to them. An old reference can never silently
26 point at a different person.
20 27
21 28 Account data lives in `data/users.db`. It also holds passkeys, one-time
22 29 enrollment links, browser sessions, repository access rules, and file locks.
@@ -26,10 +33,11 @@ take effect without restarting the server.
26 33
27 34 ```sh
28 35 vole admin user create alice --key ~/.ssh/id_ed25519.pub
36 vole admin user create bob --display "Bob Smith" --key bob.pub
29 37 vole admin user add-key alice --key ~/.ssh/id_ed25519_work.pub
30 38 vole admin user list
31 39 vole admin user rm-key alice SHA256:...
32 vole admin user rename alice a-alice
40 vole admin user display alice "Alice O'Brien"
33 41 vole admin user retire alice
34 42 vole admin user backup backup/users.db
35 43 ```
@@ -38,7 +46,9 @@ vole admin user backup backup/users.db
38 46 `--key` (and with no key on stdin), it creates a browser-only account and prints a
39 47 one-time enrollment link. `user invite` issues a fresh link for an existing
40 48 account. `user add-key` adds another SSH key; use it to rotate credentials
41 without changing the account id that access rules and approvals refer to.
49 without changing the account that access rules and approvals refer to.
50 `user display` sets or clears the label (an empty string clears it); there is no
51 command to change the account name.
42 52
43 53 ## Browser sign-in
44 54
@@ -70,7 +80,7 @@ vole admin acl default demo contributor
70 80 ```
71 81
72 82 A registered account can add its own SSH key from **Account**, which is what lets
73 it push to `refs/heads/contrib/<account-id>/`. Open registration has no email
83 it push to `refs/heads/contrib/<name>/`. Open registration has no email
74 84 verification, so leave it off on a private instance unless you want that policy.
75 85
76 86 Admins can inspect and revoke sessions:
@@ -129,7 +139,7 @@ accounts.
129 139 |---|---|
130 140 | `none` | No access |
131 141 | `read` | Clone, fetch, and browse the repository |
132 | `contributor` | Read, file issues and comments, push only `refs/heads/contrib/<account-id>/*`, and open change requests from those branches |
142 | `contributor` | Read, file issues and comments, push only `refs/heads/contrib/<name>/*`, and open change requests from those branches |
133 143 | `maintain` | Everything a contributor can do, plus push shared branches, triage issues, and approve change requests |
134 144 | `admin` | Everything a maintainer can do, plus manage access, push protected branches, override locks, and repair metadata |
135 145
@@ -175,17 +185,22 @@ vole admin acl runners demo ci-runner-1
175 185 The `contributor` role is for open-source projects that accept outside patches.
176 186 A contributor can read, file issues and comments, and open a change request from
177 187 the browser. Their Git writes are confined to a branch folder named after their
178 permanent account id:
188 account name:
179 189
180 190 ```text
181 refs/heads/contrib/<account-id>/<branch>
191 refs/heads/contrib/<name>/<branch>
182 192 ```
183 193
184 For example, account `01M5JR2JK29KKMAA1T9MDNTPBP` may push
185 `refs/heads/contrib/01M5JR2JK29KKMAA1T9MDNTPBP/fix-docs`. They cannot push
186 `refs/heads/main`, another account's folder, tags, or the `vole` metadata branch.
187 The pre-receive hook checks the namespace, and rebasing or deleting a branch
188 inside their own folder is allowed because it is not shared history.
194 For example, account `alice` may push `refs/heads/contrib/alice/fix-docs`. They
195 cannot push `refs/heads/main`, another account's folder, tags, or the `vole`
196 metadata branch. The pre-receive hook checks the namespace, and rebasing or
197 deleting a branch inside their own folder is allowed because it is not shared
198 history.
199
200 The namespace is the account name rather than the internal id, so a ref says
201 whose work it is without decoding a ULID. It is also why names are fixed at
202 creation: renaming an account would otherwise orphan every branch under its old
203 folder. A display name is safe to change because no ref is named after it.
189 204
190 205 The browser's **Open change request** form lists only the branches the account
191 206 may use as a head. The head commit is resolved from that branch; a contributor