clusev/routes/channels.php

35 lines
1.8 KiB
PHP

<?php
use App\Models\User;
use Illuminate\Support\Facades\Broadcast;
/*
|--------------------------------------------------------------------------
| Broadcast Channels — CONVENTION: every channel is PRIVATE
|--------------------------------------------------------------------------
|
| Clusev is a control plane for a whole fleet; broadcast payloads (live CPU/MEM,
| service state, future per-server streams) are infrastructure data and must NEVER
| ride a PUBLIC channel. A public channel is subscribable by anyone who can reach the
| Reverb endpoint and knows the app key — and that key is bundled into the JS
| (VITE_REVERB_APP_KEY), so it is effectively public. With on-demand TLS the `/app/*`
| Reverb socket also answers on any host Caddy still holds a cert for (e.g. an old
| domain after a domain change), so a public channel would leak metrics on a host that
| PanelScheme otherwise refuses.
|
| RULE for new channels: declare every event with a PrivateChannel (or PresenceChannel)
| and register an authorization callback here. The `/broadcasting/auth` endpoint runs in
| the `web` group, so PanelScheme + the session guard gate it — a subscriber must be an
| authenticated panel user on the active domain. Per-server channels should additionally
| scope to records the user may see, e.g.:
|
| Broadcast::channel('server.{uuid}', fn (User $u, string $uuid) =>
| Server::where('uuid', $uuid)->exists()); // tighten when RBAC lands
|
*/
// Fleet-wide metrics. Only a panel user who has completed security onboarding (rotated the
// seeded password + enrolled 2FA) may watch — mere authentication is NOT enough; this mirrors
// the EnsureSecurityOnboarded gate on panel routes (metrics are not per-user).
Broadcast::channel('metrics', fn (User $user) => $user->securityOnboarded());