Ship an R2-only Cloudflare ciphertext receiver
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 30/100
- Tipo di issue
- Funzionalità
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Tranquilla
- Stack tecnologico
- typescript
- Ambito
- backend-api-design, cloud, security
Direzione di ricerca
Inizia controllando i blocker in #8 e #9, quindi leggi la documentazione referenziata su R2 Workers API, R2 consistency e Workers limits. Considera i criteri di accettazione come la checklist di completamento: streaming, validazione limitata, idempotenza atomica, ricevute sicure, gestione dei fallimenti, isolamento del deployment e logging non sensibile devono essere tutti dimostrati.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
Ship a deliberately narrow TypeScript Cloudflare Worker that accepts automatic Protocol v1 uploads and durably stores their ciphertext in R2.
The Worker is an untrusted, bounded ingress—not an enrollment, device-authentication, analysis, or management service. Its only successful mutation is creating an immutable R2 object and returning the matching receipt.
Requirements
Scope and trust boundary
- Expose one Protocol v1 upload
POSTroute. - Do not expose list, download, delete, admin, dashboard, configuration, participant, or management APIs.
- Do not use D1, Queues, KV, Durable Objects, a private decryption key, or any decrypt/parse path.
- Treat ingress as public and unauthenticated. A deploy-time allowlist may contain accepted configuration digests and researcher signer fingerprints, but these cleartext claims are not participant or device authentication.
- Fix the accepted protocol version, media type, header set, configuration allowlist, and R2 binding at deployment. Do not add remote configuration.
- Give researchers read access directly through least-privilege, S3-compatible R2 credentials outside the public Worker.
Request validation and streaming
- Reject every method, path, media type, transfer shape, or required header not defined by Protocol v1.
- Require and strictly parse
bundle_id,Content-Length, SHA-256Content-Digest, exact claimed sequence range, event count, configuration digest, and producer metadata defined by #8/#9. - Enforce a 32 MiB body hard limit before and while reading. Reject missing, conflicting, malformed, truncated, overlong, or trailing input.
- Stream the request
ReadableStreamdirectly into R2. Do not buffer the complete body in Worker memory. - Supply the expected SHA-256 to R2 so the durable object write itself validates content integrity.
- Use
bundle_idas the immutable R2 object key under a fixed deployment namespace. - Store bounded R2 custom metadata for ciphertext SHA-256, byte count, claimed range, claimed event count, configuration digest, producer platform/version, and receive time. Mark all routing metadata as untrusted claims.
Idempotency and receipts
- Use a create-only conditional R2 write so an existing
bundle_idcan never be overwritten. - After a successful durable new write, return
201 Createdwith a canonical receipt containing the exact stored identity, digest, size, range, event count, and configuration digest. - If the same ID already exists and its object checksum and metadata are identical, return
200 OKwith the identical receipt. - If the same ID exists with any different digest, size, or metadata, return
409 Conflict; never replace either object. - Handle concurrent identical or conflicting requests safely. Rely on R2 conditional writes and strong consistency, not a non-atomic read-then-overwrite sequence.
- Return no 2xx until R2 confirms durable persistence. A lost response followed by an exact replay must be safe.
Abuse and operations
- Provide a Wrangler deployment template with explicit bindings, secrets/configuration, routes, compatibility date, and environment separation.
- Configure or document Cloudflare WAF/rate limiting, a fixed request bound, deployment isolation, R2 lifecycle/retention policy, storage-budget alerts, and emergency ingress disablement.
- Log only bounded operational reason codes, response status, coarse timing, and non-sensitive aggregate sizes. Do not log participant UUIDs, configuration artifacts, raw headers, URLs containing secrets, or body bytes.
- Expose no claim of participant authenticity, device authenticity, enrollment, completeness, or decrypted validity in receipts or documentation.
Acceptance criteria
- A valid upload is streamed to R2 and returns
201only after the object is readable with the expected checksum and metadata. - Response loss followed by exact replay returns the same receipt with
200and creates no second object. - Concurrent exact duplicates yield one creation and safe replay responses; a same-ID content or metadata conflict yields
409without overwrite. - Wrong method/path/media type, malformed headers, digest mismatch, truncation, extra bytes, and bodies above 32 MiB fail without a durable object.
- Simulated R2 failure never returns 2xx.
- Worker-memory tests demonstrate that body handling does not buffer a full 32 MiB request.
- Deployment and log tests prove that the Worker has no R2 list/download/admin surface, no decrypt key, and no sensitive logging.
- Operational documentation explicitly describes ingress and all stored routing metadata as unauthenticated/untrusted.
Documentation
Add the upload/receipt contract, Worker threat model, Wrangler deployment guide, R2 naming/metadata specification, WAF/rate-limit/lifecycle runbook, retention/cost guidance, researcher S3 read-access guide, and incident procedures.
References: R2 Workers API, R2 consistency, and Workers limits.
Dependencies
Blocked by #8 (final Protocol v1) and #9 (durable exact-replay Android outbox).
- Lingua principale
- Kotlin
- Stelle
- 0
- Fork
- 0
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di JacobLinCool/particeps
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 38/100
JacobLinCool/particeps#33 · 2 commenti ·
-
area: ios P3
Difficoltà 5/5 Più di una settimana Idoneità per principianti 25/100
JacobLinCool/particeps#21 ·
-
area: ios area: protocol P3
Difficoltà 5/5 Più di una settimana Idoneità per principianti 25/100
JacobLinCool/particeps#20 ·
-
area: collector P2
Difficoltà 5/5 Più di una settimana Idoneità per principianti 30/100
JacobLinCool/particeps#18 ·
-
Add gyroscope.v1Apertaarea: collector P2
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
JacobLinCool/particeps#17 ·
Tutte le issue di JacobLinCool/particeps
Issue simili
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
navikt/mock-oauth2-server#1129 ·
I maintainer di solito rispondono entro 1 giorno
-
Expose `close` on SsrEngineAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 77/100
-
unconfirmed
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
thunderbird/thunderbird-android#11778 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
world-federation-of-advertisers/cross-media-measurement#4709 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
I maintainer di solito rispondono entro 1 giorno