feat(api): SSE stream for identity events at /api/v1/identities/events
Mirrors GET /api/v1/topologies/{id}/events: subscribes to identity.>
on the bus for the duration of the request and forwards each event as
a named SSE frame (formed / observation.linked / merged / unmerged).
The endpoint is broadly scoped (every identity event, not per-uuid)
because both AttackerDetail and IdentityDetail need the same
firehose: AttackerDetail watches for an identity.formed that finally
binds its identity_id; IdentityDetail watches for
observation.linked / merged / unmerged against its current row. A
per-uuid filter would force the client to know its identity before
subscribing, which it doesn't always.
JWT via ?token= (EventSource can't set headers), require_stream_viewer
gate, sse_connection_slot per-user cap, snapshot-on-connect with
the first 50 identities so the client buffer renders without a
separate REST call.
Bus-disabled / unreachable path keeps the connection alive on
keepalives so the client doesn't reconnect-storm; it can re-poll
the REST API on its own timer.
This commit is contained in:
@@ -24,6 +24,7 @@ from .attackers.api_get_attacker_intel import router as attacker_intel_router
|
||||
from .identities.api_list_identities import router as identities_list_router
|
||||
from .identities.api_get_identity_detail import router as identity_detail_router
|
||||
from .identities.api_list_identity_observations import router as identity_observations_router
|
||||
from .identities.api_events import router as identity_events_router
|
||||
from .transcripts import transcripts_router
|
||||
from .config.api_get_config import router as config_get_router
|
||||
from .config.api_update_config import router as config_update_router
|
||||
@@ -94,6 +95,7 @@ api_router.include_router(attacker_intel_router)
|
||||
api_router.include_router(identities_list_router)
|
||||
api_router.include_router(identity_detail_router)
|
||||
api_router.include_router(identity_observations_router)
|
||||
api_router.include_router(identity_events_router)
|
||||
|
||||
# Observability
|
||||
api_router.include_router(stats_router)
|
||||
|
||||
Reference in New Issue
Block a user