Skip to content

Add opt-in IP allowlist + bearer token auth for MCP HTTP/WebSocket + tool execution #433

@Jordonh18

Description

@Jordonh18

Summary

Introduce optional authentication for MCP server when exposed over HTTP/WebSocket:

  • IP allowlist (default *, supports exact IP and CIDR)
  • Optional bearer token required for HTTP routes, WebSocket upgrades, and tool/resource execution
  • Unity UI “Auth” section to configure allowlist and token
  • MCP clients prompted for token when server signals auth is enabled

Background / Problem

The MCP server currently binds to 0.0.0.0 and exposes HTTP routes, WebSocket hub, and tool execution with no authentication. Anyone with network reach can register tools or invoke high-privilege tools (e.g., runtime compilation), leading to remote code execution.


Goals

  • Keep current “no-auth” behaviour unless explicitly enabled.
  • Provide defence-in-depth: IP filter at ingress + token check before tool/resource dispatch.
  • Minimal friction for users: simple token, flexible IP allowlist, clear UX in Unity UI and clients.
  • Backward compatible and easily documented.

Non-Goals

  • Full RBAC, mTLS, or per-project scoped tokens (could be future work).

Requirements

  • Config surface: auth_enabled (bool), allowed_ips (list; supports *, CIDR, single IP), auth_token (string from env/CLI/Unity UI). Empty token means “no token required.”
  • Ingress enforcement: Apply IP allowlist and token checks on HTTP routes and WebSocket upgrades; reject with 401/403 and clear messages.
  • Tool dispatch enforcement: Before executing any tool/resource, re-check token (prevents alternate path bypass).
  • Unity UI: New “Auth” section to edit allowlist and token; default allowlist *; token optional.
  • Client behaviour: When auth is enabled, server signals “auth required” so MCP clients prompt and send Authorization: Bearer <token>.
  • Observability: Startup log stating auth state and allowlist; warn if auth enabled but token empty.
  • Docs: How to enable, sample config, client usage.

Proposed Approach

  1. Config wiring
    Add fields: auth_enabled, allowed_ips, auth_token.
    Sources: env vars, CLI flags.

  2. Ingress middleware (HTTP + WebSocket)
    Check IP allowlist.
    If auth enabled and token set, require bearer token.
    Respond with 401/403 when necessary.

  3. Tool dispatch hook
    Enforce same token check before executing any tool/resource.

  4. Unity UI
    New “Auth” panel with allowlist and masked token field.

  5. Client signal
    Handshake/meta flag for “auth_required”.

  6. Docs & examples
    Clear README and UI steps.


Config Examples

  • Env:

    • UNITY_MCP_AUTH_ENABLED=1
    • UNITY_MCP_ALLOWED_IPS=127.0.0.1,10.0.0.0/8
    • UNITY_MCP_AUTH_TOKEN=supersecret
  • CLI:

    • mcp-for-unity --transport http --http-url http://localhost:8080 --auth-enabled --auth-token duq3NNkWiiarxEETlwpoZFiyn0GCzaVGNva2RMn/y6g --allowed-ip *

Testing (targeted)

  • Allowlist:
    • Accept request from allowed IP; reject from non-allowed.
    • CIDR match pass/fail.
  • Token:
    • 401 on missing/incorrect token when enabled.
    • Pass with correct bearer.
  • Tool dispatch:
    • Direct tool call without token rejected even if route passed.
  • WebSocket:
    • Upgrade denied without token when enabled; allowed with correct token.
  • Regressions:
    • Auth disabled: legacy behaviour intact.

Rollout / Risk

  • Backward compatibility: auth disabled by default.
  • Minimal risk to existing users; new checks only when enabled.
  • Potential usability risk if users enable auth but forget token—mitigated with clear startup logs and 401 messaging.

Open Questions

  • Default allowlist: keep * or prefer RFC1918 by default?
  • Should empty token + enabled be permitted, or warn+block? (suggest warn but allow)
  • Should plugins use a separate token vs. shared token?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions