Skip to content

[Realtime] SSE presentation fanout has no per-user/session/audience scoping #538

Description

@cssbruno

Current Behavior

The SSE presentation fanout has no per-user / per-tenant / per-session / per-room audience scoping. The hub registry is keyed only by channel and every payload is sent to every connected client:

// runtime/contracts/sse/sse.go
clients map[chan []byte]bool          // lines 21-25 — no user/session/topic key

for client := range hub.clients {     // lines 118-125
    select { case client <- payload: default: }
}

The fanout interface itself carries no audience parameter, and EventEnvelope has no user/session/audience field:

// runtime/contracts/types.go:148-150
SendPresentationEvents(context.Context, []EventEnvelope) error
// EventEnvelope (lines 53-59): ID, TraceParent, Category, Type, Value  -- no audience

Existing mitigations (why this is scoped, not unbounded):

  • Event-type scoping: the generated wrapper forwards only events whose Type is in the bound subscription set + query-invalidation (internal/appgen/source_realtime.go:398-439). This is topic-scoped, not user-scoped.
  • Connection-level guards: the /_gowdk/realtime/events handler runs runGuards and route-matched realtimeStreamGuards before streaming (source_realtime.go:312-387). This gates who may connect, not which events they receive.

So any user-specific presentation payload of a subscribed type is delivered to every authenticated client connected to that stream.

Expected Behavior

There should be a way to scope a presentation event to an audience (user/tenant/session/room) so that applications emitting user-specific payloads don't leak them to other connected clients. E.g. an audience/topic field on EventEnvelope (or a fanout method that takes a target), with the hub filtering delivery accordingly.

Evidence

  • runtime/contracts/sse/sse.go:21-25,118-125
  • runtime/contracts/types.go:53-59,148-150
  • internal/appgen/source_realtime.go:398-439 (type-scoping), :312-387 (connection guards)

Impact

High (security/privacy) for any app that emits user-specific presentation payloads. Currently safe only for globally-public events; the framework offers no primitive to scope otherwise.

Metadata

Metadata

Assignees

No one assigned

    Labels

    realtimeRealtime transport and live update worksecuritySecurity hardening and security-sensitive behavior

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions