security: add data-leak audits (2 sessions + comparison + meta + transcript) and SAIA reclassification

This commit is contained in:
2026-05-21 02:57:59 +02:00
parent 9f6d0dd195
commit 333e3c99cd
6 changed files with 887 additions and 2 deletions
@@ -0,0 +1,84 @@
# Data-leak audit — 2026-05-20 · `Lumen TR-004 Test Run Analysis`
**Conversation**: `75fb06e8-Lumen_TR004_Test_Run_Analysis.json`
**LobeHub session model**: `qwen3.5-397b-a17b` (21 assistant turns)
**Total messages**: 60 (2 user · 21 assistant · 37 tool)
**Auditor**: agent doctrine-driven scan, 2026-05-20
## TL;DR
**Verdict: SENSITIVE DATA LEFT THE HOMELAB to an unapproved third party.** The breach channel was `lobe-cloud-sandbox`, not the LLM inference.
Two off-host data flows, with very different trust profiles:
1. **LLM inference via SAIA / GWDG** — 21 assistant turns sent the full conversation context (incl. Shepard search results) to SAIA via LiteLLM. **NOT a leak in this context** — SAIA is operated by GWDG (German academic computing center, Göttingen), [vetted by DLR](https://docs.hpc.gwdg.de/services/ai-services/saia/index.html) and integrated with the DLR IdP federation. For LUMEN (DLR engine programme) test data, SAIA is an approved partner.
2. **`lobe-cloud-sandbox` code execution — THE BREACH.** 9 calls sent Python source code (with explicit `LUMEN`, `P3-Lampoldshausen`, `LOX/LCH4` references, anomaly timings, and synthetic-but-derived-from-real timeseries) to **`api.lobehub.com`** + **codesandbox.io** — commercial third parties, not approved for DLR data. 4 `exportFile` calls pulled generated images back. **Criticality: HIGH** — proprietary aerospace IP in plaintext executable code, sent to commercial cloud.
Shepard data fetches themselves stayed on LAN (`shepard-api.nuclide.systems`), but the **results** were re-emitted to SAIA (approved) AND to the cloud sandbox (NOT approved).
## Conversation footprint
| Channel | Calls | Destination | Trust |
|---|---|---|---|
| `shepard` MCP (`list_data_objects`, `get_data_object`, `list_lab_journal`, etc.) | 27 | `shepard-api.nuclide.systems` (CT 101) | ✅ LAN |
| `lobe-cloud-sandbox` (`executeCode` + `exportFile`) | 9 | **`api.lobehub.com` + codesandbox.io** | ❌ **unapproved third party** |
| `lobe-agent-documents` (`listDocuments`) | 1 | LobeHub local (in-container) | ✅ LAN |
| LLM inference (`qwen3.5-397b-a17b`) | 21 | **SAIA (GWDG)** via LiteLLM | ✅ approved partner (DLR-vetted, IdP-federated) |
## Data flow
```mermaid
flowchart LR
user(["You · browser"]) -->|HTTPS via Zoraxy| lobe["LobeHub · CT 104"]
lobe -->|MCP, internal| shep[Shepard API · CT 101]
shep -->|test data, lab notes,<br/>investigation records| lobe
lobe -->|prompt + Shepard results<br/>+ tool messages| litellm[LiteLLM proxy · CT 104]
litellm -.->|qwen3.5-397b-a17b<br/>21 inference calls| saia[(SAIA / GWDG<br/>academic provider)]
lobe -.->|Python source + filenames<br/>9 calls| sbx[(LobeHub Cloud Sandbox<br/>api.lobehub.com<br/>+ codesandbox.io)]
sbx -.->|4 generated PNGs<br/>back to LobeHub| lobe
classDef leak fill:#5a2a2a,stroke:#c44,color:#fcc
class saia,sbx leak
classDef ok fill:#234c2a,stroke:#4c8,color:#cfc
class shep,lobe,litellm,user ok
```
## What specifically was sent where
### To SAIA (approved partner — LLM inference, 21 calls)
- Both user prompts verbatim.
- All Shepard tool outputs — collections found, data-object IDs, lab journal entries for TR-004 (anomaly time, fuel turbopump vibration values, chamber pressure profile, mixture ratio, test bench naming).
- The model's own intermediate reasoning.
- The Python code it wrote before sending to the sandbox.
- Sensitive strings: `LUMEN TR-004`, `LOX/LCH4`, `P3-Lampoldshausen`, `Fuel Turbopump Vibration Spike at t=8.0s`, `bearing replaced`, `TR-003 → TR-004 → TR-006 campaign`.
- **Routed through LiteLLM** (`ai.nuclide.systems`, CT 104) which has SAIA registered as a backend; chain logic terminates at SAIA for free academic models. See `services/litellm.md`.
### To LobeHub Cloud Sandbox (UNAPPROVED — 9 `executeCode` calls)
- ~1,500 lines of cumulative Python source containing the same identifiers.
- Inline JSON dumps of synthetic timeseries (vibration g_rms arrays, chamber-pressure curves, gimbal angles) constructed to match the real TR-004 profile from Shepard.
- 4 generated PNGs (the dashboards) existed on the cloud sandbox's filesystem long enough to be exported back.
### Stayed on LAN
- The actual raw Shepard sensor timeseries (`get_data_object` returned data IDs; what reached SAIA was the model's interpretation/summary, not raw buffers).
- The `www.dlr.de` URLs in chat are just citations, no fetch was triggered.
## Criticality matrix
| Channel | Sensitivity | Likelihood | Trust | Verdict |
|---|---|---|---|---|
| SAIA inference (via LiteLLM) | High (proprietary test analysis) | 100% (every chat) | ✅ approved partner (DLR-vetted) | **OK** |
| lobe-cloud-sandbox | High (Python referencing program data) | 100% in this chat | ❌ unapproved (commercial cloud) | **BREACH** |
| Other LobeHub providers (Gemini/Cerebras/Mistral) | High | Latent — fallback only | ❌ commercial | MEDIUM (latent risk) |
| Shepard MCP fetches | Internal only | Every related chat | ✅ LAN | LOW |
| Stale `DAYTONA_API_KEY` | None | Never used | n/a | trivial cleanup |
## Mitigations (ranked by impact ÷ effort)
1. **Disable `lobe-cloud-sandbox` in LobeHub** (highest single-step risk reduction). Use the `mcp-sandbox` Coder workspace template instead — already built, ephemeral, GPU-passthrough, sci-stack pre-baked, all local. *Effort: 10 min.*
2. **Pin LobeHub to LiteLLM only**. Remove per-provider `*_API_KEY` env vars. *Effort: 15 min.*
3. **Add a local-LLM route to LiteLLM** for sensitive workloads (qwen3-coder-30b via ollama/vllm on Arc). *Effort: 12 h.*
4. **Tag chats by sensitivity, enforce model routing.** *Effort: research first.*
5. **Network egress firewall** on UDM blocking `api.cerebras.ai` + `api.lobehub.com` + `codesandbox.io`. *Effort: 30 min.*
6. **Remove stale `DAYTONA_API_KEY`** from LobeHub env. Trivial.
See also: [`data-leak-audit-2026-05-21-tr004-artifacts.md`](data-leak-audit-2026-05-21-tr004-artifacts.md) for the next day's session with a different model, and [`data-leak-audit-comparison.md`](data-leak-audit-comparison.md) for the side-by-side.