docs: FoF-gating spec skeleton (hand-off to Opus)
Drafts the Friend-of-Friend post-gating spec with crypto specifics marked TBD — OPUS for Opus to fill in. Six-layer implementation plan; each layer independently shippable. Includes README overview + six layer files: - Layer 1: V_me vouch primitive (keys, keyring, VouchGrant wire format) - Layer 2: Mode 2 — public post + FoF-gated comments - Layer 3: Mode 1 — FoFClosed (encrypted body via wrap_slots + prefilter) - Layer 4: per-post keypair rotation - Layer 5: unlock cache + prefilter optimization (perf-critical) - Layer 6: revocation (stub; likely deferred post-v1) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d118daee28
commit
1fdf9a94cc
8 changed files with 867 additions and 0 deletions
94
docs/fof-spec/layer-6-revocation.md
Normal file
94
docs/fof-spec/layer-6-revocation.md
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
# Layer 6 — Revocation & Rotation Cascades
|
||||
|
||||
**Status**: Stub. May not be in v1. Drafted for design review only.
|
||||
|
||||
**Scope**: Mechanism for a persona to un-vouch a specific vouchee without rotating `V_me` (which affects everyone), and for cascading rotations when a down-chain vouchee is un-vouched.
|
||||
|
||||
---
|
||||
|
||||
## The problem
|
||||
|
||||
In Layers 1–5, the only way to revoke a vouch is to rotate `V_me` and re-distribute to every remaining vouchee. This is:
|
||||
|
||||
- **Coarse**: rotates everyone to remove one.
|
||||
- **Expensive at scale**: O(remaining_vouchees) DM sends.
|
||||
- **Traceable**: observers can't see who, but a flurry of DMs hints at a change.
|
||||
- **Cascading**: if Alice rotates her `V_me`, every FoFClosed post Alice authored that was open to "friends" was open under `V_alice_old`; new readers on the updated `V_alice_new` can't decrypt old posts. Post-level Layer 4 rotation fixes this only if the author re-wraps every post under the new set.
|
||||
|
||||
Layer 6 is where we explore whether any of these frictions is worth addressing, and at what cost.
|
||||
|
||||
---
|
||||
|
||||
## Out of scope for v1
|
||||
|
||||
Without Layer 6, here's what breaks vs. what holds:
|
||||
|
||||
- **Holds**: FoF gating works. Revocation works (via coarse `V_me` rotation). Privacy properties intact.
|
||||
- **Breaks**: surgical un-vouch. If Alice wants to remove Bob but keep Charlie, she must rotate `V_alice`, re-give to Charlie. If she has 50 vouchees, that's 49 re-grants. Probably tolerable for a social-graph change that's inherently rare. Sharp corner only at large vouchee fanout.
|
||||
|
||||
Lead leaning: **v1 ships without Layer 6**. Revocation is via coarse `V_me` rotation. Revisit after usage data shows whether surgical revocation is load-bearing.
|
||||
|
||||
---
|
||||
|
||||
## Candidate designs (if we do Layer 6 later)
|
||||
|
||||
### Candidate A: Revocation List signed by voucher
|
||||
|
||||
Voucher publishes `(revoked_vouchee_id, since_epoch)`. Readers exclude posts whose `vouch_mac` identifies a chain through a revoked vouchee.
|
||||
|
||||
Drawbacks:
|
||||
- Requires `vouch_mac` to be public (not just for author strict mode).
|
||||
- Publishes the social graph — the thing we worked to keep private.
|
||||
- Non-starter without Zero-Knowledge proofs.
|
||||
|
||||
### Candidate B: Per-vouchee key derivation
|
||||
|
||||
Instead of one `V_me`, derive a per-vouchee key `V_me_bob = HKDF(V_me_master, bob_id)`. To revoke Bob, rotate `V_me_master` (affects everyone again — same problem).
|
||||
|
||||
Alternative: author re-wraps posts under `V_me_current \ {V_me_bob}`. This is per-post rotation (Layer 4) with deliberate exclusion. Feasible but requires the author to know which slot was Bob's — which breaks anonymous wrap slots.
|
||||
|
||||
### Candidate C: Forward-secrecy ratchet
|
||||
|
||||
`V_me` ratchets forward on a cadence. Old vouchees retain access to content encrypted before revocation; lose access to new. Avoids explicit revocation. Close to Signal's group ratchet.
|
||||
|
||||
Complexity is significant. Would require a per-persona state machine, out-of-band sync of current epoch between persona's devices, etc.
|
||||
|
||||
### Candidate D: Accept the coarse rotation
|
||||
|
||||
Acknowledge `V_me` rotation IS the revocation primitive. Smooth the UX:
|
||||
- UI: "Remove Bob from your Friends" → warns "This will re-distribute your Friends key to your other 49 Friends."
|
||||
- Background rotation task handles the N DMs.
|
||||
- Existing FoFClosed posts don't auto-re-wrap (remain under old `V_alice`). Author can opt to re-wrap specific posts via Layer 4.
|
||||
|
||||
Lead leaning: **Candidate D**. The "problem" is mostly UX friction, addressable with good affordances.
|
||||
|
||||
---
|
||||
|
||||
## Open design questions (deferred)
|
||||
|
||||
- Is there user demand for surgical revocation that doesn't rotate everyone?
|
||||
- What's the actual fanout distribution? If p95 vouchee count is <20, coarse rotation is a ~20-DM operation — tolerable.
|
||||
- Does Candidate D's UX feel heavy enough that users avoid revoking at all? (Anti-pattern: graph accumulates stale vouches.)
|
||||
- For Mode 2 (public posts with FoF comments), revocation has different urgency — author cares about who can still COMMENT, not about access to past content. Is surgical comment-only revocation simpler? (Hint: Layer 4 rotation on a specific post already does this coarsely — rotate `priv_post`, re-wrap under the narrowed set.)
|
||||
|
||||
---
|
||||
|
||||
## What Layer 6 should deliver IF we build it
|
||||
|
||||
Not decided. Placeholder:
|
||||
|
||||
- A defined revocation primitive (candidate selected).
|
||||
- Cascading / not-cascading behavior specified.
|
||||
- UI surface consistent with Layers 1–5.
|
||||
- Does NOT introduce per-vouchee public identifiers in any wire format.
|
||||
|
||||
---
|
||||
|
||||
## Decision point
|
||||
|
||||
**Revisit after Layers 1–5 ship and 30 days of production usage.** Signals that would move Layer 6 into scope:
|
||||
- p95 vouchee count > 50 (coarse rotation cost meaningfully high).
|
||||
- User reports of "I want to remove X but not everyone."
|
||||
- Privacy audit finding that the DM-flurry of coarse rotation leaks social-graph change timing.
|
||||
|
||||
Absent those, Layer 6 stays deferred.
|
||||
Loading…
Add table
Add a link
Reference in a new issue