Storage add-on: per-user 10 GB increments via Kanidm attribute + per-user quota #185
Etiketter
Inga etiketter
area/backups
area/ci
area/control-panel
area/identity
area/infra
area/observability
area/payments
area/security
area/storage
area/web
blocked
needs-info
needs-triage
ready-for-implementation
type
bug
type
chore
type
docs
type
epic
type
feature
type
task
wontfix
Ingen milstolpe
Inget projekt
Inga tilldelade
1 deltagare
Notiser
Förfallodatum
Inget förfallodatum satt.
Beroenden
Inga beroenden satta
Referens
bitborg/bitborg-infra#185
Läser in…
Hänvisa till i nytt ärende
Ingen beskrivning angiven.
Ta bort grenen "%!s()"
Borttagning av en gren är permanent. Även om den borttagna grenen kan fortsätta existera en kort tid innan den faktiskt tas bort, kan det INTE ångras i de flesta fall. Vill du fortsätta?
Follow-up to #184 (LFS included / single shared 10 GB
paidquota). The paid storage add-on was deferred there — this issue is its design + build.Requirement
Paying users can buy unlimited extra storage in 10 GB increments (not a single fixed add-on).
Why it can't be groups
Forgejo assigns quota via group membership only (no per-user rule assignment) and merges overlapping rules most-permissively (the reason #125 needed the two-rule split). So "base + N×10 GB" cannot be N stacked add-on groups that sum. The only Forgejo-native way to give each user an arbitrary total is a per-user group + per-user
size:allrule whose limit the reconciler computes =10 GiB × (1 + increments).Design
group_vars— operator decision 2026-07-21). Needs Kanidm schema work (a custom attribute on the person) + the reconciler reading it viaGET /v1/person/<user>.paid-<user>group +size:allrule at the computed limit and assign the user; when the count returns to 0, move them back to the sharedpaidgroup and delete the per-user group/rule (self-healing).Also in scope — Kanidm cleanup
kanidm-provisionis additive and never pruned the now-unused groups. Delete from the live instance:ent_lfs,ent_lfs_large,ent_storage(kanidm group delete), and drop them from the provisioning state if still referenced.Relates: #184; epics bitborg-docs#5 (payments), #26 (pricing enforcement).
The Kanidm-attribute half of this issue is not implementable
Verified while researching identity architecture for ADR 0040.
This issue proposes per-user 10 GB increments "via Kanidm attribute". Kanidm has no admin-facing
schema extension, so there is no supported way to add a custom per-user attribute:
/scim/v1/Class,/scim/v1/Attribute) are registered GET-only.scim_schema_class_listandscim_schema_attribute_list.schemaverb offers onlyclass list|searchandattribute list|search.memory, which makes runtime user-defined schema less likely rather than more.
The upstream request is kanidm#3493, open since
March 2025 with no milestone. Its own motivating example is, almost word for word, this use case:
setting up a per-user quota for a cloud service. A second request,
kanidm#256, has been open since 2020. Given that
history, this should not be planned around.
Kanidm also documents entry schema as an unstable API, so even if custom schema were reachable
by some unsupported route, it would not be a safe place for billing-relevant state.
What replaces it
Two options exist. Only one survives contact with the requirement.
Group per increment. OAuth2 claim maps can carry arbitrary operator-chosen values, but they are
keyed group to value, not user to value. So each distinct increment needs its own group
(
quota_increment_10gb,quota_increment_20gb, and so on). Values merge correctly when a user isin several such groups. Workable for a small fixed set. It does not scale to an arbitrary per-user
number, and it puts commercial state in the identity provider, which ADR 0040 has since decided
against.
Hold the number in the billing service. ADR 0040 moves entitlement authority out of the
identity provider. Under that decision a per-user storage increment is an integer column, and the
reconciler projects it onto a per-user Forgejo quota rule exactly as this issue describes. No
Kanidm attribute is required and no group-per-value proliferation happens.
The second is the direction ADR 0040 sets, and it is recorded there as a consequence.
Status of this issue
Leaving open. The capability is still wanted and the Forgejo half of this issue is unchanged: a
per-user quota rule is still the enforcement mechanism.
What needs rewriting when this is picked up is the source of the number. The title and body should
drop "via Kanidm attribute". Cross-repo sequencing is tracked separately.