feat(intake): global submission ceiling with an abuse alert #227

Closed
opened 2026-08-29 09:03:12 -05:00 by bermudalamb · 0 comments
Owner

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

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
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bermudalamb/redefined-designs#227