Composition and lifecycle
Site relay is optional application infrastructure. No component set or server preset creates its runtime, mounts its routes, registers connector sites, publishes cooperative events, or builds a viewer portal. The server host, connected client, and browser application meet at explicit contracts.
The server host owns the broker and its perimeter
For connector-backed sites, create a gateway with the application's AppNode, initialize the site runtime, and mount the router behind the product's complete route authorization policy:
from fastapi import Depends
from servercheetah.features.sites.relay import (
CheetahConsoleSiteConnectorGateway,
create_cooperative_site_router,
initialize_cooperative_site_runtime,
)
gateway = CheetahConsoleSiteConnectorGateway(
app_node_provider=lambda: app_node,
)
site_runtime = initialize_cooperative_site_runtime(
app,
connector_gateway=gateway,
sharing_policy=site_sharing_policy,
)
app.include_router(
create_cooperative_site_router(
authenticated_user_dependency=require_user,
optional_authenticated_user_dependency=resolve_optional_user,
),
dependencies=[Depends(require_site_relay_route_access)],
)
require_user, resolve_optional_user, site_sharing_policy, and require_site_relay_route_access are application code. The outer dependency must implement the complete authorization decision described in Sessions and sharing; the router's two identity callbacks alone do not protect every session route.
The host must also route authenticated cooperative event messages through the feature wrapper:
from servercheetah.features.sites.relay import ingest_cooperative_site_message
result = await ingest_cooperative_site_message(
rest_node=rest_node,
runtime=site_runtime,
payload=payload,
user_id=authenticated_user_id,
)
Call await site_runtime.shutdown() during application shutdown so in-process loopback clients are closed. Replace the process-local state and event delivery when restart survival, several replicas, longer audit retention, or replay are requirements.
The connector owns local reachability
Create a CooperativeSiteConnectorService from normalized definitions. Include createCooperativeSiteRelayHandler(service) in the runtime's handler registry, its action descriptor in advertised actions, and service.advertisedSites() in client_metadata.cooperative_sites.
After the Cheetah connection is live, call registerCooperativeSites() with the authenticated API base URL, the same connector client ID, and the same site definitions. The helper silently does nothing when it cannot derive an API base URL or has no connector client ID; treat both values as required product configuration rather than relying on that permissive behavior.
Stop any local control server with the connector process. Local cookies live in the connector service's memory and disappear with it. Reconnect can restore the site advertisement and registration, but it does not restore those cookie jars or prove that an earlier local mutation completed.
The browser application owns the experience
The application lists permitted sites, opens a viewer session, and navigates or embeds the returned relay entry URL. It decides how to present disconnected sites, authentication failure, relay errors, revocation, and a local application that cannot operate below the relayed base path.
For cooperative sites, the optional web helper subscribes to events and invokes approved actions. The product still decides whether an action needs confirmation, how event invalidation refreshes the view, and what the viewer sees after a missed event or connector restart.
Deployment preserves all underlying Cheetah requirements
Connector-backed relay requires the App-facing role to see the same authenticated connection registry and retained history as the WebSocket and REST roles. In a multi-process deployment, use the same shared-component and role composition required for ordinary commands and RPC; a process-local registry cannot route to a connector owned by another process.
The site registry, session store, decision store, and event bus remain separate application concerns. The convenience runtime currently uses in-memory implementations even when the core Cheetah components use Redis. Do not infer distributed site-session coordination from distributed command dispatch.
Verify the complete relationship
A useful product-level check should prove:
- a connected client advertises the relay action and its site claim;
- authenticated registration binds the descriptor to that host and connector;
- an allowed viewer can open a session while a denied viewer cannot;
- every session route enforces the chosen authorization matrix;
- an allowed method and path reach only the configured origin and base path;
- an unexposed path or method is rejected;
- local cookies remain isolated between two sessions;
- close and revoke stop later relay, event, and action work;
- cooperative events reach the intended live subscriber and an allowed action returns a correlated result;
- restart and replica behavior match the selected state implementations.
products/sitewatch is the repository's small consumer application for the server, connector, and local site. It is useful implementation evidence and a place to study application glue. Its demo configuration and open development portal are not a production deployment template.
Return to Site relays and cooperative sites, or continue with Diagnostics and observability when the next concern is the live command and connector path.