Files
wehub-resource-sync 7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

7.1 KiB

Egress modes — what each one does

⚠️ Experimental. The egress boundary is new and ships as defense-in-depth, not an absolute guarantee. It blocks the known data-egress paths under the scope you pick, but this is an early version — don't rely on it as your only protection for highly sensitive data yet. See the threat model and limitations linked just below.

LDR's egress scope (Settings → Egress Scope, or the Privacy & Egress panel on the research form) controls where your research traffic is allowed to go — which search engines run, whether your LLM/embeddings may be cloud services, and which URLs may be fetched. It's the single switch for "how much of this run is allowed to leave my machine?"

Pick a mode below. The default is Adaptive, which just follows your primary search engine, so most people never need to think about it.

This page explains the modes for everyday use. For the threat model, guarantees, and limitations, see SECURITY.md and the technical egress package README.

At a glance

Mode Search engines LLM / embeddings Best for
Adaptive (default) follows your primary engine forced local only when the run is private "just do the sensible thing"
Unprotected any engine (no restriction) any provider (cloud allowed) escape hatch — not recommended; disables egress protection (hard SSRF / cloud-metadata blocking still applies)
Public only public web/academic engines only your configured providers public research; your local collections aren't touched
Private only local engines only (collections, local SearXNG/Ollama) forced local — cloud blocked sensitive work that must stay on the machine
Strict only your one primary engine your configured providers a single, exact source with zero expansion

🔀 Adaptive (default)

Adaptive follows your primary search engine and resolves to a concrete mode for each run:

  • Primary is a public engine (e.g. SearXNG pointed at a public instance, arXiv, PubMed) → behaves like Public only.
  • Primary is a private source (a local collection, your library) → behaves like Private only (and therefore forces local LLM + embeddings).

Why it's the default: you choose a search engine anyway, and the privacy posture "just matches" it. If you make a private collection your primary, the whole run automatically stays local — nothing leaves the box.

Note: to use a cloud LLM on a private collection, mark the collection public (see below) or add the provider to trusted inference providers; to drop all restrictions for one run, use Unprotected. Adaptive deliberately narrows to match the primary.

🔓 Unprotected

Not recommended — an escape hatch. Egress-scope restrictions are disabled for the run: any engine, URL, and LLM/embeddings provider is permitted. The hard SSRF and cloud-metadata blocks still apply. A loud, non-dismissible banner shows while it is active. Prefer marking a collection public, or adding a trusted destination (policy.trusted_inference_providers / policy.trusted_search_engines) for the specific case, over disabling protection wholesale.

The older Both scope (blanket-permit any classified engine) has been retired: existing saved both configurations are migrated to Adaptive (which follows your primary engine and forces local inference for a private primary). If you relied on both to use a private collection with a cloud model, mark that collection public, or choose Unprotected to opt out of protection explicitly.

☁️ Public only

Only public web/academic engines run; your local collections are excluded. URL fetches are allowed to public hosts and blocked for private ones. Inference is whatever you configured (cloud allowed). Use it when you want public research and don't want your private documents queried at all.

🔒 Private only

The privacy mode. Only local engines run (collections, library, a local SearXNG/Ollama). Crucially, it forces local LLM and embeddings — cloud providers (OpenAI, Anthropic, Google, OpenRouter, …) are blocked, so your query and your retrieved documents never reach a cloud model. Public URL fetches are blocked, and a process-wide socket guard blocks stray outbound connections. Nothing leaves the machine.

If you have no local LLM configured, a Private-only run will refuse rather than silently fall back to the cloud — that's intentional (fail-closed).

🎯 Strict

The tightest mode: only your single primary engine runs — no expansion to any other engine at all. At the URL layer it behaves like Private-only (private hosts allowed, public blocked), but it does not force local inference — set the Require local toggles if you also want local LLM/embeddings.


Per-collection public/private

Each RAG collection has a public/private flag (default private):

  • A private collection is excluded under Public only / Adaptive-public, and when used it forces local inference — its chunks never reach a cloud model.
  • Mark a collection public (the Public collection checkbox when creating it) only if its contents are non-sensitive and you're happy to process them with cloud inference / use them under public scope.

The two local-inference toggles

Independent of the scope, you can force local inference any time:

  • Require local LLM endpoint — refuse cloud LLM providers / non-local URLs.
  • Require local embeddings — refuse cloud embedders, and refuse a HuggingFace download for an uncached local model.

Both are implied automatically under Private only (and Adaptive-private), which is why those toggles auto-check and lock when you select Private only.


Per-research overrides

The three primary controls — Egress Scope, Require local LLM endpoint, and Require local embeddings — also appear on the research-form page as per-run dropdown / checkbox overrides. Values set there apply only to that research run and do not persist to the settings database, so you can do a one-off private run without changing your defaults.

Audit log

Changes to any policy.* key, llm.require_local_endpoint, llm.allowed_local_hostnames, or embeddings.require_local emit a policy_audit=True log line so administrators can trace configuration changes. Those audit lines are deliberately filtered out of the WebSocket progress stream (they never reach browser subscribers).


See also

  • Configuration reference — the exact setting keys (policy.egress_scope, llm.require_local_endpoint, embeddings.require_local, llm.allowed_local_hostnames) and their auto-generated LDR_* environment variables.
  • SECURITY.md — threat model, guarantees, and caveats (including what this does not defend against).