Cyphrme / Cyphrme/Cyphr

Optional: sound per-identity write-rate limiting (post-verification), if a need appears

Open
#127 0 comments 0 reactions 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.