diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index 6add26c6..099f8d5f 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -52,7 +52,7 @@ control-plane, relay, compute, and worker implementations are private services. | `ENGRAPHIS_LLM_AUTO_EXTRACT` | `0` | Opt in to switching the running engine to `llm_structured` after a successful live connection test; the dashboard's extraction Off button persists `0`, and its On button restores `1` | | `ENGRAPHIS_FORWARDED_ALLOW_IPS` | *(none)* | Proxies trusted for forwarded client/TLS headers (`*` only when the service is reachable exclusively through that proxy) | | `ENGRAPHIS_LOCAL_TRUSTED_PEERS` | *(none)* | Exact peers/CIDRs treated as local without forwarding headers; use only for trusted Docker/LAN peers, never public deployments | -| `ENGRAPHIS_DASHBOARD_URL` | Not set | The exact URL clients use to reach this dashboard. Its host name is accepted by the `/mcp` DNS-rebinding guard and, without an API token, by the dashboard API | +| `ENGRAPHIS_DASHBOARD_URL` | Not set | The exact URL clients use to reach this dashboard. Its host name is accepted by the `/mcp` DNS-rebinding guard, by automatic dashboard browser access, and, without an API token, by the dashboard API | | `ENGRAPHIS_ALLOWED_HOSTS` | *(none)* | Comma-separated extra host names (ports ignored) that the token-free dashboard API and read-only graph server answer. Without a token they otherwise accept only exactly `localhost`, IP addresses, the bind host and the `ENGRAPHIS_DASHBOARD_URL` host, which keeps DNS-rebinding websites out; with a token every name works | | `ENGRAPHIS_UPDATE_CACHE` | `86400` | Update-check cache TTL in seconds, bounded to `1..31622400`; this is never a cache-file path | | `ENGRAPHIS_UPDATE_CHECK` | Off | Opt-in release reminder surfaced in the dashboard, server startup log, and MCP. Update checks run only when this is set to an affirmative value; `0` keeps them off. | diff --git a/playwright.config.js b/playwright.config.js index 27d9ed37..8877c3d7 100644 --- a/playwright.config.js +++ b/playwright.config.js @@ -30,8 +30,8 @@ module.exports = defineConfig({ ENGRAPHIS_EXTRACTOR: 'none', ENGRAPHIS_LOOP_INTERVAL: '0', ENGRAPHIS_HOST: '127.0.0.1', - // Public test fixture, never the owner's configured credential. The real - // browser smoke uses this to exercise governed source approval. + // Public test fixture, never the owner's configured credential. The server keeps + // token-protected API routes while browsers open through automatic access. ENGRAPHIS_API_TOKEN: 'engraphis-playwright-local-only', ENGRAPHIS_SERVICE_MODE: 'customer', }, diff --git a/tests/test_config.py b/tests/test_config.py index a5a29e83..20841f29 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -273,6 +273,20 @@ def test_malformed_boolean_values_use_safe_default(monkeypatch): monkeypatch.setenv("ENGRAPHIS_UPDATE_CHECK", "perhaps") assert Settings().update_check is False + +def test_browser_auto_session_defaults_on_and_can_be_hardened(monkeypatch): + monkeypatch.delenv("ENGRAPHIS_BROWSER_AUTO_SESSION", raising=False) + assert Settings().browser_auto_session is True + + for raw in ("0", "false", "off", "no"): + monkeypatch.setenv("ENGRAPHIS_BROWSER_AUTO_SESSION", raw) + assert Settings().browser_auto_session is False + + # A malformed value keeps the documented default instead of silently flipping the + # dashboard's access posture. + monkeypatch.setenv("ENGRAPHIS_BROWSER_AUTO_SESSION", "perhaps") + assert Settings().browser_auto_session is True + @pytest.mark.parametrize("url", RETIRED_RELAY_URLS) def test_retired_relay_url_override_is_canonicalized(url): assert config.canonicalize_relay_url(url) == config.DEFAULT_RELAY_URL