Commit Graph

3 Commits

Author SHA1 Message Date
Oliver Kieselbach fe9ffc3f67 fix(security): backend-review Lows — SignalR revoke enforcement, revoke audit integrity, casing
Revoke enforcement (L4): a revoked delegated (MSP) user kept receiving pushes on
already-joined SignalR groups until the connection dropped (join-time-only
authorization). Negotiate now goes through the Management SDK and binds the
client token to a SignalR user id (lowercased UPN); new DisconnectUserAsync
strips the user from all groups server-side and pushes "accessRevoked", on
which the web client restarts its connection so every re-join re-runs
authorization against the fresh scope. Wired into delegated revoke/disable and
tenant-group unassign / remove-tenant / delete-group. Residual (documented): a
tampered client ignoring the push, and connections negotiated before this
deploy (no user id), keep streams until the connection drops.

Revoke audit integrity (L5): POST /global/delegated-admins now requires a GUID
tenantId (mirrors the tenant-group path), and DELETE reports 404 for an
assignment that never existed instead of returning 200 and writing a false
customer-visible "access removed" audit row (repo delete now checks the 404
response of the idempotent DeleteEntityAsync).

Casing (L6): the SignalR group join/leave cross-tenant check now compares
tenant IDs OrdinalIgnoreCase, aligned with the middleware and the delegated
scope dictionary, so a casing difference can never flip which branch
authorizes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 16:06:39 +02:00
Oliver Kieselbach c91fd1a43e massive re-org and re-structuring 2026-03-06 03:02:19 +01:00
Oliver Kieselbach d532ffd7a4 massive re-org and re-structuring 2026-03-06 03:01:24 +01:00