Skip to content

fix(seat-decisions): an agent key records and reads only its own agent's seat decisions (abilityai/trinity-enterprise#839) - #3355

Merged
vybe merged 1 commit into
devfrom
fix/ent839-seat-decisions-self-gate
Oct 8, 2026
Merged

vybe merged 1 commit into
devfrom
fix/ent839-seat-decisions-self-gate

Conversation

@dolho

@dolho dolho commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Summary

  • POST / GET /api/agents/{name}/decisions now 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, …).
  • The MCP tools record_decision and list_seat_decisions refuse a foreign agent_name from an agent-scoped key before calling the backend. The parameter stays for user-scoped keys, and its description now says so.
  • Authorization fix (CWE-863). It is present since ent#638 and not in v0.9.5.

Changes

  • src/backend/routers/seat_decisions.py: _self_gate, called first in both handlers.
  • src/mcp-server/src/tools/decisions.ts (+ test): foreignTarget refusal.
  • 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 of None.
  • 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.
  • Mutation: with the gate replaced by pass, both sibling cases go red (2 failed).
  • MCP decisions.test.ts: 7 passed (2 new).
  • test_2338_journey_catalog and the root-placement lint are green.

Follow-ups

Fixes abilityai/trinity-enterprise#839

🤖 Generated with Claude Code

…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 vybe left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merge-train: validated in the 2026-10-08 batch

@vybe
vybe merged commit 8b92254 into dev Oct 8, 2026
25 checks passed
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.

2 participants