Optional: sound per-identity write-rate limiting (post-verification), if a need appears
- Dominant language
- Rust
- Stars
- 3
- Forks
- 0
- Avg merge
- 1d 42m
- Merged PRs (30d)
- 11
Description
## Summary
The server currently has no per-identity write-*rate* limit — writes are bounded by a per-IP rate limit, a per-identity total-*count* quota, and request-size caps. This issue records a sound design for adding per-identity rate limiting *if a future need appears*, so the decision (deliberately deferred, not overlooked) stays visible.
## Background
An earlier draft of the resource fence included a per-principal rate limit, but it keyed on the principal identifier read from the request body **before** signature verification. That identifier is public and attacker-nameable, so an unauthenticated attacker could name a victim's identifier in a flood of garbage and drain the victim's write allowance — a zero-cost targeted denial of service. It was removed rather than shipped.
## Why it isn't needed today
The surviving fences cover the MVP's actual threats:
- anonymous floods from one source → per-IP rate limit (keyed on the real transport peer, un-spoofable);
- total storage exhaustion per identity → the durable count quota;
- oversized bodies → request-size caps;
- a compromised key making valid writes as a victim → handled by revocation (the naked-revoke path), not by rate limiting.
The only threat a per-identity rate limit uniquely addresses is a *legitimately signed* write stream from one identity, at high **rate**, spread across many IPs, while staying under its total count quota — a QoS/fairness concern more than a hard denial of service, since the total is already bounded by the quota.
## The sound design, if it's wanted later
The DoS came from keying on an *unauthenticated* identity. The fix is to only rate-limit an *authenticated* one:
- **Preferred — rate-limit after signature verification.** The expensive work worth protecting is the storage commit (write + history replay); signature verification is comparatively cheap. Verify the signature first (that authenticates the identity), then apply the per-identity rate limit, then do the storage work. Garbage with a forged identity fails verification and never reaches the rate check, so it cannot touch a victim's bucket. No extra mechanism needed — the write's own signature is the possession proof.
- **Only if verification CPU itself must be gated — add proof-of-possession.** A cheap challenge proving the client holds the private key, checked before full verification. Worth it only if signature-checking becomes a bottleneck (unlikely at MVP scale; the per-IP limit already bounds the single-source flood that would cause it).
Either way the key must be the *authenticated* principal, never an identifier read from an unverified body.
Contributor guide
No contributing guide indexed for this repository
Research direction
No files, tests, or entry points are named; start by locating the server's signature-verification, per-IP limiting, quota, and storage-commit paths. The issue's stated design is to authenticate the identity before applying a per-identity rate limit, with implementation deferred until a future need appears.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- backend-api-design, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100