DEV Community

Auth By Example
Auth By Example

Posted on

A long-lived stream is not a standing permission grant

SSE and WebSocket handlers often authorize once when the connection opens, then push events for minutes or hours. That first check is not a standing grant.

While the stream is open, membership can be revoked, a role narrowed, or the resource moved out of the subject's scope. If you only gate the handshake, later events can leak data the subject is no longer allowed to see.

Re-authorize before sensitive payloads leave the server—on a short interval, on each privileged event type, or when the subject's session/membership version changes. Close the stream when the check fails.

A connection lifetime is not a permission lifetime. Authorization still belongs at the moment of access.

Top comments (1)

Collapse
 
sinarezaei profile image
Sina Rezaei •

This is a good distinction between connection authentication and ongoing authorization.

I’ve seen the same problem with SSE streams in multi-tenant systems. A user opens /events while they have access to tenant A, then their membership or role changes. If the server only validates the JWT when the stream is created, the existing connection can keep receiving tenant events based on stale authorization.

That’s where checking the current membership/version at the event boundary becomes important. The token proves who opened the stream, but it shouldn’t automatically become a permanent permission grant for everything the stream emits later.