This is an automated email from the ASF dual-hosted git repository.

epugh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr-mcp.git


The following commit(s) were added to refs/heads/main by this push:
     new 38fca3d  docs(security): document STDIO transport security model (#119)
38fca3d is described below

commit 38fca3dc075bb89cc5098ca932b00368176966b7
Author: Aditya Parikh <[email protected]>
AuthorDate: Fri May 8 16:22:14 2026 -0400

    docs(security): document STDIO transport security model (#119)
    
    Adds docs/security/stdio.md capturing why STDIO mode intentionally has
    no in-process auth layer, with operational guidance and citations to the
    MCP specification (Authorization, Transports, Security Best Practices),
    Spring AI MCP Security docs, spring-ai-community/mcp-security, and
    relevant Spring Security/Boot references.
    
    Signed-off-by: adityamparikh <[email protected]>
    Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
---
 docs/security/stdio.md | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 98 insertions(+)

diff --git a/docs/security/stdio.md b/docs/security/stdio.md
new file mode 100644
index 0000000..74b3565
--- /dev/null
+++ b/docs/security/stdio.md
@@ -0,0 +1,98 @@
+# STDIO Transport — Security Model
+
+This document captures the security posture of the Solr MCP server when run in
+**STDIO mode** (the default), with citations to the primary specifications and
+framework guidance that justify it.
+
+## TL;DR
+
+In STDIO mode the server has **no in-process authentication or authorization,
+and that is intentional and spec-aligned**. Trust is inherited from the OS user
+that launched the process. No code changes are required for STDIO security.
+
+## Why STDIO has no auth layer
+
+| Property | Where it's set | Why it's safe |
+|---|---|---|
+| No network listener | `application-stdio.properties` → 
`spring.main.web-application-type=none` | No socket exists for a remote 
attacker to reach |
+| Communication is stdin/stdout only | MCP framing per spec | Only the parent 
process (e.g. Claude Desktop) can write to `stdin` |
+| Trust boundary = OS process owner | Launcher runs the binary | Same model as 
any local CLI; OS user permissions are the auth |
+| Spring Security autoconfig disabled | `application-stdio.properties` 
excludes `SecurityAutoConfiguration` and 
`ManagementWebSecurityAutoConfiguration` | Belt-and-suspenders; the filter 
chain has nothing to do without a servlet container |
+| `stdout` is reserved for JSON-RPC | `logback.xml` + empty 
`logging.pattern.console` (see [Logging Architecture in 
CLAUDE.md](../../CLAUDE.md#logging-architecture)) | Prevents log lines from 
being mis-parsed as MCP frames |
+
+## Operational guidance for STDIO deployments
+
+- **Do not run under a shared or elevated account.** The MCP tools execute with
+  the launcher's privileges. Run as the same unprivileged user that owns the
+  MCP client.
+- **Treat `SOLR_URL` as deployer-controlled config**, not user-controlled 
input.
+  It is read once at startup. Never wire it from an MCP tool argument.
+- **Scope the Solr instance.** STDIO mode delegates Solr-side authorization to
+  Solr itself (Basic Auth, mTLS, network policy). Point at a Solr that the
+  launching user is already authorized to use.
+- **Do not redirect stdout.** Stray writes to stdout corrupt the JSON-RPC
+  stream. Application logging in STDIO mode is suppressed for this reason; do
+  not add `System.out.println` or appenders that target stdout.
+
+## Primary sources
+
+### Model Context Protocol specification (2025-06-18)
+
+- **Authorization spec** — explicitly excludes STDIO from the OAuth flow:
+  > *"Implementations using an STDIO transport SHOULD NOT follow this
+  > specification, and instead retrieve credentials from the environment."*
+  >
+  > 
<https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization>
+
+- **Transports spec** — security warnings (Origin validation, localhost 
binding,
+  authentication) apply only to Streamable HTTP. STDIO has no auth section.
+  > <https://modelcontextprotocol.io/specification/2025-06-18/basic/transports>
+
+- **Security Best Practices** — recommends STDIO **as a mitigation** against
+  local-server compromise:
+  > *"MCP servers intending for their servers to be run locally SHOULD
+  > implement measures to prevent unauthorized usage from malicious
+  > processes: Use the `stdio` transport to limit access to just the MCP
+  > client […]"*
+  >
+  > 
<https://modelcontextprotocol.io/specification/2025-06-18/basic/security_best_practices>
+
+### Spring AI
+
+- **Spring AI MCP Security reference** — security module is HTTP-only:
+  > *"This module is compatible with Spring WebMVC-based servers only."*
+  >
+  > <https://docs.spring.io/spring-ai/reference/api/mcp/mcp-security.html>
+
+- **`spring-ai-community/mcp-security`** (the library backing
+  `org.springaicommunity:mcp-server-security`) — README documents Streamable
+  HTTP / stateless transport support; STDIO is out of scope by design because
+  `McpServerOAuth2Configurer` plugs into Spring Security's `HttpSecurity`
+  filter chain.
+  > <https://github.com/spring-ai-community/mcp-security>
+
+- **Spring Blog — *Securing Spring AI MCP servers with OAuth2*** (2025-04-02):
+  > *"MCP Servers can run locally, using the STDIO transport. To expose an MCP
+  > server to the outside world, it must expose a few standard HTTP 
endpoints."*
+  >
+  > <https://spring.io/blog/2025/04/02/mcp-server-oauth2/>
+
+- **Spring Blog — *Securing MCP Servers with Spring AI*** (2025-09-30):
+  > <https://spring.io/blog/2025/09/30/spring-ai-mcp-server-security/>
+
+### Spring Security / Spring Boot
+
+- **`SecurityAutoConfiguration` Javadoc** — only activates with a servlet web
+  application; inert when `spring.main.web-application-type=none`.
+  > 
<https://docs.spring.io/spring-boot/api/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfiguration.html>
+
+- **Spring Security Servlet Architecture** — the filter chain is built around
+  `HttpServletRequest`. Without a servlet container there is no chain to
+  configure.
+  > 
<https://docs.spring.io/spring-security/reference/servlet/architecture.html>
+
+## Related documents
+
+- HTTP transport security model — *planned, will live at 
`docs/security/http.md`*
+- [GraalVM native image spec](../specs/graalvm-native-image.md)
+- [Logging architecture in `CLAUDE.md`](../../CLAUDE.md#logging-architecture)

Reply via email to