Skip to content

Latest commit

 

History

History
90 lines (73 loc) · 4.65 KB

File metadata and controls

90 lines (73 loc) · 4.65 KB

Shared-key channels

Status: implemented, pre-alpha; established-client matrix pending

IRC channel mode +k supplies a low-friction admission option between a fully public room and account-by-account private membership. It is a shared bearer secret, not a replacement for server admission, a durable role, or a secret channel mode.

Admission contract

The key is an optional condition layered over the channel's immutable base access policy:

Channel policy Admission requirement
public, no +k any connection admitted to the server
public +k an admitted connection presenting the current key
invite-only +i an authenticated account with a durable channel role
invite-only +ik a durable member presenting the current key

A key never bypasses required server authentication, an account ban, durable +i membership, or the live +l member limit. In a +ik room, INVITE grants the target account durable membership but neither reveals nor waives the key. Admission checks reject a ban or missing private membership before doing expensive key verification, and verify a key before exposing whether the room is at its live-member limit.

Successful key use is connection-scoped. It creates no durable membership, role, invitation edge, or key-use audit record. Every device and reconnect must present the key again. An anonymous connection may join a public keyed room when the server otherwise permits anonymous registration, but only an authenticated channel owner or operator may set, rotate, or clear the key.

This gives an invite-gated server a useful intermediate room: everyone still passes network onboarding, while a channel owner can share one phrase instead of granting every admitted account a channel role.

IRC behavior

The adapter accepts the traditional positional key list in JOIN, returns numeric 475 for either a missing or incorrect key, advertises k honestly in CHANMODES, and exposes the active mode through MODE #channel. Repeating JOIN for a connection already in the room remains an idempotent no-op and does not require the key again.

MODE #channel +k key sets or rotates the key. Both mode broadcasts and later 324 queries substitute * for the secret. MODE #channel -k * clears it; the required parameter follows the traditional type-B mode shape but is not compared with the current key. A malformed key supplied to +k receives 525.

Setting a new key either enables or rotates +k. Existing connections remain joined, while new and reconnecting clients need the new value. Clearing +k does not eject anyone. In a public room it deliberately lets any server-admitted connection join and retrieve the retained history; in a +i room the durable membership requirement remains.

Adding a key cannot retract content that clients already received. Removing a key can publish still-retained history to the room's underlying public access class. Documentation and native clients must make both transitions explicit.

+k is not the traditional secret mode +s. A public keyed room may remain visible through ordinary public discovery, although its messages, names, cursors, and history still require a successful JOIN. Operators who need account-backed membership and hidden discovery use an invite-only room.

Secret handling

  • Keys are 1 through 128 bytes of printable ASCII. Commas, a leading colon, and the reserved mask * are rejected before hashing so IRC framing and positional JOIN parsing stay unambiguous.
  • Store only a salted Argon2id verifier. Raw keys exist only while parsing, setting, or checking the command that supplied them.
  • Never write a raw key or verifier into application logs, authority audit values, or message history. Audit only the fact that a key was set, rotated, or cleared.
  • Mask later mode queries and channel-wide mode projection as *; the server must not retain reversible plaintext merely so a client can ask for it again. Exact established-client behavior belongs in the M7 client matrix.
  • Four concurrent Argon2 jobs are allowed per process. Failed checks add a bounded exponential delay to that connection; missing and incorrect keys share numeric 475 and create no durable attempt trail.

Channel history, read-marker, delivery-checkpoint, and legacy replay operations already require the requesting connection to be joined. The atomic key-aware JOIN gate therefore protects retained content without inventing a persistent key-derived entitlement or social graph. Verification happens outside the channel-policy mutation lock, followed by a revision-consistent read under the lock before membership is installed; a concurrent rotation cannot admit a stale successful check.