feat: board-first orchestration with Gateway Bridge, live-update, and flow-board
- GatewayBridgeController: MCP-artiger Kommando-Adapter für Agent-zu-Backend - TaskBridgeService + LiveUpdateService: SSE Live-Sync + Bridge-Kommandos - FlowBoard.vue: Board-first orchestration dashboard panel - live-sync.ts store + live.ts service: SSE-basierte Live-Updates - Nullability-Warnung in HealthController.cs gefixt - nginx.conf: SSE-Proxy + CORS für Bridge-Endpunkte - .gitignore: pnpm/corepack local caches ausgeschlossen - docs: architecture-board-first-orchestration.md hinzugefügt - README: Backend Bridge API dokumentiert
This commit is contained in:
@@ -0,0 +1,503 @@
|
||||
# Nexus Board-First Orchestration & Sichere OpenClaw-Integration
|
||||
|
||||
> Gegenprüfung: Architekt, 2026-06-22
|
||||
> Gegenstand: Sicherster Pfad für Board-first-Agent-Orchestrierung und MCP-artige/strukturierte
|
||||
> OpenClaw-Integration im Nexus-Backend
|
||||
> Kein Frontend-direkter MCP-Pfad. Kein Deploy.
|
||||
|
||||
## 1. Executive Summary
|
||||
|
||||
### 1.1 Prüfergebnis
|
||||
|
||||
Der eingeschlagene Pfad ist **architektonisch korrekt und sicher**. Das Board-first-Modell mit
|
||||
Nexus-Backend als zentraler Brücke zwischen Benutzer, Board und OpenClaw-Gateway ist der richtige
|
||||
Ansatz. Das Backend fungiert bereits als sichere Schicht zwischen allen Akteuren.
|
||||
|
||||
### 1.2 Kernbewertung
|
||||
|
||||
| Aspekt | Status | Bewertung |
|
||||
|--------|--------|-----------|
|
||||
| Board-first Architektur | ✅ Umsetzung läuft | Parent/Child-Modell korrekt implementiert |
|
||||
| Kein Frontend-direkter Gateway-Zugriff | ✅ Eingehalten | Frontend spricht NUR mit Nexus-Backend |
|
||||
| Backend als sichere Brücke | ✅ Eingehalten | API-Container proxyt alle Gateway-Calls |
|
||||
| Auth-/Rechte-Modell | ✅ Solide | JWT + ApiKey + X-Agent-Id Enforcement |
|
||||
| Gateway-Security | ⚠️ Verbesserbar | `loopback`-Bind muss auf `lan` für Docker |
|
||||
| Migration-Reihenfolge | 📋 Vorgeschlagen | (siehe Abschnitt 8) |
|
||||
|
||||
## 2. Ist-Architektur: Wer spricht mit wem?
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────┐
|
||||
│ Browser (Bao/Iris) │
|
||||
│ auth.ts → JWT Access Token (15m) + HttpOnly Refresh Cookie │
|
||||
│ api.ts → fetch /api/v1/* → Authorization: Bearer <JWT> │
|
||||
└───────────────────────────┬──────────────────────────────────────┘
|
||||
│ HTTPS :443 (Traefik/npm)
|
||||
▼
|
||||
┌──────────────────────────────────────────────────────────────────┐
|
||||
│ Nexus web (nginx container) │
|
||||
│ location /api/ → proxy_pass http://api:8080 │
|
||||
│ location / → SPA (index.html) │
|
||||
│ CSP: connect-src 'self' — kein externer Gateway-Call möglich │
|
||||
└───────────────────────────┬──────────────────────────────────────┘
|
||||
│ HTTP :8080 (internal network)
|
||||
▼
|
||||
┌──────────────────────────────────────────────────────────────────┐
|
||||
│ Nexus API (.NET 10 Container) ← SICHERE BRÜCKE │
|
||||
│ │
|
||||
│ Auth-Middleware (JWT → Controller) │
|
||||
│ ApiKey-Middleware (X-Nexus-Api-Key → Role=Service) │
|
||||
│ SecurityHeaders-Middleware (HSTS, CSP, XFO) │
|
||||
│ Rate Limiter (auth: 5/min/caller, agents: 30/min/caller) │
|
||||
│ │
|
||||
│ IOpenClawGatewayClient │
|
||||
│ ├─ InvokeToolAsync("session_status", ...) │
|
||||
│ ├─ InvokeToolAsync("sessions_list", ...) │
|
||||
│ ├─ InvokeToolAsync("sessions_history", ...) │
|
||||
│ ├─ InvokeToolAsync("memory_search", ...) │
|
||||
│ ├─ InvokeToolAsync("sessions_send", ...) │
|
||||
│ └─ InvokeToolAsync("cron", ...) │
|
||||
│ │
|
||||
│ GatewayBridgeController (/api/bridge/*) <- NEU (2026-06-22) │
|
||||
│ └─ ITaskBridgeService │
|
||||
│ create_task / create_child_task / update_status / │
|
||||
│ append_activity / handoff / get_board / get_agent_overview │
|
||||
│ │
|
||||
│ IAgentRuntime (OpenClawRuntime) │
|
||||
│ └─ POST /v1/chat/completions (OpenAI-compat) │
|
||||
│ │
|
||||
│ ALLE Gateway-Calls → Authorization: Bearer <Gateway-Password> │
|
||||
└──────────────┬──────────────────────────────┬────────────────────┘
|
||||
│ host.docker.internal:18789 │
|
||||
│ (Gateway loopback/lan) │
|
||||
▼ │
|
||||
┌──────────────────────────────┐ │
|
||||
│ OpenClaw Gateway Container │ │
|
||||
│ Port 18789 │ │
|
||||
│ Auth: password │ │
|
||||
│ Bind: loopback (127.0.0.1) │ │
|
||||
│ │ │
|
||||
│ HTTP Deny-List (default): │ │
|
||||
│ exec, spawn, shell, │ │
|
||||
│ fs_write, fs_delete, │ │
|
||||
│ fs_move, apply_patch, │ │
|
||||
│ sessions_spawn, sessions_send│ │
|
||||
│ cron, gateway, nodes, │ │
|
||||
│ whatsapp_login │ │
|
||||
└───────────────────────────────┴──────────────┘
|
||||
```
|
||||
|
||||
### 2.1 Wichtig: Das Frontend sieht den Gateway NICHT
|
||||
|
||||
```
|
||||
Browser ─── [Nexus API] ─── Gateway
|
||||
│
|
||||
+─ Gateway-Passwort lebt NUR im Backend
|
||||
+─ CSP: connect-src 'self' blockiert jeden Direktzugriff
|
||||
+─ Gateway HTTP Deny-List blockiert alle RCE-Tools
|
||||
```
|
||||
|
||||
**Das ist die korrekte Architektur.** Kein Frontend-komponenten-direkter MCP-Pfad existiert
|
||||
und keiner sollte eingeführt werden.
|
||||
|
||||
## 3. Board-First Orchestrierung: Ist-Stand & Bewertung
|
||||
|
||||
### 3.1 Das Parent/Child-Task-Modell (Phase 3)
|
||||
|
||||
```
|
||||
Parent-Task (Owner: Iris)
|
||||
├── Child-Task A (AssignedTo: programmer)
|
||||
├── Child-Task B (AssignedTo: reviewer)
|
||||
└── Child-Task C (AssignedTo: architekt)
|
||||
```
|
||||
|
||||
**Status:** ✅ Implementiert (2026-06-21)
|
||||
|
||||
**Datenmodell (WorkTask):**
|
||||
- `ParentTaskId` (Guid?) — verknüpft Child mit Parent
|
||||
- `IsAgentTask` (bool) — markiert programmatisch erstellte Agent-Tasks
|
||||
- `ExpectedFrom` (string?) — wer als nächstes antworten soll
|
||||
- `AssignedTo` (string?) — operativer Owner der Task
|
||||
|
||||
**State Machine:**
|
||||
```
|
||||
Parent: Backlog → InProgress → Review → Done
|
||||
↘ Blocked → Backlog
|
||||
|
||||
Child: Backlog → InProgress → Done
|
||||
↘ Blocked → Backlog
|
||||
```
|
||||
|
||||
**Rules (aus TaskStateHelper.CanChangeState):**
|
||||
- **Nur Iris & Bao** dürfen State-Änderungen vornehmen
|
||||
- Sub-Agenten (programmer, reviewer, architekt, researcher, executor) **niemals**
|
||||
- `nexus-system` als technischer Fallback für Cron/Reset-Stale
|
||||
|
||||
### 3.2 Bewertung: Architektonisch korrekt
|
||||
|
||||
| Kriterium | Bewertung | Begründung |
|
||||
|-----------|-----------|------------|
|
||||
| Board als Single Source of Truth | ✅ | Task Board = sichtbare Aufgabenwahrheit |
|
||||
| Delegation sichtbar | ✅ | Child-Tasks statt unsichtbarem Delegations-Status |
|
||||
| Feingliedrige Berechtigung | ✅ | State-Change nur durch Iris/Bao |
|
||||
| Agenten arbeiten gegen Child-Tasks | ✅ | Klare Ownership durch `AssignedTo` |
|
||||
| Parent bleibt bei Iris | ✅ | Parent in `InProgress` während Koordination |
|
||||
| Review-Gate für Bao | ✅ | Parent erst in `Review`, dann Bao-Entscheidung |
|
||||
|
||||
### 3.3 Offene Punkte im Board-Modell
|
||||
|
||||
1. **Keine automatische Child-Task-Erstellung** — Das Board-Modell setzt voraus, dass Iris manuell
|
||||
Child-Tasks anlegt. Ein strukturierter Workflow für automatische Child-Task-Erstellung bei
|
||||
`spawn`/Subagent-Aufrufen fehlt.
|
||||
|
||||
2. **Keine Task→Session-Verknüpfung** — Es gibt keine direkte Verknüpfung zwischen einer
|
||||
Child-Task und der OpenClaw-Subagent-Session, die sie bearbeitet. Der `AgentService` kennt
|
||||
Sessions, `TaskService` kennt Tasks — aber sie sind nicht verknüpft.
|
||||
|
||||
3. **Reset-Stale ist ungeschützt** — `POST /api/v1/tasks/reset-stale` hat `[AllowAnonymous]`
|
||||
und kann von jedem aufgerufen werden (siehe Risiko #1).
|
||||
|
||||
## 4. Auth- und Rechte-Modell
|
||||
|
||||
### 4.1 Authentifizierungsebenen
|
||||
|
||||
```
|
||||
Ebene 1: Browser-JWT (Access Token 15m, Refresh Token HttpOnly Cookie)
|
||||
Ebene 2: X-Nexus-Api-Key (Service-zu-Service, Role=Service)
|
||||
Ebene 3: Gateway-Password (Backend → Gateway, Bearer Authorization)
|
||||
Ebene 4: X-Agent-Id Header (Agent-Identität für Task-State-Enforcement)
|
||||
```
|
||||
|
||||
### 4.2 Berechtigungsmatrix
|
||||
|
||||
| Aktion | Bao | Iris | Sub-Agent | nexus-system | Service (ApiKey) |
|
||||
|--------|-----|------|-----------|--------------|-------------------|
|
||||
| Task State ändern | ✅ | ✅ | ❌ | ✅ (intern) | ❌ |
|
||||
| Task Inhalt editieren | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Agent-Config lesen | ✅ | ✅ | ❌ | ❌ | ✅ |
|
||||
| Gateway-Tool aufrufen | ❌ | ❌ | ❌ | ❌ | ✅ (intern) |
|
||||
| Dashboard-Metriken sehen | ✅ | ✅ | ❌ | ❌ | ✅ |
|
||||
|
||||
### 4.3 Bewertung
|
||||
|
||||
**Positiv:**
|
||||
- JWT-Sicherheit entspricht Best Practices (PBKDF2-SHA256, 210k Iterationen, Rotating Refresh Tokens)
|
||||
- Refresh-Token-Reuse-Detection verhindert Token-Theft
|
||||
- Rate-Limiting auf Login und Refresh
|
||||
- CSRF-Protection via `X-CSRF-TOKEN` + `nexus-csrf` Cookie
|
||||
- Security Headers (HSTS, CSP, XFO, Referrer-Policy)
|
||||
|
||||
**Kritisch:**
|
||||
- `[AllowAnonymous]` auf `/tasks/board` und `/tasks/reset-stale` — siehe Risiko-Analyse
|
||||
- Kein Scoped-ApiKey — der `X-Nexus-Api-Key` gibt volle Service-Rechte
|
||||
- Keine Audit-Protokollierung für ApiKey-Nutzung
|
||||
|
||||
## 5. Gateway-Integration: Sicherheitsanalyse
|
||||
|
||||
### 5.1 Tool-Invoke-Pfad (Ist-Stand)
|
||||
|
||||
```
|
||||
POST /api/v1/operations/snapshot
|
||||
→ DashboardService → OpenClawGatewayClient.InvokeToolAsync()
|
||||
→ POST http://host.docker.internal:18789/tools/invoke
|
||||
Authorization: Bearer <Gateway-Password>
|
||||
```
|
||||
|
||||
**Aufgerufene Tools (durch Nexus-Backend):**
|
||||
- `session_status` — Agent-Status abfragen (read-only)
|
||||
- `sessions_list` — Session-Liste (read-only)
|
||||
- `sessions_history` — Chat-Verlauf (read-only)
|
||||
- `memory_search` — Memory-Suche (read-only)
|
||||
- `sessions_send` — Chat-Nachricht senden (write, aber kontrolliert)
|
||||
- `cron` — Cron-Jobs verwalten (write)
|
||||
|
||||
**Gateway HTTP Deny-List blockiert:**
|
||||
- Alle Exec-Tools (exec, spawn, shell)
|
||||
- Alle Filesystem-Tools (fs_write, fs_delete, fs_move, apply_patch)
|
||||
- Gateway-Control-Plane (gateway)
|
||||
- Node-Relay (nodes)
|
||||
- Session-Orchestrierung (sessions_spawn, sessions_send)
|
||||
|
||||
### 5.2 Docker-Netzwerk & Gateway-Bind
|
||||
|
||||
**Aktuelles Problem:**
|
||||
```
|
||||
compose.yaml:
|
||||
api:
|
||||
extra_hosts:
|
||||
- host.docker.internal:host-gateway
|
||||
networks:
|
||||
- nexus
|
||||
- openclaw_default ← API-Container ist im Gateway-Netzwerk
|
||||
|
||||
Gateway-Konfiguration:
|
||||
gateway.bind: "loopback" ← Bindet nur 127.0.0.1 IM GATEWAY-CONTAINER
|
||||
```
|
||||
|
||||
**Ergebnis:**
|
||||
- `host.docker.internal:18789` funktioniert, weil `extra_hosts` auf den Docker-Host zeigt
|
||||
- ABER: Docker-Port-Forward (wenn vorhanden) sendet an Container-IP, nicht loopback
|
||||
- Die `openclaw_default` Netzwerk-Mitgliedschaft des API-Containers wird NICHT genutzt
|
||||
|
||||
**Empfehlung (siehe gateway-api-research.md, Abschnitt 6):**
|
||||
```json5
|
||||
// openclaw.json
|
||||
{
|
||||
gateway: {
|
||||
bind: "lan" // war "loopback"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Alternativ: API-Container über Gateway-Container-Namen ansprechen:
|
||||
```yaml
|
||||
Integrations__OpenClaw__BaseUrl: http://openclaw_gateway:18789
|
||||
```
|
||||
(Vorausgesetzt der Gateway-Container heißt `openclaw_gateway` und ist im `openclaw_default` Netzwerk)
|
||||
|
||||
### 5.3 MCP-artige Integration: Bewertung
|
||||
|
||||
**Das Gateway `/tools/invoke` ist bereits MCP-artig:**
|
||||
- JSON-RPC-ähnliche Aufrufe mit `tool` + `args` + `sessionKey`
|
||||
- Strukturierte Responses mit `{ ok, result, error }`
|
||||
- Tool-Discovery via Policy (Deny/Allow-List)
|
||||
- Request/Response mit eindeutiger Fehlersemantik
|
||||
|
||||
**Was fehlt für ein vollständiges MCP-Interface:**
|
||||
- Keine Tool-Listing/Discovery über API (kein `tools/list`)
|
||||
- Keine Schema-Validierung für Tool-Arguments
|
||||
- Keine Structured Outputs (function-calling-ähnliches Format)
|
||||
|
||||
**Empfehlung: NICHT ein MCP-Protokoll zwischen Nexus und Gateway einführen.**
|
||||
Stattdessen den bestehenden `/tools/invoke`-Pfad weiter nutzen und strukturieren.
|
||||
|
||||
### 5.4 Neue Backend-Bridge (Implementiert 2026-06-22)
|
||||
|
||||
Der Nexus-eigene strukturierte Kommando-Adapter wurde eingeführt:
|
||||
|
||||
```
|
||||
Nexus Backend
|
||||
├─ GatewayToolClient (bestehender OpenClawGatewayClient)
|
||||
│ └─ POST /tools/invoke (Gateway)
|
||||
│
|
||||
├─ GatewayBridgeController (NEU — /api/bridge/)
|
||||
│ ├─ POST /api/bridge/tasks (create_task)
|
||||
│ ├─ POST /api/bridge/tasks/{id}/children (create_child_task)
|
||||
│ ├─ PATCH /api/bridge/tasks/{id}/status (update_status)
|
||||
│ ├─ POST /api/bridge/tasks/{id}/activity (append_activity)
|
||||
│ ├─ POST /api/bridge/tasks/{id}/handoff (handoff)
|
||||
│ ├─ GET /api/bridge/board (get_board)
|
||||
│ ├─ GET /api/bridge/tasks/{id} (get_task)
|
||||
│ ├─ GET /api/bridge/tasks/{id}/children (get_children)
|
||||
│ ├─ GET /api/bridge/tasks/{id}/activity (get_activity)
|
||||
│ └─ GET /api/bridge/agent-overview (get_agent_overview)
|
||||
│
|
||||
├─ ITaskBridgeService / TaskBridgeService (NEU)
|
||||
│ └─ Typisierte TaskBridgeResult<T> mit Outcome: Success/NotFound/InvalidState/Unauthorized/ValidationError
|
||||
│
|
||||
├─ BoardOrchestrationService (offen)
|
||||
│ ├─ Tasks erstellen/aktualisieren
|
||||
│ ├─ Session-Status abfragen
|
||||
│ └─ Agent-Progress berechnen
|
||||
│
|
||||
└─ AgentDelegationService (offen)
|
||||
├─ Subagent-Task anlegen
|
||||
├─ Session verfolgen
|
||||
└─ Ergebnis integrieren
|
||||
```
|
||||
|
||||
**Auth-Modell für /api/bridge:**
|
||||
- Primär: `X-Agent-Id` Header (Agent-Identität vom Gateway)
|
||||
- Fallback: JWT (Browser-authenticated user → bao)
|
||||
- Fallback: `X-Nexus-Api-Key` (Backend-zu-Backend Service-Identität)
|
||||
- Rate-Limiting: 30 Requests/Minute (agents-Policy)
|
||||
|
||||
**Das Frontend sieht /api/bridge NICHT.** Der Pfad ist ausschließlich für Agent-zu-Backend-Kommunikation.
|
||||
|
||||
## 6. Risikoanalyse
|
||||
|
||||
### 6.1 KRITISCH — `[AllowAnonymous]` auf Board-Endpunkten ✅ BEHOBEN (2026-06-22)
|
||||
|
||||
**Betroffen (vorher):**
|
||||
```csharp
|
||||
// TasksController.cs
|
||||
[AllowAnonymous]
|
||||
[HttpGet("board")] // Gab ALLE Tasks zurück — inkl. Detail-Texte
|
||||
|
||||
[AllowAnonymous]
|
||||
[HttpPost("reset-stale")] // Konnte Tasks zurücksetzen — datenändernd
|
||||
```
|
||||
|
||||
**Fix angewandt:**
|
||||
- `[AllowAnonymous]` entfernt
|
||||
- Inline-Auth-Check: `X-Agent-Id` Header, ApiKey-Rolle, oder JWT erforderlich
|
||||
- `reset-stale` erfordert zusätzlich `X-Agent-Id: iris` Identität (nur Iris darf)
|
||||
- Neuer `/api/bridge/` Pfad als sauberer Agent-zu-Backend-Adapter
|
||||
- Rate-Limiting (agents-Policy: 30/min) auf Bridge-Endpunkte
|
||||
|
||||
### 6.2 MITTEL — Keine Task→Session-Verknüpfung
|
||||
|
||||
Wenn ein Subagent eine Child-Task bearbeitet, gibt es keine technische Verknüpfung zwischen
|
||||
der Child-Task und der OpenClaw-Session. Das bedeutet:
|
||||
- Keine automatische Status-Aktualisierung bei Session-Abschluss
|
||||
- Keine Sitzungs-Historie direkt von der Task aus erreichbar
|
||||
- Iris muss manuell prüfen, ob ein Agent fertig ist
|
||||
|
||||
**Empfehlung:**
|
||||
- `WorkTask` um `SessionKey` (string?) erweitern
|
||||
- Bei Child-Task-Erstellung Session-Key speichern
|
||||
- Status-Polling: Wenn Session inaktiv, Child-Task auf Done/Blocked prüfen
|
||||
|
||||
### 6.3 MITTEL — Gateway-Passwort in Config-Dateien
|
||||
|
||||
Das Gateway-Passwort `ieDmOjBiVfbbDM0ibrEebPAg` ist:
|
||||
- In `.env` auf dem Host (OK)
|
||||
- In `gateway-api-research.md` (maskiert: `ieDm...PAg`)
|
||||
- Im `openclaw.json` auf dem Host (OK)
|
||||
- In der API-Container-Umgebungsvariable (notwendig)
|
||||
|
||||
**Empfehlung:**
|
||||
- Gateway-Rate-Limiting aktiv halten (10 attempts/60s → 5min lockout)
|
||||
- Gateway-Bind auf `lan` ändern (nicht öffentlich exponiert)
|
||||
- `gateway-api-research.md` aus dem öffentlichen Repo entfernen oder Passwort entfernen
|
||||
|
||||
### 6.4 NIEDRIG — Keine Scoped API-Keys
|
||||
|
||||
Der `X-Nexus-Api-Key` gibt volle Service-Rechte. Es gibt keine Möglichkeit, verschiedene
|
||||
API-Keys mit unterschiedlichen Rechten zu vergeben.
|
||||
|
||||
**Empfehlung (spätere Phase):**
|
||||
- API-Key-Scopes einführen (read, write, admin)
|
||||
- Rate-Limiting pro API-Key
|
||||
- Audit-Log für ApiKey-Nutzung
|
||||
|
||||
### 6.5 NIEDRIG — Kein Structured Output vom Gateway
|
||||
|
||||
Die `/tools/invoke`-Responses sind JSON, aber ohne Schema-Garantie. Die Backend-Logik
|
||||
extrahiert Felder mit vielen Fallbacks (`??`-Kettenantworten).
|
||||
|
||||
**Empfehlung:**
|
||||
- Response-Typen für jedes Tool definieren (DTOs)
|
||||
- Deserialisierung mit Schema-Validierung
|
||||
- Fallback-Logik zentralisieren
|
||||
|
||||
## 7. Migrationsreihenfolge (Vorschlag)
|
||||
|
||||
### Phase 3b — Sichere Board-Grundlage (JETZT)
|
||||
```
|
||||
1. [AllowAnonymous] auf /tasks/board und /tasks/reset-stale fixen
|
||||
→ ApiKey-Auth plus X-Agent-Id-Validierung
|
||||
→ README/Iris-Doku aktualisieren
|
||||
|
||||
2. Gateway-Bind von loopback auf lan ändern
|
||||
→ API-Container über openclaw_default Netzwerk ansprechen
|
||||
→ host.docker.internal-Fallback entfernen
|
||||
```
|
||||
|
||||
### Phase 4 — Strukturierte Orchestrierung
|
||||
```
|
||||
3. Task→Session-Verknüpfung einführen
|
||||
→ WorkTask.SessionKey (string?)
|
||||
→ Bei Child-Task-Erstellung Session speichern
|
||||
|
||||
4. AgentDelegationService
|
||||
→ Zentralisierte Subagent-Task-Erstellung
|
||||
→ Session-Status-Monitoring
|
||||
→ Automatische Status-Propagation (Session done → Task done)
|
||||
|
||||
5. BoardOrchestrationService
|
||||
→ Refresh-Intervall für Agent-Progress
|
||||
→ Stale-Erkennung mit Session-Status
|
||||
→ Priorisierung nach Workload
|
||||
```
|
||||
|
||||
### Phase 5 — Erweiterte Integration
|
||||
```
|
||||
6. Structured Tool Responses
|
||||
→ DTOs für jedes Gateway-Tool
|
||||
→ Schema-Validierung
|
||||
→ Caching für häufige Abfragen
|
||||
|
||||
7. API-Key-Scopes
|
||||
→ read/write/admin Scopes
|
||||
→ Audit-Log für ApiKey-Nutzung
|
||||
|
||||
8. Automatische Child-Task-Erstellung
|
||||
→ Bei spawn/subagent-Aufrufen automatisch Child-Task anlegen
|
||||
→ Session-Key verknüpfen
|
||||
→ Activity-Feed erweitern
|
||||
```
|
||||
|
||||
## 8. Sichere Brücke: Architekturprinzipien
|
||||
|
||||
### 8.1 Das Backend ist die einzige Brücke
|
||||
|
||||
```
|
||||
Browser ←→ Nexus API ←→ OpenClaw Gateway
|
||||
↑ ↑
|
||||
JWT Auth Gateway Password
|
||||
(pro User) (nur im Backend)
|
||||
```
|
||||
|
||||
**Niemals:**
|
||||
- Gateway-Passwort im Frontend
|
||||
- Direkter Browser→Gateway API-Call
|
||||
- MCP-Protokoll zwischen Frontend und Gateway
|
||||
- Agent-Sessions direkt aus dem Frontend steuern
|
||||
|
||||
### 8.2 Prinzipien für jede neue Integration
|
||||
|
||||
1. **Neue Endpunkte immer im Nexus-Backend**
|
||||
2. **Auth über bestehendes JWT/ApiKey-System**
|
||||
3. **Gateway-Calls immer serverseitig mit Gateway-Passwort**
|
||||
4. **Kein Gateway-Tool direkt aus dem Frontend aufrufen**
|
||||
5. **State-Änderungen nur durch Iris/Bao (via Backend-Enforcement)**
|
||||
6. **Activity/Audit für jede State-Änderung**
|
||||
|
||||
### 8.3 Strukturierte OpenClaw-Integration (MCP-artig)
|
||||
|
||||
Der Gateway `/tools/invoke`-Endpunkt ist bereits strukturell MCP-artig. Eine formale
|
||||
MCP-Implementierung zwischen Nexus und Gateway ist **nicht notwendig**. Stattdessen:
|
||||
|
||||
```
|
||||
Nexus.Backend.Services
|
||||
├── IOpenClawGatewayClient (Gateway-Tool-Abstraktion)
|
||||
│ └── InvokeToolAsync(tool, args) → JsonNode?
|
||||
│
|
||||
├── IBoardOrchestrationService (NEU)
|
||||
│ ├── CreateDelegateTask(agentId, title, detail) → WorkTask
|
||||
│ ├── WatchAgentSession(agentId) → SessionWatcher
|
||||
│ └── SyncAgentProgress() → Progress[]
|
||||
│
|
||||
└── IAgentDelegationService (NEU)
|
||||
├── DelegateToAgent(parentTaskId, agentId, instruction)
|
||||
├── CollectResult(subTaskId) → AgentResult
|
||||
└── HandleBlocker(subTaskId, reason) → void
|
||||
```
|
||||
|
||||
## 9. Zusammenfassung
|
||||
|
||||
### Was gut ist (nicht ändern):
|
||||
- Board-first-Ansatz mit Parent/Child-Tasks
|
||||
- Backend als einzige Gateway-Brücke
|
||||
- JWT + Gateway-Password-Trennung
|
||||
- State-Change-Restriktion auf Iris/Bao
|
||||
- HTTP Deny-List des Gateways
|
||||
- CSP im Frontend (kein externer Connect)
|
||||
|
||||
### Was verbessert werden muss:
|
||||
- `[AllowAnonymous]` auf Board-Endpunkten → ApiKey-Auth
|
||||
- Gateway-Bind loopback → lan (oder Netzwerk-Routing korrigieren)
|
||||
- Task→Session-Verknüpfung fehlt
|
||||
|
||||
### Was später kommen kann:
|
||||
- Automatische Child-Task-Erstellung bei Subagent-Aufrufen
|
||||
- Structured Gateway Responses mit Schema-Validierung
|
||||
- API-Key-Scopes und Audit
|
||||
- Session-gesteuertes Progress-Tracking
|
||||
|
||||
### Was niemals kommen darf:
|
||||
- Gateway-Passwort im Frontend
|
||||
- Direkter MCP-Pfad Browser→Gateway
|
||||
- Agent-Session-Steuerung aus dem Frontend
|
||||
- Task-State-Änderung durch Sub-Agenten
|
||||
@@ -1,7 +1,12 @@
|
||||
# Gateway API Research
|
||||
|
||||
> Generated: 2026-06-10
|
||||
> Generated: 2026-06-10 | Updated: 2026-06-22
|
||||
> Auth mode: password (not token)
|
||||
>
|
||||
> ⚠️ **Security note:** Diese Datei enthält Infrastruktur-Details zur Gateway-Integration.
|
||||
> Sie gehört nicht ins öffentliche Repository. Bis zur Bereinigung: Gateway-Passwort
|
||||
> maskiert als `ieDm...PAg`. Vollständige Architektur-Analyse in
|
||||
> [`architecture-board-first-orchestration.md`](architecture-board-first-orchestration.md).
|
||||
|
||||
## 1. Authentication
|
||||
|
||||
|
||||
Reference in New Issue
Block a user