mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-13 03:13:41 +08:00
* feat(mcp): forward authenticated user identity to opt-in STDIO MCP servers A STDIO MCP server is one shared subprocess per configuration; its env is fixed at spawn and STDIO has no per-request header channel, so per-user identity must travel in-band with each tool call. Previously nothing carried it, so an MCP server could not call its downstream REST backend on behalf of the acting user. Inject the authenticated username (from ToolExecutionContext) into each tool call's JSON arguments under the reserved key `__mateclaw_user__`, for servers an operator explicitly opts in via `mateclaw.mcp.identity-forward.servers` (by name or id). The MCP server reads/strips it and forwards on-behalf-of alongside its own backend API key. - McpIdentityForwardProperties: per-server opt-in allowlist (name or id). - IdentityForwardingToolCallback: wraps an MCP callback, merges the username into the args; injected by trusted code, overwrites any LLM-supplied value (no spoofing); forwards unchanged when there is no user or args aren't an object/are malformed. - McpClientManager: captures server names; wraps opt-in servers' callbacks inside the prefix wrapper (so name-prefixing / return-direct still see the raw delegate). Non-opt-in servers are untouched — username never leaks to them. - Tests: injection, LLM-value overwrite, empty/non-object/malformed inputs, no-user passthrough, opt-in matching by id/name. - Docs (zh/en mcp.md): opt-in config, `__mateclaw_user__` contract, FastMCP Python skeleton, trust model. Default off (empty allowlist) — zero behavior change for existing servers. Plaintext username suits a trusted-network REST backend keyed by an API key; a signed short-lived token is noted as the stronger-isolation follow-up. * feat(mcp): add signed-token trust model for MCP identity forwarding Plaintext username forwarding makes the REST backend trust an unverifiable assertion from the (shared, LLM-adjacent) MCP service — a confused-deputy model. Add an opt-in signed-token mode so identity crosses the trust boundary as a short-lived RS256 JWT the backend can verify with a public key. - McpIdentityForwardProperties: nested `token` config (enabled, issuer, ttl-seconds, key-id, private-key-pem, audiences) + USER_ARG/TOKEN_ARG keys. - McpIdentityForwardService: resolves the injection — plaintext username (__mateclaw_user__) when token mode off, else a minted RS256 JWT (__mateclaw_token__) with sub=user, aud=server, short exp, jti. Lazy key parse; fail-closed when token mode is on but the key is missing/unparseable (no silent downgrade to plaintext). Signs with MateClaw's private key so the backend only needs the public key (cannot mint/impersonate). - IdentityForwardingToolCallback: now delegates the what-to-inject decision to the service (keyed by per-server audience); static withClaim() keeps the JSON-merge logic (overwrites LLM-supplied key, leaves non-object/malformed args untouched). - McpClientManager: injects the service; passes service + audience through the wrap path for opt-in servers only. - Tests: token mint+verify (with an in-test RSA keypair, asserting sub/aud/iss/ exp/jti), plaintext mode, no-user and no-key fail-closed, audience resolution. - Docs (zh/en): token config, key generation, claims, REST-side verification example, public-key distribution + JWKS-endpoint follow-up. Default unchanged: token.enabled=false → plaintext (back-compat); whole feature still opt-in per server and off by default. |
||
|---|---|---|
| .. | ||
| src | ||
| Dockerfile | ||
| pom.xml | ||
| settings.xml | ||