|
Download docs/CONSOLE.md from DibaAi/DibaGuard-Open: direct link, hf CLI and curl.
- Browser
- Download file 8.98 kB
-
https://huggingface.co/DibaAi/DibaGuard-Open/resolve/main/docs/CONSOLE.md
- Command line
-
hf download hf://DibaAi/DibaGuard-Open/docs/CONSOLE.md
-
curl -L -o CONSOLE.md https://huggingface.co/DibaAi/DibaGuard-Open/resolve/main/docs/CONSOLE.md
8.98 kB
| # DibaGuard console | |
| > **Open-release copy** ([DibaAi/DibaGuard-Open](https://huggingface.co/DibaAi/DibaGuard-Open)). This document was written for the private build of DibaGuard. Numbers that involve the HTTP request model (`http_v2`) were measured with that model, which is **not** part of the open release; the open release ships the licence-clean network models described in `CLEAN_MODELS.md`. Licence statements inside this document are superseded by `DATA_LICENSES.md`, `CLEAN_MODELS.md` and the repository's `LICENSE`, `LICENSE-WEIGHTS` and `NOTICE` files. Sections of the original that were written in Persian were removed from this copy; nothing else was edited. | |
| The operator console is one self-contained page served by the sidecar at `GET /console` (`/` and `/dashboard` redirect | |
| to it). It loads nothing from anywhere else - no CDN, font or script - so it works on an air-gapped server. Tabs: | |
| Overview, Incidents (with a per-source drawer: evidence, timeline, what the layer did and why, database remediation), | |
| Review queue, Rules, Policy, Databases, Posture & enforcement, Teach. Light and dark themes follow the OS; the sun/moon | |
| button overrides it. | |
| ## Opening it | |
| The sidecar binds to `127.0.0.1` by default. From your laptop, tunnel to it: | |
| ``` | |
| ssh -N -L 8787:127.0.0.1:8787 user@guard-host | |
| # then open http://127.0.0.1:8787/console | |
| ``` | |
| Start the sidecar with the shield layer (without `--policy` the console is read-only, engine only): | |
| ``` | |
| python -m dibaguard.llm http --models models --policy policy.json --inputs http,flows --port 8787 | |
| ``` | |
| Reading needs nothing. Every write (verdicts, rules, policy, block / lift, teaching) needs the **console token**: | |
| - set `DIBAGUARD_CONSOLE_TOKEN` in the sidecar's environment, or | |
| - leave it unset: the sidecar generates one and prints it **once** on stderr at startup. | |
| Click **Read-only** in the header and paste the token. It is kept in that browser tab only (sessionStorage) and | |
| forgotten when the tab closes or you click **Unlocked** to lock again. | |
| ## Connecting an LLM (Teach) | |
| The model is configured in the sidecar's environment, never in the page; the key never reaches the browser. | |
| | variable | value | | |
| |---|---| | |
| | `DIBAGUARD_LLM_PROVIDER` | `openai` - any OpenAI-compatible `/chat/completions` endpoint (vLLM, llama.cpp server, Ollama, LM Studio, OpenAI) - or `anthropic` (Messages API) | | |
| | `DIBAGUARD_LLM_BASE_URL` | e.g. `http://10.0.0.30:8000/v1`; for `anthropic` defaults to `https://api.anthropic.com` | | |
| | `DIBAGUARD_LLM_MODEL` | the model name | | |
| | `DIBAGUARD_LLM_API_KEY` | the key (optional for local servers; required for `anthropic`) | | |
| | `DIBAGUARD_LLM_TIMEOUT` | seconds per call, default 120 | | |
| On an air-gapped site, point `DIBAGUARD_LLM_BASE_URL` at a model served on the local network; the model must support | |
| tool / function calling. Without an LLM, the Teach tab explains this and still offers the built-in Persian / English | |
| rule parser. | |
| The Rules tab can also use the connected LLM to interpret a rule written in any language (interpreter | |
| "Connected LLM", or "Auto" when the built-in parser finds no condition). The result is shown as a precise rule first. | |
| ## The approval model | |
| The sidecar runs the tool loop itself (`POST /console/chat`), with the dispatcher's tools (`guard_*`) plus four | |
| console tools (`console_entity`, `console_rule_install`, `console_rule_remove`, `console_enforce`). | |
| - **Reads run at once**: status, report, entity details, review queue, fast state, rules / policy (viewing), database | |
| status, playbook. | |
| - **Everything that changes state becomes a proposal**: rule install / removal, verdicts, policy changes, block / lift, | |
| calibration, and feeding traffic to the engine (scoring can lead to actions). The model is told "proposed - not | |
| executed" and the proposal appears in the transcript and in *Pending proposals* with its exact tool call. | |
| - **Only you execute it**, by clicking **Approve** (`POST /console/approve`). A rule proposal installs exactly the rule | |
| you saw in the preview - it is not re-interpreted. A mode switch additionally needs the target mode typed back. | |
| Proposals expire after an hour; each can be decided once. | |
| - The assistant hears your decisions (approved, rejected, failed, and your own changes from other tabs) at the start of | |
| its next turn. The server keeps a bounded history (40 messages for the model, 300 transcript lines); **Clear** forgets it. | |
| Policy changes from the Policy tab are validated by `Policy.validate` before they apply. Switching between REPORT and | |
| ENFORCE asks you to type `ENFORCE` / `REPORT`, server-side (an API caller cannot skip it either). Fields that only take | |
| effect at start-up (`alpha`, database thresholds read at load) are not editable live: edit `policy.json` and restart. | |
| Rules and policy changed in the console live in memory; **Policy -> Effective policy -> Download** gives a | |
| `policy.json` with the installed rules to keep them across restarts. | |
| ## Security notes | |
| - **Bind to loopback** and reach it over SSH. If you bind elsewhere the sidecar warns at startup; put TLS and access | |
| control in front. | |
| - **Writes**: every `POST /console/*` needs `X-DibaGuard-Token` (or `Authorization: Bearer`), the custom header | |
| `X-DibaGuard-Console: 1`, and `Content-Type: application/json`. Cross-site requests (`Origin` not matching `Host`, | |
| `Sec-Fetch-Site: cross-site|same-site`) are refused. No CORS headers are ever sent, so another site's page can neither | |
| send those headers nor read answers. | |
| - **DNS rebinding**: `/console*` is only served when `Host` is an IP literal or `localhost`; add names (a reverse proxy) | |
| with `DIBAGUARD_CONSOLE_HOSTS=guard.example.internal`. | |
| - **The page** carries a CSP that pins its one inline script by hash, forbids every external load, framing, forms and | |
| base changes. Everything shown is inserted as text - evidence, queries and user-agents from attackers never become markup. | |
| - **The tool API** (`POST /tools/<name>`): calls that change what the layer enforces - `guard_policy` with `set`, | |
| `guard_feedback`, `guard_rules` with `add` (not `interpret_only`), `guard_posture` when port closing is on - need the | |
| same token **and** `X-DibaGuard-Console: 1`, and so do `guard_calibrate` / `guard_db_calibrate` (re-calibration | |
| rewrites what the site's normal is). Reads stay open on loopback. **Traffic feeds that carry sources** | |
| (`guard_score_http` with `client` / `t` / `status`, `guard_score_flows`, `guard_db`, `guard_rpc`) need the **feed | |
| token** - `DIBAGUARD_FEED_TOKEN`, sent as `X-DibaGuard-Feed-Token` by the Go proxy and the authz service, which read | |
| the same variable - or the console token: otherwise anyone who can reach the port could feed traffic that makes the | |
| layer block an address of their choice (validation finding V-16). Without `DIBAGUARD_FEED_TOKEN` the sidecar makes | |
| one and prints it once on stderr. A score-only `guard_score_http` (texts, no client or time) changes nothing and stays | |
| open. `DIBAGUARD_FEEDS_OPEN=1` reopens every feed (an isolated loopback deployment only; the sidecar warns at | |
| startup); `DIBAGUARD_FEEDS_NEED_TOKEN=1` demands the console token and header for feeds too. MCP over stdio is | |
| unchanged (it is the local process's own channel). | |
| - **Prompt injection**: tool results contain attacker-written text. The system prompt tells the model it is data, and | |
| the approval gate means a manipulated model can at most *propose*; read each proposal's exact tool call before approving. | |
| - The LLM key stays in the sidecar process; provider errors are redacted before they are shown. | |
| ## Endpoints | |
| | method | path | | | |
| |---|---|---| | |
| | GET | `/console` | the page | | |
| | GET | `/console/state` | counters, pressure, drift, mode, backend, latest alarms / actions, per-minute series | | |
| | GET | `/console/incidents?limit=` | sources with risk, score, families, playbook names, enforcement | | |
| | GET | `/console/entity?ip=` | one source: evidence, timeline, audit (what was done, why), explanation, remediation, verdicts | | |
| | GET | `/console/review` | review queue (incl. `site:drift`), verdict stats, recent verdicts | | |
| | GET | `/console/rules`, `/console/policy`, `/console/databases`, `/console/posture`, `/console/chat` | tab data | | |
| | POST | `/console/auth` | check the token | | |
| | POST | `/console/rules/interpret` `{text, engine: auto\|builtin\|llm}` | preview only | | |
| | POST | `/console/rules/install` `{rule, text}` / `/console/rules/remove` `{id}` | | | |
| | POST | `/console/policy` `{set, confirm?}` | 409 + `confirm_word` when the mode changes | | |
| | POST | `/console/feedback` `{entity, verdict, note}` | confirm / reject / benign_source | | |
| | POST | `/console/enforce` `{ip, action: block\|rate_limit\|challenge\|lift, reason}` | | | |
| | POST | `/console/posture/run` | runs the audit (closes ports only if the policy allows) | | |
| | POST | `/console/chat` `{message}` / `/console/chat/reset` | the assistant | | |
| | POST | `/console/approve` `{id, decision: approve\|reject, confirm?, note?}` | execute or drop a proposal | | |