stacklok / stacklok/toolhive

[vMCP] Implement resource exhaustion and DoS protection for session creation

Open
#3,874 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

api enhancement security vmcp
Dominant language
Go
Stars
2.2k
Forks
300
Avg merge
1d 15h
Merged PRs (30d)
184

Description

Depends on #3866

Session-scoped clients multiply backend connections (N sessions × M backends). Without limits, a burst of session creation requests can exhaust file descriptors or memory. Implement configurable limits to protect the system.

Global session limit:

  • Configurable via TOOLHIVE_MAX_SESSIONS (or equivalent config key)
  • When reached: reject new InitializeRequest with HTTP 503 and a Retry-After header
  • Error body: {"error": {"code": -32000, "message": "Maximum concurrent sessions exceeded. Please try again later or contact administrator."}}
  • No request queueing — reject immediately; Retry-After gives clients the retry signal
  • Do not expose current session count in the error response

Per-client session limit:

  • Configurable maximum sessions per client identity/IP
  • Enforced independently of the global limit

Idle session timeout:

  • Sessions inactive for a configurable period (e.g. 5 minutes with no incoming requests) should be expired proactively, independently of the global session TTL
  • This reclaims backend connections faster than waiting for the full TTL to elapse, reducing the steady-state connection count under low-traffic conditions
  • Idle timeout must reset on every request touching the session (i.e. any CallTool, ReadResource, or GetPrompt resets the idle clock)
  • Configurable separately from the session TTL; idle timeout must be shorter than or equal to TTL
Acceptance Criteria
  • A configurable global session limit exists and defaults to a documented value
  • Requests exceeding the limit receive HTTP 503 with a Retry-After header
  • The error response body does not include the current session count or any internal metrics
  • A configurable per-client session limit is enforced independently of the global limit
  • A configurable idle timeout exists and defaults to a documented value shorter than the session TTL
  • Sessions with no activity for longer than the idle timeout are expired and their backend clients closed
  • Any request to a session resets the idle clock
  • Idle timeout is enforced independently of — and cannot exceed — the session TTL
  • Requests within the limit are unaffected
  • Tests cover: 503 + Retry-After on global limit hit, per-client limit enforced, idle session expired after inactivity, active session not expired while in use, error response contains no internal data

RFC: THV-0038 — Session-scoped client lifecycle

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read the linked THV-0038 session-scoped client lifecycle RFC and resolve dependency #3866 first. Trace the session creation and request-handling entry points, then use the acceptance criteria as the definition of done, including limits, idle expiry, Retry-After behavior, and the listed tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
backend, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.