Skip to content

security: add API key auth and user scoping to MCP server#28

Merged
marinone94 merged 1 commit into
mainfrom
fix/mcp-security
Mar 30, 2026
Merged

security: add API key auth and user scoping to MCP server#28
marinone94 merged 1 commit into
mainfrom
fix/mcp-security

Conversation

@marinone94

Copy link
Copy Markdown
Owner

Summary

  • SEC-C1 + LLM-H4: Add API key authentication for MCP HTTP mode (X-Api-Key header, Starlette middleware)
  • LLM-H5: Scope all collection tools to authenticated user in HTTP mode (list/create/get/add/export)
  • stdio mode remains unauthenticated (trusted local agent)

Files changed

  • mcp_server/server.py — auth middleware, context vars, user scoping on all collection tools
  • tests/unit/test_mcp_auth.py — 17 new tests covering auth + scoping

Test plan

  • uv run pytest passes (594 passed, 1 skipped)
  • MCP HTTP mode requires X-Api-Key when auth_enabled=True
  • Invalid/missing API key returns 401
  • Collections scoped to user in HTTP mode
  • stdio mode unchanged (all collections visible)

🤖 Generated with Claude Code

- Add `_resolve_user_from_api_key` helper: SHA-256 hash lookup against
  api_keys table, returns associated User or None for missing/inactive keys
- Add `_current_user` and `_current_transport` ContextVars to carry auth
  state into tool functions without threading issues
- Add `ApiKeyAuthMiddleware` (Starlette BaseHTTPMiddleware) that enforces
  X-Api-Key header on all HTTP requests when `settings.auth_enabled=True`;
  skips /health endpoint and no-ops when auth is disabled
- Add `_build_http_app()` that wraps FastMCP's streamable-http ASGI app
  with the auth middleware via Starlette mount
- Update `__main__` block: HTTP mode uses uvicorn + `_build_http_app()`;
  stdio mode runs as before (trusted local agent, no auth)
- Scope collection tools to authenticated user when `_current_user` is set:
  - `list_collections`: filters by user_id
  - `create_collection`: stamps user_id on new collection
  - `add_to_collection`, `get_collection`, `export_collection`,
    `export_collection_custom`: verify ownership, return 404-style error
    for cross-user access
- stdio mode (no user set) retains full unrestricted access
- Add 17 unit tests covering key resolution, scoping, and ownership checks

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@marinone94
marinone94 merged commit 77bfca3 into main Mar 30, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant