Access Control
itty-sockets supports two types of keys that control who can do what on a channel.
Join Key
A join key is required to connect to a channel. Without the correct key, the connection is rejected with a 403.
// channel requires a join key
connect('myapp:private', {
joinKey: 'correct-key', // ✓ connected
})
connect('myapp:private', {
joinKey: 'wrong-key', // ✗ 403 rejected
})
connect('myapp:private') // ✗ 403 rejectedSend Key
A send key controls who can send messages. Clients without the send key can still listen — they just can't broadcast.
// channel has a send key
const writer = connect('myapp:feed', {
sendKey: 'write-pass', // can send messages
})
const reader = connect('myapp:feed') // can listen, can't send
writer.send('breaking news') // ✓ sent
reader.send('hello') // ✗ error, no send keyThis is perfect for broadcast-style channels like live feeds, notifications, or dashboards where one source publishes and many clients listen.
Key Sources
Keys can come from two sources, with different behaviors:
Namespace Keys
Set via the Reservations dashboard. These apply to all channels under your namespace and can't be overridden by clients.
Ephemeral Keys (Open Channels)
On channels without a namespace reservation, the first client to connect can set their own keys:
// first joiner sets the rules
connect('my-room', {
joinKey: 'secret',
sendKey: 'writer-pass',
})
// now everyone else needs the joinKey
connect('my-room', { joinKey: 'secret' }) // ✓
connect('my-room') // ✗ rejectedThese keys are ephemeral — they last only as long as the channel exists. When the last user disconnects, the channel is destroyed and the keys are gone.
Important: If a namespace reservation exists for a channel, ephemeral keys are blocked. The namespace owner's config always wins.
Config Priority
- Most specific namespace — e.g.
myapp:privatewins overmyapp - Parent namespace — default keys for all channels under the namespace
- Ephemeral (first joiner) — only for open channels with no namespace match
- None — fully open, anyone can join and send
Next: Recipes — common patterns and real-world examples.