Repository navigation
fix(seat-decisions): an agent key records and reads only its own agent's seat decisions (abilityai/trinity-enterprise#839) - #3355
Merged
Conversation
…t's seat decisions (trinity-enterprise#839)
POST and GET /api/agents/{name}/decisions authorized on
assert_agent_access alone. An agent-scoped key resolves to its owner
carrying the owner's role, so a sibling agent (and, under an admin owner,
any agent on the instance) could name another agent and one of its seat
runs: a forged active decision became standing instruction text in that
agent's system prompt, and the GET returned a person's criteria and notes
(CWE-863). Both handlers now self-gate first, before any lookup, as the
eight sibling modules do.
The MCP record_decision / list_seat_decisions tools refuse an agent_name
that is not the agent key's own before calling; the override stays for a
user-scoped key. ent#638's router tests now pass a person principal
instead of None.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
vybe
approved these changes
Oct 8, 2026
vybe
left a comment
Contributor
There was a problem hiding this comment.
merge-train: validated in the 2026-10-08 batch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
POST/GET /api/agents/{name}/decisionsnow refuse an agent-scoped key that names a different agent. The check is the first statement in each handler, before any lookup, the same self-gate the eight sibling agent-callable modules already carry (reminders._self_gate,public_memory, …).record_decisionandlist_seat_decisionsrefuse a foreignagent_namefrom an agent-scoped key before calling the backend. The parameter stays for user-scoped keys, and its description now says so.Changes
src/backend/routers/seat_decisions.py:_self_gate, called first in both handlers.src/mcp-server/src/tools/decisions.ts(+ test):foreignTargetrefusal.tests/unit/test_ent839_seat_decisions_self_gate.py: new, through the real router.tests/unit/test_ent638_seat_decisions.py: the router tests pass a person principal instead ofNone.docs/memory/feature-flows/workspace-seat-decisions.md,tests/registry.json.Test Plan
cd tests && pytest unit/test_ent839_seat_decisions_self_gate.py unit/test_ent638_seat_decisions.py: 54 passed.pass, both sibling cases go red (2 failed).decisions.test.ts: 7 passed (2 new).test_2338_journey_catalogand the root-placement lint are green.Follow-ups
GET /{agent_name}/seat-autonomyto this file. It gets the same gate once this lands.record_seat_decision. It needs a rebase check so the gate survives.Fixes abilityai/trinity-enterprise#839
🤖 Generated with Claude Code