Skip to content

Latest commit

 

History

History
107 lines (76 loc) · 14 KB

network.md

File metadata and controls

107 lines (76 loc) · 14 KB

Network traffic

What the router contacts, when, and how to turn it off. The router has no telemetry, crash reporting or analytics, and it turns off the telemetry of the ONNX Runtime library it uses for in-process embeddings (below). Every outbound connection is one of the destinations below, and most of them only exist because you configured them.

Destinations

What Destination When How to turn it off
Connectors The BaseAddress of each HTTP connector (api.anthropic.com, api.openai.com, a local model server, …) A request is routed to one of its models, the dashboard checks or discovers models, or doctor runs Disable or remove the connector, or its models
Embeddings Embeddings:Endpoint when the provider is OpenAICompatible Every classified prompt, and route warm-up Use Onnx, or a server on this machine
ONNX model download huggingface.co, which redirects the model file to its CDN (*.hf.co; the host is regional, e.g. us.aws.cdn.hf.co or cas-bridge.xethub.hf.co) Once, on the first start with Embeddings:Provider: Onnx and no model in models/{name} Copy a models/{name} directory into the local data directory (or set ModelPath); the download is then skipped. The files are pinned to a revision and checked by SHA-256; their sources and licences are in The embedding models
The answer judge One of your connectors (Middleware:Judge:Model) A sampled share of cheap answers, when Judge:Enabled is on (off by default) Leave Judge:Enabled off
Webhooks Each Notifications:Webhooks URL A notice appears or clears, and the weekly digest Remove the webhook
Subscription CLIs (claude, codex, copilot) and the Copilot SDK connector Their vendor's API, from the vendor's own process A request is routed to one of their models, or doctor runs Disable the connector. The router starts Claude Code with DISABLE_AUTOUPDATER=1 and CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 and Copilot with --no-auto-update, so a run makes no update, telemetry or error-reporting requests. Codex is started with -c check_for_update_on_startup=false -c analytics.enabled=false -c otel.metrics_exporter="none" (and --ignore-user-config), so it checks for no update and sends OpenAI no analytics or metrics
The dashboard's setup scan Their vendor's API, from a claude, codex or copilot CLI found on PATH, even when no connector uses it The dashboard looks for models on this machine: on the Overview while no model is enabled, and when the Add connector menu or an empty Connectors page shows presets. It runs each CLI's --version, and claude auth status or codex login status; a result is reused for 30 seconds Offline mode, or a machine policy that turns that CLI off: then no CLI is started. The scan uses the same environment as a run, so the settings in the row above apply, but a CLI's own sign-in check may still reach its vendor
Desktop app updates api.github.com, github.com and the release download hosts it redirects to (release-assets.githubusercontent.com, objects.githubusercontent.com) A minute after the app starts, then every 12 hours, when installed with the installer Untick Check for updates automatically in the tray menu; for a whole machine, Updates:Mode Off or an internal feed in the machine policy
init localhost:1234 (LM Studio), localhost:11434 (Ollama) When you run semantic-router init Nothing leaves this machine

Nothing else is contacted:

  • The dashboard loads its scripts, styles and fonts from the router itself and sends Content-Security-Policy: default-src 'self'; …, so the browser refuses requests to any other host. The link to the project on GitHub is only followed when you click it.
  • The desktop app shows the dashboard from the router it runs, and reads the weekly digest from it for the tray.
  • Building from source sends no Avalonia build telemetry: Directory.Build.targets replaces its telemetry target. The .NET SDK has its own; set DOTNET_CLI_TELEMETRY_OPTOUT=1 to turn it off (see Contributing).

ONNX Runtime telemetry

The in-process embeddings (Embeddings:Provider: Onnx, which init picks when it finds no embedding server) run on Microsoft's ONNX Runtime. Its Linux and macOS builds send usage data to mobile.events.data.microsoft.com about ten seconds after a model is loaded, and keep a device id and an event queue in ~/.cache/Microsoft/DeveloperTools/.onnxruntime/, unless the environment variable ORT_DISABLE_TELEMETRY is 1 when ONNX Runtime loads. Its Windows build writes its events to Event Tracing for Windows (ETW) on the machine instead.

The router turns this off:

  • Every way it runs (the tool, the desktop app, a service, the container): before it first loads ONNX Runtime, it sets ORT_DISABLE_TELEMETRY=1 in the process's own environment, where ONNX Runtime reads it (setenv on Linux and macOS). On every platform it also turns off ONNX Runtime's telemetry events, which covers the Windows ETW events. Your own value is kept when you set ORT_DISABLE_TELEMETRY before starting the router.
  • The container image and the systemd and launchd services that semantic-router service install writes also set ORT_DISABLE_TELEMETRY=1 in the environment they start the router with.
  • Your own app with the SemanticRouter.Embeddings.Onnx package: AddOnnxEmbeddings and UseOnnxEmbeddings set it. If your app uses ONNX Runtime itself before that, call OnnxRuntimeEnvironment.DisableTelemetry() first, or set the variable before the process starts. Environment.SetEnvironmentVariable alone does not work on Linux and macOS: it changes only .NET's copy of the environment, which ONNX Runtime does not read.

semantic-router doctor says whether it is off, on an egress line, when the embeddings are Onnx.

Proxies and certificates

HTTP connectors, embeddings, webhooks and the ONNX download use .NET's HttpClient. It honours HTTPS_PROXY, HTTP_PROXY and NO_PROXY (and the system proxy on Windows and macOS), and trusts the operating system's certificate store.

A corporate root certificate. A proxy that inspects TLS signs every site with its own root. When that root is not in the operating system's store (common in containers), point SemanticRouter:Network:CaBundle at a PEM file with it:

{ "SemanticRouter": { "Network": { "CaBundle": "/etc/semantic-router/corporate-root.pem" } } }
  • The certificates in the file are trusted in addition to the system store, for the router's own connections only: connectors, the embeddings endpoint, webhooks and the ONNX download. A certificate must still match the host name and chain to a trusted root; nothing turns validation off.
  • It is a host setting, read at start-up: put it in appsettings.json in the configuration directory, the environment (SemanticRouter__Network__CaBundle) or the command line (--SemanticRouter:Network:CaBundle=…). A relative path is resolved against the configuration directory.
  • A file that is missing or holds no certificate stops the router at start-up, and doctor names it. doctor also prints how many certificates it added.
  • The desktop app's updater does not use it; it trusts the system store.

The container image is Ubuntu chiseled, with no shell or package manager, so update-ca-certificates cannot run in it. Mount the PEM file and set the option:

docker run -v ./corporate-root.pem:/etc/semantic-router/corporate-root.pem:ro \
  -e SemanticRouter__Network__CaBundle=/etc/semantic-router/corporate-root.pem … semantic-router

On Linux, .NET also reads SSL_CERT_FILE (a bundle) and SSL_CERT_DIR, but these replace the system store instead of adding to it: a file with only the corporate root then fails every site the proxy does not inspect. Use CaBundle, or give SSL_CERT_FILE a file with both the system's roots and yours.

The CLIs are separate programs: CaBundle does not reach them. They inherit the router's environment (minus the variables the preset removes), so the same proxy variables reach them, and so do their own certificate settings: NODE_EXTRA_CA_CERTS for Claude Code and the Copilot CLI (Node.js programs; it adds to their built-in roots) and CODEX_CA_CERTIFICATE for Codex. Set them in the router's environment, or per connector in EnvironmentVariables, e.g. "EnvironmentVariables": { "NODE_EXTRA_CA_CERTS": "/etc/semantic-router/corporate-root.pem" }.

Offline mode

For an air-gapped or locked-down network, SemanticRouter:Network:Offline makes sure nothing leaves except the model traffic you allow:

{ "SemanticRouter": { "Network": { "Offline": true, "AllowedHosts": ["llm-gateway.corp.example"] } } }
  • Connectors, the embeddings endpoint and webhooks reach only this machine (loopback) and AllowedHosts (host names, *.domain or IP addresses, each with an optional :port). Models on any other connector are turned off at start-up and listed with the warnings on the dashboard; turning one back on, on the dashboard or through the admin API, is refused. Remote embeddings fall back to the in-process hashing provider; a webhook elsewhere is not used.
  • CLI and Copilot connectors are off. They always reach their vendor over the internet, whatever the router does.
  • Prices are not looked up (the dashboard's Look up prices, and the prices Discover models fills in from OpenRouter's list), unless openrouter.ai is in AllowedHosts.
  • ONNX Runtime's telemetry is off, as it is outside offline mode (see above).
  • The ONNX embedding model is never downloaded. If it is not on disk, classification fails with a message naming the file, where to put it and its SHA-256: download it on another machine (semantic-router doctor prints the URLs' host and the folder) or set Embeddings:ModelPath to a folder with model.onnx and vocab.txt.
  • semantic-router doctor shows what is still contacted, and what is never contacted and why.

It is a host setting, like CaBundle: appsettings.json in the configuration directory, the environment (SemanticRouter__Network__Offline=true) or the command line. An administrator can force it for the whole machine with "Offline": true in the machine-wide policy; then the policy's AllowedEndpoints are the hosts it allows, the user's AllowedHosts cannot add more, and the desktop app does not update. The user's own Network:Offline does not change the desktop app's updates: untick Check for updates automatically in its tray menu.

Allowing it through a firewall

For an egress allowlist, list:

  1. the hosts of the connectors you enabled;
  2. huggingface.co and *.hf.co (its CDN, which serves the model file through a redirect) for the first start with ONNX embeddings, or pre-seed models/ and leave them out;
  3. your webhook hosts;
  4. for subscription CLIs, the hosts their vendors document (also for a CLI no connector uses, when the dashboard's setup may run it);
  5. for desktop updates, api.github.com, github.com, release-assets.githubusercontent.com and objects.githubusercontent.com;
  6. for the dashboard's price lookup, openrouter.ai (optional: without it, prices are entered by hand).

semantic-router doctor prints this list for the current configuration, one egress line per destination:

[ OK ] egress: connector lmstudio: localhost:1234 (this machine).
[ OK ] egress: connector openai: api.openai.com.
[ OK ] egress: connector claude: CLI: claude, which contacts Anthropic.
[ OK ] egress: embeddings: huggingface.co and its CDN (*.hf.co), once, to download ONNX model all-MiniLM-L6-v2 into /data/models/all-MiniLM-L6-v2 (copy it there to skip the download).
[ OK ] egress: ONNX Runtime telemetry: off (ORT_DISABLE_TELEMETRY=1, set before ONNX Runtime loads): mobile.events.data.microsoft.com is never contacted and no device id is written.
[ OK ] egress: webhook ops: hooks.slack.com.
[ OK ] egress: price list: openrouter.ai, only when the dashboard looks up cloud models' prices (Look up prices, Discover models); nothing but the request for the list is sent.
[ OK ] egress: setup scan: when the dashboard's setup looks for models on this machine, it starts any claude (Anthropic), codex (OpenAI) or copilot (GitHub) CLI on PATH to read its version and sign-in, even when no connector uses it, and that CLI may contact its vendor; LM Studio and Ollama are looked for on this machine only.
[ OK ] egress: desktop app updates: api.github.com, github.com, release-assets.githubusercontent.com and objects.githubusercontent.com (only the installed desktop app; untick Check for updates automatically in its tray menu to turn this off).

Connectors and webhooks show their host and port only: a webhook URL usually carries its token, so its path and query are never printed. The embeddings line names the download host only while the model is not in the models directory yet. Then doctor checks each enabled connector and the embeddings, so it fails on any host the allowlist is missing. It does not check a connector that offline mode or the machine policy turns off.

A test keeps this list honest: it runs the tool behind a recording proxy, with connectors and a judge on made-up hosts and a stand-in claude as the only program on PATH (so the CLIs installed where it runs are never started), through start-up, doctor, a chat call the judge grades, a classify call and the dashboard's pages, and fails when the tool contacts a host its egress lines do not name, or, in offline mode, any host but this machine. It sees only what goes through the proxy: the connectors' clients (the chat call and doctor's checks) and the judge do, while the webhook, price-list and embeddings-download clients are not exercised, and a client that ignored the proxy would fail to resolve the made-up hosts without the test noticing. The ONNX model download and the update redirects are followed weekly against the live hosts instead.