Skip to content

Design: responsible anonymous comment submission (no required auth) #85

Description

@Ndevu12

Context

Comments are being made persistent + moderated (see branch feat/dashboard-tags-comments). The current implementation lets readers submit anonymously — no auth, and authentication is not required. That is a deliberate product stance (low friction, more engagement), but it needs a proper design so open submission stays trustworthy.

This issue is to think through how to do anonymous comment submission responsibly — not to force logged-in accounts.

Risks with open/anonymous submission

  1. Spam / bots — automated junk.
  2. Impersonation — anyone can type any display name (including the blog author's or a known person's).
  3. Abuse — offensive content with no accountability.
  4. Moderation load — if every comment needs a human, it doesn't scale.
  5. Privacy — collecting email from strangers is PII we may not want to store.

None of these require login to mitigate — they're design levers we can dial.

Design levers

Moderation model

  • All comments pending → admin approves (current behaviour). Safest, but every comment needs review.
  • Auto-publish + report/remove after the fact. Lower friction, riskier.
  • Trusted fast-lane: first comment moderated; once approved, a signed cookie/token lets that commenter's later comments auto-publish. Good middle ground for a small blog.

Spam defense (all no-auth, low-friction)

  • Honeypot field + minimum time-to-submit (kills naive bots for free).
  • Rate limit per IP / session; store a hashed IP, not raw.
  • Lightweight content heuristics (link count, keyword / URL blocklist).
  • Optional invisible captcha (Cloudflare Turnstile / hCaptcha) for a hard wall — near-zero user friction.

Identity without accounts

  • Email optional, never displayed — used only for optional reply notifications / Gravatar.
  • Reserve author/admin display names so nobody can impersonate the author; label everyone else "guest".
  • Keep the door open: if a user happens to be signed in (admin today, readers later), attribute + auto-approve — but never require it.

Proposed baseline

Anonymous allowed · name required, email optional · comments moderated by default with a trusted fast-lane after first approval · spam-hardened (honeypot + min-time + hashed-IP rate limit + link heuristics) · author display name reserved · hashed IP for abuse control, minimal PII. Add Turnstile only if a strong wall is wanted.

Open decisions

  • Moderation: everything-pending, or moderate-first-then-trusted-fast-lane?
  • Email: optional (lean), required, or drop entirely for privacy?
  • Spam wall: heuristics-only, or add invisible captcha (Turnstile / hCaptcha)?
  • Abuse / rate-limit: OK to store a hashed IP + a per-post "disable comments" switch?

Known gaps in the current implementation (to fix as part of this)

  • The public comment form requires email but the backend RPC treats email as optional — mismatch to reconcile.
  • No spam hardening yet (no honeypot, rate limit, heuristics, or captcha).
  • No impersonation guard (author display name is not reserved).
  • No abuse controls (no IP handling, no per-post disable).

Current state (for reference)

  • Migration supabase/migrations/20260717000200_blog_comments.sql: blog_comments table (status pending/approved/spam), RLS locked to RPCs, public submit + approved-list, admin list/counts/set-status/delete.
  • Public UI wired in src/features/comments/*; admin moderation queue at /dashboard/comments.

Once the four decisions above are settled, the rework touches the migration (spam fields, hashed IP, trusted token), the RPCs (spam checks + fast-lane), and the form/UI.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions