Skip to content

Session enforcement

When a runtime is served to multiple callers — over MCP HTTP, or inside a multi-tenant app — isolation isn’t optional. KAOS enforces it at the boundary.

flowchart TB
    a["Caller A<br/><small>client_id = A</small>"] --> rt{{"KaosRuntime<br/>scopes by identity"}}
    b["Caller B<br/><small>client_id = B</small>"] --> rt
    rt --> sa["Session A<br/><small>memory · VFS · artifacts</small>"]
    rt --> sb["Session B<br/><small>memory · VFS · artifacts</small>"]

    classDef iso fill:#eef2ff,stroke:#6366f1,color:#1e1b4b;
    class sa,sb iso;

B asking for A’s resource gets the same “not found” as a truly-missing one — never “exists, but not yours.”

Calls carry an identity (client_id / request_id). The runtime scopes session memory, the virtual filesystem, and artifacts to that identity, so one caller can’t read another’s data. The single-user-chat reference app, for example, namespaces each session’s files and injects the right client_id per request.

Asked for a resource that doesn’t exist or that the caller isn’t allowed to see, the runtime returns the same not-found response. It never reveals “this exists but isn’t yours” — which would leak the existence of other tenants’ data.

The MCP HTTP transport (kaos-mcp --http, kaos-*-serve --http) requires an explicit auth token and refuses to run open by default. Exposing tools — some of which touch files, networks, or credentials — to an unauthenticated network endpoint is exactly the mistake the default guards against. (The token is an operator acknowledgement, not a substitute for real reverse-proxy auth in production.)

Isolation and auth live in the runtime and the bridge, not in each tool. So every tool a runtime exposes inherits the same boundary — you can’t forget to add it to a new tool.