Architekturüberblick: Sichere Agent‑Website
Ebene
Rolle
Sicherheitsfokus
Frontend (Web)
UI, Interaktion, Anzeige
Hardening, CSP, kein direkter MCP‑Zugriff
Backend API
HTTP/JSON‑API für Website
Auth, Rate‑Limit, Input‑Validation
Agent‑Engine
Task‑Routing, Prompt‑Analyse
Sandbox, Rechte‑Trennung
MCP‑Client
spricht mit Compose‑Runtime / MCP‑Server
mTLS, Auth‑Token, strikte Protokolle
MCP‑Server
kontrolliert laufende App
Zugriffskontrolle, Logging, Isolation
1. Website‑Backend: sichere Schnittstelle zum Agenten
Ziel: Die Website spricht nur mit deinem Backend, nie direkt mit MCP.
kotlin
@RestController @RequestMapping("/api/agent") class AgentController(
private val engine: AgentEngine
) {
@PostMapping("/task")
fun handleTask(
@RequestBody req: TaskRequest,
principal: Principal
): ResponseEntity<AgentResponse> {
// 1. Auth & Rechte prüfen
if (!hasPermission(principal, req)) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build()
}
// 2. Eingaben validieren
val safeTask = sanitizeTask(req)
// 3. Task an Agent‑Engine
val result = runBlocking {
engine.dispatch(safeTask.toAgentTask(), AgentContext(user = principal.name))
}
// 4. Nur sichere Daten zurückgeben
return ResponseEntity.ok(result.toResponse())
}
}
Wichtig:
- Keine Roh‑Prompts ungefiltert an den Agent
- Keine direkten MCP‑Calls aus dem Controller
- Strikte Input‑Validierung (Länge, Typ, erlaubte Aktionen)
2. Sicherheitslayer im Agent‑Modul (MCP)
Wir härten das McpAgentModule:
kotlin
class SecureMcpAgentModule(
private val mcp: McpClient,
private val policy: SecurityPolicy
) : AgentModule {
override val name: String = "compose-mcp"
override suspend fun handle(task: AgentTask, context: AgentContext): AgentResult {
// 1. Policy prüfen
if (!policy.isAllowed(task, context)) {
return AgentResult.Error("Action not allowed by policy")
}
// 2. Nur whitelisted Aktionen
return when (task.type) {
"inspect-ui" -> inspectUi(task, context)
"take-screenshot"-> takeScreenshot(task, context)
"simulate-input" -> simulateInput(task, context)
"analyze-logs" -> analyzeLogs(task, context)
"hot-reload" -> performHotReload(task, context)
else -> AgentResult.Ignored("Unknown MCP task: ${task.type}")
}
}
}
SecurityPolicy‑Beispiele:
-
Nur bestimmte User dürfen
hot-reload -
Nur bestimmte Pfade dürfen
simulate-input - Rate‑Limit pro User/Session
- Keine freien Text‑Prompts → direkte MCP‑Calls
3. MCP‑Kommunikation: sicher und robust
Empfehlungen:
- mTLS zwischen Agent‑Backend und MCP‑Server
- Kurzlebige Tokens für MCP‑Requests
- Strikte JSON‑Schemas für alle Payloads
- Timeouts & Circuit‑Breaker (z.B. Resilience4j)
kotlin
class SecureHttpMcpClient(
private val baseUrl: String,
private val http: HttpClient
) : McpClient {
override suspend fun semanticTree(): SemanticNode =
http.get("$baseUrl/semanticTree") {
header("Authorization", "Bearer ${tokenProvider.token()}")
}.body()
// analog für screenshot, input, logs, hotReload }
4. Frontend‑Sicherheit (Website)
Minimal, aber wichtig:
- Content Security Policy (CSP) Nur eigene Scripts/Styles, keine Inline‑Eval.
- Keine direkten Agent‑Kontrollen im Browser Alles über Backend‑API mit Auth.
- CSRF‑Schutz bei POST‑Requests
- Strikte Fehler‑Maskierung (keine Stacktraces im Browser)
5. Resilienz gegen Angriffe
Typische Angriffe & Gegenmaßnahmen:
- Prompt‑Injection: Agent bekommt „mach Hot Reload“ → → Policy prüft, ob der User das darf → Task wird ggf. abgelehnt
- DoS über Agent‑Tasks: → Rate‑Limit pro IP/User → Queue mit Max‑Parallel‑Tasks
- MCP‑Missbrauch: → MCP‑Server nur intern erreichbar → Kein direkter Internet‑Zugriff → Logging aller Aktionen
- Datenlecks: → AgentResult filtert sensible Daten → Keine Roh‑Logs oder Screenshots an unprivilegierte User
6. Konkreter Minimal‑Stack (empfehlenswert)
- Backend: Kotlin + Spring Boot / Ktor
- Frontend: Minimalistisches HTML/JS, kein schweres CMS
-
Agent‑Engine: dein bestehendes System +
SecureMcpAgentModule - MCP‑Server: Compose Multiplatform 1.12, nur intern erreichbar
- Security: mTLS, JWT, CSP, Rate‑Limit, Policy‑Layer
Wenn du magst, können wir im nächsten Schritt:
-
eine konkrete API‑Spec für
/api/agent/taskausformulieren - ein Threat‑Model für dein Setup durchgehen
- oder ein Minimal‑Projektlayout (Ordnerstruktur, Module) für diese Website definieren.