Commit Graph
4 Commits
Author SHA1 Message Date
JMR-devandClaude Opus 4.8 80db59d9f1 Correct privacy doc status after #7/#8/#2 merged to main
Bring docs/privacy.md's implementation status current with main, which now
includes the ingest endpoint (#7), the scrub library (#8), and the Pulumi
infra (#2).

- Stop claiming the ingest endpoint is unimplemented: POST /v1/reports (size
  cap, v1 schema validation, and the 202/400/413/415/405/503 contract) and the
  PII-scrub library are now implemented in the repo.
- Replace the granular per-stage status table with one concise
  "Current implementation status" note that is less prone to going stale.
- Keep the honest nuance: the endpoint is wired to a no-op sink, so accepted
  reports are not yet retained, scrubbed in-line, encrypted, or published;
  scrub is not yet invoked on the live path. Encrypted storage (#9), lifecycle
  (#10), manual removal (#11), cron (#13), and publish (#14/#15) remain not yet
  built, and the edge rate-limit ruleset is reserved but not yet provisioned.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 14:47:43 -05:00
JMR-devandClaude Opus 4.8 cb1b6536f2 Document data flow & privacy posture (#12)
Add docs/privacy.md describing the end-to-end bug-report pipeline and its
privacy posture, so it can be linked from LibreMail's README / F-Droid
metadata.

Covers: opt-in / user-initiated-only submission; HTTPS ingest (POST
/v1/reports, size-limited, validated); best-effort PII scrub and its
documented limits; encrypted-at-rest R2 storage (AES-256-GCM, key in
Cloudflare Secrets Store); manual review/removal window; and the weekly
publish to GitHub. States plainly that scrubbing is best-effort (not a
guarantee) and marks stages that are designed but not yet implemented.

Links ADR #5 (encryption) and ADR #6 (labels/abuse).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 14:47:43 -05:00
Jason RossandClaude Opus 4.8 e93b6a2266 Add encryption ADR: Worker-side AES-256-GCM + Secrets Store key custody (#19)
Documents the decision for #5: Worker-side authenticated encryption (AES-256-GCM) applied in the Worker before writing to R2, so R2 never receives plaintext or the key. Key material is held as a versioned keyring in Cloudflare Secrets Store (shared by the ingest and weekly-publish Workers). Rotation is data-loss-free via a key-id/version in each object header plus retained old key versions. Unblocks #9.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 13:17:15 -05:00
Jason RossandClaude Opus 4.8 041c7758c1 #6 Decision: GitHub labels + abuse/rate-limit policy ADR (#18)
Add docs/decisions/labels-and-abuse.md fixing concrete values that unblock
#14 and inform #7:

- Labels on auto-published issues (JMR-dev/LibreMail): bug-report, automated,
  needs-triage. #14 must create any missing.
- Ingest policy: 256 KiB payload cap (413); per-IP 15/60s + 100/1h rate limits
  (429 + Retry-After) via Cloudflare Rate Limiting rules in Pulumi; full
  response-code contract (202/400/413/415/405/429/5xx).
- Weekly publish job: 50 issues/run cap; serial creation, 1s spacing,
  Retry-After honoured, exponential backoff (base 1s, cap 60s, jitter,
  max 5 attempts), mark-published-on-confirm de-dup.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 13:13:39 -05:00