MCP Governance and Security Hardening
Securing the Model Context Protocol integration layer
The MCP integration layer went through six P0 governance controls (P0-1 to P0-6), moving from a half-finished state to production-grade multi-user isolation.
What was fixed
| ID | Vulnerability | Fix |
|---|---|---|
| M1 | Unauthenticated RCE (tool_layers had no authorization) | Authorization dependency added to the router; stdio restricted to admin |
| M2 | No allowlist for stdio command/args | Shell rejection table plus a command allowlist |
| M3 | The ToolRouter main path bypassed the firewall | Firewall converged into the call_tool main path |
| M4 | Governance pre-check extracted only four key names | Full-parameter scanning (scan_all) with graded fail-closed |
| M5 | The MCP client was a cross-user singleton | Firewall identity threaded per request (injected via ContextVar) |
| M6 | No reconnect, backoff, circuit breaking or health probing | Configuration converged and dead paths removed (further work planned in P1) |
| M7-M10 | Configuration forks / dead code / key-name bugs | Storage converged, lazy ToolEngine acquisition, server_id corrected |
Security architecture
request → JWT auth → role gate (admin/user) → firewall pre-check → parameter scan → audit persisted → execution
↓ ↓ ↓ ↓ ↓
L0 entry L1 isolation L2 output L3 audit L4 data
API
GET /api/v1/tool-layers/mcp-servers # list MCP servers (signed-in user)
POST /api/v1/tool-layers/mcp-servers # add an MCP (admin)
DELETE /api/v1/tool-layers/mcp-servers/{id} # delete (admin)
POST /api/v1/tool-layers/mcp/tool # call an MCP tool (full firewall scan)