Skip to content

Security Model & Trust Boundaries

litestar-mcp treats the Model Context Protocol (MCP), Agent-to-Agent (A2A 1.0) bindings, and background agent/task workers as transports into your Litestar application rather than separate security silos. Every tool, resource, prompt, and skill executes through Litestar's internal ASGI pipeline, inheriting your application's authentication middleware, route guards, and dependency injection graph.


1. End-to-End Security Pipeline

Authentication and authorization are separated into two explicit layers:

  1. Transport Authentication Boundary: Litestar middleware (or MCPStdioContext on local stdio) validates credentials at the edge and populates request.user, request.auth, and scope["litestar_security"].
  2. Handler & Domain Authorization: Internal ASGI synthesis (execute_tool, execute_prompt, execute_handler) and QueueTaskExecutor worker rehydration forward that validated identity into route guards, Provide / FromDishka[T] dependencies, and domain services that verify object ownership.
flowchart LR
    A["Inbound Transport (HTTP, Stdio, A2A)"] --> B["Authentication Middleware (request.user & request.auth)"]
    B --> C["ASGI Scope Synthesis & Worker Rehydration"]
    C --> D["Route Guards & DI Providers"]
    D --> E["Domain Object Authorization"]

2. Trust Boundaries by Transport & Execution Mode

The source of caller identity depends on how the request enters your application and whether execution stays in-process or crosses into a litestar-queues worker:

Transport / Execution Mode Entry Point Identity Source Scope & Context Populated Isolation Boundary
Streamable HTTP (2026-07-28, 2025-06-18, 2025-03-26) POST /mcp, DELETE /mcp Litestar AbstractAuthenticationMiddleware, OAuth2PasswordBearerAuth, litestar-security SecurityPlugin, or IAP assertion validator request.user, request.auth, scope["litestar_security"], forwarded HTTP headers Per-request ASGI scope; Origin header validated against MCPConfig.allowed_origins
In-Process Stdio litestar mcp stdio, run_stdio, MCP.run(transport="stdio") MCPStdioContext or CLI --header / --bearer-env / --bearer-cmd forwarded into internal ASGI scope scope["user"], scope["auth"], scope["litestar_mcp.owner_id"], scope["session"], scope["state"] Local OS process boundary; anonymous stdio receives owner_id=None (never a shared "stdio" owner)
HTTP-to-Stdio Bridge litestar mcp bridge, run_stdio_streamable_http_bridge Bearer token (--bearer-env, --bearer-cmd) or static headers (--header) sent over HTTPS to remote /mcp Validated on the remote Litestar server by its HTTP authentication middleware Untrusted client-side forwarder; all authentication and authorization happen on the target HTTP server
Distributed MCP Tasks (litestar-queues) QueueTaskExecutor (litestar_mcp.mcp.run_tool_task) extract_principal_snapshot at enqueue time -> rehydrate_security_scope or principal_loader in worker scope["user"] (Principal / user struct), scope["auth"], scope["litestar_security"] (SecurityContext), Dishka Scope.REQUEST TaskRecord.owner_id locks tasks/get, tasks/update, and tasks/cancel to the creating principal
Queued Agent Turns (litestar-queues) QueuedAgentChatController, QueuedTurnManager (litestar_mcp.agent.run_turn) PrincipalSnapshot (user_id, tenant, roles, scopes) serialized in QueuedTurn ToolContext(user=..., tenant_id=..., session_id=..., turn_id=...) SessionStore owner scoping and turn-scoped stream replay
A2A 1.0 Endpoints POST /a2a (JSON-RPC) & /a2a/message:send (HTTP+JSON REST) Litestar authentication middleware + A2AConfig.context_builder(request, context) ServerCallContext.user, ServerCallContext.tenant, ServerCallContext.state Multi-tenant path (/{tenant:str}) or X-A2A-Tenant header validated inside context_builder and owner-checked TaskStore

3. Transport Authentication vs Domain Object Authorization

Authenticating a caller and isolating their protocol-level task or session records does not prove that the caller is permitted to read or mutate the domain entity referenced in tool arguments.

Security Layer Question Answered Enforced By Example
Transport Authentication Who is the caller making this MCP, stdio, or A2A request? Litestar authentication middleware, litestar-security, MCPStdioContext Verifying a Bearer JWT or x-goog-iap-jwt-assertion header and binding request.user
Capability / Route Authorization Is this principal allowed to invoke this tool, prompt, or controller? Litestar Guard functions, MCPConfig.guards, MCPConfig.route_opt Checking that request.auth includes the report:read scope or admin role
Protocol Task & Session Isolation Did the caller create the taskId or session_id they are polling or cancelling? MCPTaskStore (TaskRecord.owner_id), SessionStore (owner_id), a2a-sdk task store Rejecting tasks/get when record.owner_id != current_owner_id
Domain Object Authorization Does the authenticated principal own or have access to the requested workspace_id, note_id, or file handle? Application Provide / FromDishka dependencies and repository queries (WHERE owner_sub = :sub) Verifying request.user.sub == workspace.owner_id before exporting a workspace

Never trust client-supplied identity fields in tool arguments

Treat tool arguments such as user_id, tenant_id, workspace_id, or file_path as untrusted selectors. Always compare them against server-validated identity on request.user, request.auth, scope["litestar_security"], or ToolContext.


4. Security & Operations Guides

Authentication Middleware, JWT & Google IAP

Configure Litestar AbstractAuthenticationMiddleware, OAuth2PasswordBearerAuth, Google Cloud IAP signed assertions, and MCPStdioContext.

Authentication Guide →

First-Party litestar-security Integration

Bind mechanism policies with MCPConfig(route_opt={"auth": required(...)}), publish RFC 9728 protected-resource metadata, and rehydrate SecurityContext in queue workers.

litestar-security Guide →

Authorization, Guards, Scopes & Input Safety

Enforce route guards, understand discovery-only tool scopes, protect multi-round requestState with AEAD/HMAC, and validate remote file/path arguments.

Authorization & Scopes →

OpenTelemetry Tracing & Tool Callbacks

Emit GenAI semantic convention spans with TelemetryConfig and SpanManager, and wire before_tool_call / after_tool_call audit hooks.

Observability Guide →

Migrating to v0.14–v0.18

Upgrade across the modular package layout, Litestar-native auth middleware, dual-version Streamable HTTP, A2A 1.0 REST, and zero-config litestar-queues execution.

v0.14–v0.18 Migration →

Migrating to v0.12 Stateless MCP

Historical reference for the stateless MCP 2026-07-28 transport, MCPTaskConfig, multi-round MCPInputRequiredResult, and subscriptions/listen.

v0.12 Migration →