Per-channel hashcash requirement for PRIVMSG (anti-spam) #12

Open
opened 2026-02-11 03:14:11 +01:00 by clawbot · 5 comments
Collaborator

Idea

Channels can set a hashcash proof-of-work requirement for sending messages, as a per-channel anti-spam mechanism.

How it works

  1. A channel operator sets a mode or key/value property specifying the required hashcash bits (e.g. +H 20 for 20 bits)
  2. Any PRIVMSG to that channel must include a valid hashcash token in the message meta field — same mechanism as signatures
  3. The hashcash token must contain:
    • Current date (prevents old token reuse)
    • Channel name (prevents cross-channel reuse)
    • Hash of the message body (binds the token to the specific message)
  4. Server validates the token before relaying the message
  5. Server caches spent tokens (e.g. 1 week TTL) to prevent replay attacks

Example

{
  "command": "PRIVMSG",
  "to": "#general",
  "body": ["hello world"],
  "meta": {
    "hashcash": "1:20:260210:#general:sha256(body)::abc123",
    "sig": "..."
  }
}

Rationale

  • Per-channel granularity — high-value channels can require higher cost, casual channels can be free
  • No central authority — channel operators decide their own spam policy
  • Composable with signatures — hashcash goes in meta alongside sig, same extensibility model
  • IRC-native feel — similar to channel modes like +m (moderated), but proof-of-work instead of voice
  • Self-regulating — during spam floods, operators raise the bits; during normal use, lower or disable

Implementation notes

  • Spent token cache can be a simple in-memory map with TTL, or a DB table with periodic cleanup
  • Token format follows standard hashcash spec with extensions for channel+message binding
  • Servers in a federation must each validate independently (tokens are per-server, not relayed)
  • Could be extended to DMs too (recipient sets their own hashcash requirement)

Not MVP — post-1.0 feature

Related to #11 (session creation hashcash). This is the per-message equivalent.

## Idea Channels can set a hashcash proof-of-work requirement for sending messages, as a per-channel anti-spam mechanism. ## How it works 1. A channel operator sets a mode or key/value property specifying the required hashcash bits (e.g. `+H 20` for 20 bits) 2. Any `PRIVMSG` to that channel must include a valid hashcash token in the message `meta` field — same mechanism as signatures 3. The hashcash token must contain: - Current date (prevents old token reuse) - Channel name (prevents cross-channel reuse) - Hash of the message body (binds the token to the specific message) 4. Server validates the token before relaying the message 5. Server caches spent tokens (e.g. 1 week TTL) to prevent replay attacks ## Example ```json { "command": "PRIVMSG", "to": "#general", "body": ["hello world"], "meta": { "hashcash": "1:20:260210:#general:sha256(body)::abc123", "sig": "..." } } ``` ## Rationale - **Per-channel granularity** — high-value channels can require higher cost, casual channels can be free - **No central authority** — channel operators decide their own spam policy - **Composable with signatures** — hashcash goes in `meta` alongside `sig`, same extensibility model - **IRC-native feel** — similar to channel modes like `+m` (moderated), but proof-of-work instead of voice - **Self-regulating** — during spam floods, operators raise the bits; during normal use, lower or disable ## Implementation notes - Spent token cache can be a simple in-memory map with TTL, or a DB table with periodic cleanup - Token format follows standard hashcash spec with extensions for channel+message binding - Servers in a federation must each validate independently (tokens are per-server, not relayed) - Could be extended to DMs too (recipient sets their own hashcash requirement) ## Not MVP — post-1.0 feature Related to #11 (session creation hashcash). This is the per-message equivalent.
clawbot self-assigned this 2026-02-20 09:29:40 +01:00
clawbot added the
needs-review
label 2026-02-20 09:29:40 +01:00
sneak added this to the 1.5 milestone 2026-02-27 05:13:34 +01:00
sneak modified the milestone from 1.5 to 1.0 2026-02-27 05:13:36 +01:00
clawbot removed their assignment 2026-03-01 15:24:42 +01:00
Author
Collaborator

@sneak This was assigned to clawbot but has no bot label. Unassigning — needs your ruling on whether agent work is desired here.

@sneak This was assigned to clawbot but has no `bot` label. Unassigning — needs your ruling on whether agent work is desired here.
sneak added the
bot
label 2026-03-01 15:26:27 +01:00
clawbot was assigned by sneak 2026-03-01 15:26:31 +01:00
Owner

@clawbot what's the status here? no progress for an hour?

@clawbot what's the status here? no progress for an hour?
Owner

@clawbot needs code review

@clawbot needs code review
Owner

also token cache should be a year

also token cache should be a year
Author
Collaborator

@sneak Same as #11 — no implementation exists yet (no PR, no branch, no hashcash code in the repo). Waiting for your answer on #11: should I implement both, or is there existing code I'm missing?

Noted: token cache TTL should be 1 year.

@sneak Same as [#11](https://git.eeqj.de/sneak/chat/issues/11) — no implementation exists yet (no PR, no branch, no hashcash code in the repo). Waiting for your answer on #11: should I implement both, or is there existing code I'm missing? Noted: token cache TTL should be 1 year.
Sign in to join this conversation.
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: sneak/chat#12
No description provided.