The per-link controls in #222 each bound one link. Nothing bounds the whole intake surface, and nothing tells anyone that something is wrong.
Why the per-link controls are not enough
A default cap of 25 per link bounds each link, but links accumulate — twenty links is five hundred submissions with nobody having decided that. The per-IP rate limiter is in-memory and per-address, so it is bypassed by using more addresses. Revoking a link works, but only once someone has noticed, and the current design gives nobody any reason to look.
Scope
A circuit breaker counting submissions across every link over a rolling 24 hours. Past the ceiling, intake refuses with a 503 that says to try again later — submissions stop, and the storefront, checkout and admin are untouched. Recovery is automatic as the window rolls, with a manual reset from the admin.
An alert email to the admin when the ceiling is hit, and when a single link crosses a threshold well below it — the second is the one that catches a leaked link early, which is the case the whole revoke mechanism exists to handle and currently depends on luck to trigger.
Notes
sendMail already exists and can be used directly. This does not need the editable-template system from #224, and should not wait for it — an abuse alert is not copy anyone will want to reword.
The alert must be rate limited against itself. An alert per submission during an incident is how a mailbox gets filled and the signal gets lost.
Count from item_drafts.created_at rather than a new counter. The rows already exist and a separate tally is a second thing that can be wrong.
The ceiling must never apply to the admin upload path. Intake being throttled is an inconvenience; the shop being unable to add stock is an outage.
The per-link controls in #222 each bound one link. Nothing bounds the whole intake surface, and nothing tells anyone that something is wrong.
## Why the per-link controls are not enough
A default cap of 25 per link bounds each link, but links accumulate — twenty links is five hundred submissions with nobody having decided that. The per-IP rate limiter is in-memory and per-address, so it is bypassed by using more addresses. Revoking a link works, but only once someone has noticed, and the current design gives nobody any reason to look.
## Scope
A circuit breaker counting submissions across every link over a rolling 24 hours. Past the ceiling, intake refuses with a `503` that says to try again later — submissions stop, and the storefront, checkout and admin are untouched. Recovery is automatic as the window rolls, with a manual reset from the admin.
An alert email to the admin when the ceiling is hit, and when a single link crosses a threshold well below it — the second is the one that catches a leaked link early, which is the case the whole revoke mechanism exists to handle and currently depends on luck to trigger.
## Notes
- `sendMail` already exists and can be used directly. This does not need the editable-template system from #224, and should not wait for it — an abuse alert is not copy anyone will want to reword.
- The alert must be rate limited against itself. An alert per submission during an incident is how a mailbox gets filled and the signal gets lost.
- Count from `item_drafts.created_at` rather than a new counter. The rows already exist and a separate tally is a second thing that can be wrong.
- The ceiling must never apply to the admin upload path. Intake being throttled is an inconvenience; the shop being unable to add stock is an outage.
Depends on #222. Part of #220
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The per-link controls in #222 each bound one link. Nothing bounds the whole intake surface, and nothing tells anyone that something is wrong.
Why the per-link controls are not enough
A default cap of 25 per link bounds each link, but links accumulate — twenty links is five hundred submissions with nobody having decided that. The per-IP rate limiter is in-memory and per-address, so it is bypassed by using more addresses. Revoking a link works, but only once someone has noticed, and the current design gives nobody any reason to look.
Scope
A circuit breaker counting submissions across every link over a rolling 24 hours. Past the ceiling, intake refuses with a
503that says to try again later — submissions stop, and the storefront, checkout and admin are untouched. Recovery is automatic as the window rolls, with a manual reset from the admin.An alert email to the admin when the ceiling is hit, and when a single link crosses a threshold well below it — the second is the one that catches a leaked link early, which is the case the whole revoke mechanism exists to handle and currently depends on luck to trigger.
Notes
sendMailalready exists and can be used directly. This does not need the editable-template system from #224, and should not wait for it — an abuse alert is not copy anyone will want to reword.item_drafts.created_atrather than a new counter. The rows already exist and a separate tally is a second thing that can be wrong.Depends on #222. Part of #220