From b8297b8077a2b2417e646816d802de609f3d2dc3 Mon Sep 17 00:00:00 2001 From: Kyou0203 Date: Mon, 17 Aug 2026 01:30:45 +0800 Subject: [PATCH 1/3] docs(explorer): update stale authentication notes after v0.6.5 The Explorer API has required SEMANTICA_API_KEY (X-API-Key header) since v0.6.5, failing closed with 503 when unconfigured. Both the explorer README security note and docs/explorer-setup.md still claimed there was no built-in authentication. Update both to describe the actual behavior: API-key enforcement, the 503 fail-closed mode, and the explicit SEMANTICA_ALLOW_ANONYMOUS=true opt-in for local development. Fixes #1028 --- docs/explorer-setup.md | 2 +- explorer/README.md | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/explorer-setup.md b/docs/explorer-setup.md index f023730e..4d8caa1f 100644 --- a/docs/explorer-setup.md +++ b/docs/explorer-setup.md @@ -162,7 +162,7 @@ semantica-explorer --graph my_graph.json --no-browser ``` - `--host 0.0.0.0` makes Explorer reachable on every network interface. The server has no built-in authentication. Only use this on a trusted private network. + `--host 0.0.0.0` makes Explorer reachable on every network interface. Since v0.6.5 the Explorer API requires `SEMANTICA_API_KEY` (sent as the `X-API-Key` header) and fails closed with `503` when unconfigured; unauthenticated access is only possible when `SEMANTICA_ALLOW_ANONYMOUS=true` is set explicitly. Only use this on a trusted private network. diff --git a/explorer/README.md b/explorer/README.md index 3884aaee..3f5c313e 100644 --- a/explorer/README.md +++ b/explorer/README.md @@ -63,7 +63,9 @@ semantica-explorer --graph my_graph.json --no-browser python -m semantica.explorer --graph my_graph.json ``` -> **Security note:** The Explorer API has no built-in authentication. The default `--host 127.0.0.1` binds to localhost only, so it is not reachable from other machines on your network. If you bind to `0.0.0.0`, all graph data is readable and writable by any host that can reach the port. The CLI will print a warning in that case. +> **Security note:** Since v0.6.5 the Explorer API requires an API key. Set the `SEMANTICA_API_KEY` environment variable and send it as the `X-API-Key` header on every request; without a configured key, protected routes fail closed with `503` rather than serving anonymously. To opt into unauthenticated access for local development only, set `SEMANTICA_ALLOW_ANONYMOUS=true` explicitly. +> +> The default `--host 127.0.0.1` binds to localhost only, so it is not reachable from other machines on your network. If you bind to `0.0.0.0`, all graph data is readable and writable by any host that can reach the port (subject to API-key auth); the CLI will print a warning in that case. --- From dae21166a14dfc929c326b584c3a86fdcf3006b2 Mon Sep 17 00:00:00 2001 From: Kyou0203 Date: Tue, 18 Aug 2026 12:48:01 +0800 Subject: [PATCH 2/3] docs(explorer): clarify auth behavior and document auth env vars Address review feedback: - State that only protected routes require the API key and note that /api/health and /api/info are intentionally unauthenticated. - Note the CLI warning on non-loopback binds only fires in anonymous mode or when SEMANTICA_API_KEY is unset. - Add SEMANTICA_API_KEY and SEMANTICA_ALLOW_ANONYMOUS to the Environment variables table. --- explorer/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/explorer/README.md b/explorer/README.md index 3f5c313e..89616096 100644 --- a/explorer/README.md +++ b/explorer/README.md @@ -63,9 +63,9 @@ semantica-explorer --graph my_graph.json --no-browser python -m semantica.explorer --graph my_graph.json ``` -> **Security note:** Since v0.6.5 the Explorer API requires an API key. Set the `SEMANTICA_API_KEY` environment variable and send it as the `X-API-Key` header on every request; without a configured key, protected routes fail closed with `503` rather than serving anonymously. To opt into unauthenticated access for local development only, set `SEMANTICA_ALLOW_ANONYMOUS=true` explicitly. +> **Security note:** Since v0.6.5 the Explorer API requires an API key on protected routes. Set the `SEMANTICA_API_KEY` environment variable and send it as the `X-API-Key` header; without a configured key, protected routes fail closed with `503` rather than serving anonymously. To opt into unauthenticated access for local development only, set `SEMANTICA_ALLOW_ANONYMOUS=true` explicitly. (`/api/health` and `/api/info` are intentionally unauthenticated.) > -> The default `--host 127.0.0.1` binds to localhost only, so it is not reachable from other machines on your network. If you bind to `0.0.0.0`, all graph data is readable and writable by any host that can reach the port (subject to API-key auth); the CLI will print a warning in that case. +> The default `--host 127.0.0.1` binds to localhost only, so it is not reachable from other machines on your network. If you bind to `0.0.0.0`, all graph data is readable and writable by any host that can reach the port (subject to API-key auth). The CLI prints a warning when binding to a non-loopback host in anonymous mode or when `SEMANTICA_API_KEY` is unset. --- @@ -150,6 +150,8 @@ This writes the compiled assets to `../semantica/static/`. The Python server the | --- | --- | --- | | `EXPLORER_CORS_ORIGINS` | `http://localhost:5173,http://127.0.0.1:5173` | Comma-separated list of allowed CORS origins | | `EXPLORER_CORS_CREDENTIALS` | `false` | Set to `true` to allow credentialed cross-origin requests (only needed behind an authenticating reverse proxy) | +| `SEMANTICA_API_KEY` | *(unset)* | API key required on protected routes since v0.6.5; send it as the `X-API-Key` header. When unset, protected routes fail closed with `503`. | +| `SEMANTICA_ALLOW_ANONYMOUS` | `false` | Set to `true` to opt into unauthenticated access (local development only). | --- From a96f1590f15c2dd190d433345a7019a85c98fdc5 Mon Sep 17 00:00:00 2001 From: Sameer6305 Date: Tue, 18 Aug 2026 19:20:44 +0530 Subject: [PATCH 3/3] docs(explorer): document WebSocket authentication --- explorer/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/explorer/README.md b/explorer/README.md index 89616096..39103f49 100644 --- a/explorer/README.md +++ b/explorer/README.md @@ -255,6 +255,11 @@ Vite automatically tries the next available port and prints the actual URL in th - Confirm the backend exposes the `/ws/graph-updates` WebSocket endpoint. - Check DevTools → Network → WS tab for the connection status and error code. - Ensure the backend version matches the frontend — mixing major versions can cause protocol mismatches. +- **Authentication:** `/ws/graph-updates` enforces the same API key as the REST routes. Browsers cannot set custom headers on a WebSocket handshake, so pass the key as a query parameter instead: + ``` + ws://127.0.0.1:8000/ws/graph-updates?api_key= + ``` + Non-browser clients (native apps, scripts) may send it as the `X-API-Key` header. A missing or incorrect key results in close code `4401`; if `SEMANTICA_API_KEY` is unset and `SEMANTICA_ALLOW_ANONYMOUS` is not `true`, the connection is also rejected. Note that API keys in URLs appear in server logs — prefer the header for non-browser clients. ---