Commit 9ff63ee5ef

9ff63ee5eff7f810bca1fcacf316f57ae4b4aab7

parent: a6378c178c

Verified · cmc ci/build: success ci/test: success

cmc <hello@cleberg.net> · 2026-09-29 15:30 UTC

wiki, changelog: ids not reused after a delete

Closes #306

Layout: unified · split

.gitbay/wiki/Architecture/09-Controls.org +1
@@ -40,6 +40,7 @@ chapter names of OWASP ASVS 4.0 where one fits.
4040| Admin functions isolated | in place | =admin= noun gated in =Dispatch=; =audit= admin-only |
4141| CSRF protection | in place | SameSite=Lax plus =checkOrigin= (=accounts.go=) |
4242| Typed confirmation for destructive web actions | in place | =internal/httpd/confirm.go= |
43| Deleted rows' ids never handed out again | in place | AUTOINCREMENT on accounts, orgs, repositories, keys, tokens and the delivery queues; build ids from a high-water mark (=internal/store/builds.go=), so a grant, deploy key, parked about text, token or claim naming a deleted row names nothing; deletes take the grants, deploy keys and about texts that name the row by id |
4344
4445** Input handling and output encoding (V5)
4546
.gitbay/wiki/Architecture/10-Known-Gaps.org +1
@@ -16,6 +16,7 @@ what the 2026-09-27 review found; remove a row when its issue closes.
1616| Area | Gap | Severity |
1717|-------+-------------------------------------------------------------------------------------------------------------+----------|
1818| Audit | The hash chain is unkeyed, so whoever can write the database can edit a row and recompute every later hash; removing the newest audit rows, or writing new rows under their freed ids, needs no recomputing at all. Neither is detectable from the database; only comparing =gitbayd admin audit verify='s last id and hash with the daemon's journal shows it. Rows written by =gitbayd shell= (=ssh.mode = "system"=) and host admin commands have no journal copy, and the refusal caps are per process, so under that mode each connection counts separately | low |
19| Access | Grants and parked profile about texts (=profile_about_backfill=) of deleted accounts and organizations, and deploy keys of deleted repositories, left by deletes before #306, are removed on upgrade and the "schema migrated" log line gives the counts. One whose id a later row had already taken is no longer an orphan and stays with that row; on gitbay.org the orphans found (two grants, one deploy key) name ids no later row had taken | low |
1920| Availability | Under =ssh.mode = "system"= each SSH session is a separate =gitbayd shell= process, so the pack-generation limit (=internal/packlimit=, #262) cannot count SSH clones across sessions; only HTTP and git:// share a budget there | low |
2021| Availability | Pushes have no concurrency limit; =max_pack_bytes= bounds each one, not how many run at once | medium |
2122| Availability | =repo download= (SSH, API) runs =git archive= outside the pack limit; only its two-minute deadline and 512 MiB cap bound it | low |
CHANGELOG.org +13
@@ -23,6 +23,19 @@ anything beyond "replace the binary and restart" is needed.
2323- A reply whose header has a field name outside RFC 5322 =ftext=
2424 (=From : x=), no single From, or a repeated To, Cc, Message-ID,
2525 Content-Type or Content-Transfer-Encoding is refused. (#307)
26- Ids of accounts, organizations, repositories, SSH keys, API tokens,
27 webhook deliveries, queued pushes and builds are no longer handed out
28 again after a delete. Before, the next row took the id of the newest
29 deleted one, with anything that still named it: a deleted account's
30 repository grants, a deleted repository's deploy keys, signed LFS and
31 reply-by-mail tokens, a runner's claimed build. The migration rebuilds
32 those tables and starts each sequence above every id still named
33 (#306).
34- Deleting an account or organization removes its repository grants
35 and its parked profile about text, and deleting a repository removes
36 its deploy keys. On upgrade, rows of these kinds left by earlier
37 deletes are removed, and the "schema migrated" log line gives how many
38 (#306).
2639
2740* v1.39.0 — 2026-09-29
2841