API-70Required
Check access when the connection opens and while it lasts
Sign the client in during the handshake, as for any request. Check permission for each channel it joins and each message it sends. Close the connection when its session ends.
How to do it
A WebSocket or event stream can stay open for hours, long after a password change or a removal from a team. Keep the session ID with each connection. When sessions end on an access change, close its connections too, with WebSocket close code 1008. Recheck the session at least every 5 minutes, in case an event was missed. Check permission on every subscribe and every incoming message, never only once at connect. Browsers send cookies with a WebSocket handshake, so also check the origin. Keep tokens out of the address, as keep secrets out of addresses says.
Examples
JavaScript example
const POLICY_VIOLATION = 1008;
socket.on('message', async raw => {
const message = parseMessage(raw);
if (!(await canAccess(connection.userId, message.channel))) return socket.close(POLICY_VIOLATION, 'forbidden');
await handle(connection, message);
});
sessionEvents.on('ended', sessionId => {
for (const socket of socketsBySession.get(sessionId) ?? []) socket.close(POLICY_VIOLATION, 'session ended');
});
Python example
POLICY_VIOLATION = 1008
async def handle_socket(websocket, session):
async for raw in websocket:
message = parse_message(raw)
if not await can_access(session.user_id, message.channel):
await websocket.close(POLICY_VIOLATION, "forbidden")
return
await handle(session, message)
How to check
Connect as a test user and subscribe to another shop's channel. The server refuses it. Disable the test user as an admin. The open connection closes within 5 minutes.
Sources
Related rules
- End sessions when access changes in Accounts
- Check the origin of WebSocket connections in Security testing
- Keep secrets out of addresses in API design
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/api-design/live-connections/connection-access">Agent Wranglers API design playbook</a>. In code you write, add a comment next to it with the same link.