Skip to content

fix: restrict stateDelta from API endpoints to session scope#359

Open
g0w6y wants to merge 4 commits into
google:mainfrom
g0w6y:fix/statedelta-scope-escalation
Open

fix: restrict stateDelta from API endpoints to session scope#359
g0w6y wants to merge 4 commits into
google:mainfrom
g0w6y:fix/statedelta-scope-escalation

Conversation

@g0w6y
Copy link
Copy Markdown
Contributor

@g0w6y g0w6y commented May 19, 2026

What

/run and /run_sse accept a stateDelta field that is applied to
the session before the agent runs. The session service distinguishes
three state scopes by key prefix:

Prefix Scope
(none) current session only
user: all sessions for this user
app: all users of this app

There was no restriction on which prefixes callers could use. A caller
could send {"app:some_key": "value"} and write into the global
app-level state, which getSession() merges into every user's session
via mergeStates(). With DatabaseSessionService this is persisted
across server restarts.

Fix

Added toSessionScopedDelta() which strips any key starting with
app: or user: before the delta reaches the runner. Session-scope
keys (no prefix) pass through unchanged, so existing behavior for
normal use is unaffected.

Applied to both /run and /run_sse.

Why not filter in the runner or session service

The runner and session service are also used internally by agents and
tools that legitimately write cross-scope state. Filtering at the API
boundary is the right place — only user-supplied input from the HTTP
endpoints needs the restriction.

Testing

# app:-prefixed key is stripped — appState stays clean
curl -X POST /run -d '{"stateDelta":{"app:ctx":"injected",...}}'
# only session-scope keys survive

g0w6y and others added 4 commits May 19, 2026 14:45
Keys prefixed with app: and user: in stateDelta write into shared
app-level and cross-session user-level state, which gets merged into
every session via getSession(). Restricting the API endpoints to
session-scope keys only prevents callers from escalating writes
beyond their own session.
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.

3 participants