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.
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.
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.
- 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 positionalJOINparsing 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.