fix(reconciler): enforce org quotas to close the org bypass (#121) #151

Sammanfogat
supernaut sammanfogade 1 incheckning från fix/121-org-quota in i main 2026-07-19 20:07:12 +00:00
Ägare

#121 part 2 — org quota enforcement

Orgs are separate quota owners the reconciler never touched (§4 was a TODO), so every org fell to [quota.default] = -1 = unlimited → a user could push unlimited data into an org and fill the shared 60 GB data volume (full-instance outage).

Change (roles/reconciler)

  • New ensure_size_group — creates a quota group with a single size:all rule (total cap over repos + LFS + packages; no base rule, so the cap isn't defeated by the most-permissive merge).
  • Ensures two org groups: org-default (size:all = 5 GiB, tenant orgs) and org-unlimited (-1, first-party/exempt orgs).
  • New §4: enumerate orgs via /api/v1/admin/orgs and assign each to its target group (exempt → org-unlimited, else → org-default), same idempotent add-to-target / remove-from-other pattern as users.
  • reconciler_org_exempt: ["bitborg"] — the platform's own org owns all the project repos and must not be capped. It's assigned to org-unlimited explicitly (not just skipped) so it also overrides the fail-closed default group from PR-C via the most-permissive merge.

Why 5 GiB

Orgs have no Kanidm tier signal and can have multiple owners, so a flat default is pragmatic; an org needing more gets a manual bump (rare, and org-create is now gated by PR-A).

Validation

ansible-lint (production) · --check --diff renders clean (0 failed) · bash -n on the new logic.
Runtime correctness (the admin/orgs JSON field + orgs being assignable to quota groups) will be confirmed by a dry-run at apply time: the reconciler logs org <name>: quota=<group> for every org before anything is applied — review that first, then let RECONCILE_APPLY proceed.

Apply/ordering note

Apply this before PR-C (DEFAULT_GROUPS = participant) so the gitborg org is already in org-unlimited and can't be caught by the fail-closed default. Confirm the first live run assigns bitborg → org-unlimited and pushes to the platform repos still work.

Refs #121.

## #121 part 2 — org quota enforcement Orgs are separate quota owners the reconciler never touched (§4 was a TODO), so every org fell to `[quota.default] = -1` = unlimited → a user could push unlimited data into an org and fill the shared 60 GB data volume (full-instance outage). ## Change (`roles/reconciler`) - New `ensure_size_group` — creates a quota group with a single `size:all` rule (total cap over repos + LFS + packages; **no** `base` rule, so the cap isn't defeated by the most-permissive merge). - Ensures two org groups: **`org-default`** (`size:all = 5 GiB`, tenant orgs) and **`org-unlimited`** (`-1`, first-party/exempt orgs). - New §4: enumerate orgs via `/api/v1/admin/orgs` and assign each to its target group (exempt → `org-unlimited`, else → `org-default`), same idempotent add-to-target / remove-from-other pattern as users. - **`reconciler_org_exempt: ["bitborg"]`** — the platform's own org owns all the project repos and must not be capped. It's assigned to `org-unlimited` explicitly (not just skipped) so it also overrides the fail-closed default group from PR-C via the most-permissive merge. ## Why 5 GiB Orgs have no Kanidm tier signal and can have multiple owners, so a flat default is pragmatic; an org needing more gets a manual bump (rare, and org-create is now gated by PR-A). ## Validation ansible-lint (production) · `--check --diff` renders clean (0 failed) · `bash -n` on the new logic. **Runtime correctness** (the admin/orgs JSON field + orgs being assignable to quota groups) will be confirmed by a **dry-run** at apply time: the reconciler logs `org <name>: quota=<group>` for every org before anything is applied — review that first, then let RECONCILE_APPLY proceed. ## Apply/ordering note Apply this **before** PR-C (`DEFAULT_GROUPS = participant`) so the `gitborg` org is already in `org-unlimited` and can't be caught by the fail-closed default. Confirm the first live run assigns `bitborg → org-unlimited` and pushes to the platform repos still work. Refs #121.
supernaut tvångsskickade fix/121-org-quota från 560866d318
Alla kontroller lyckades
ci / ci (pull_request) Successful in 2m29s
till 0b939838c6
Alla kontroller lyckades
ci / ci (pull_request) Successful in 2m31s
2026-07-19 20:00:39 +00:00
Jämför
supernaut sammanfogade incheckning cb6632ce61 till main 2026-07-19 20:07:12 +00:00
supernaut tog bort grenen fix/121-org-quota 2026-07-19 20:07:12 +00:00
Logga in för att delta i denna konversation.
Inga granskare
Ingen milstolpe
Inget projekt
Inga tilldelade
1 deltagare
Notiser
Förfallodatum
Förfallodatumet är ogiltigt eller utanför gränserna. Använd formatet "åååå-mm-dd".

Inget förfallodatum satt.

Beroenden

Inga beroenden satta

Referens
bitborg/bitborg-infra!151
Ingen beskrivning angiven.