ADR-0069: Synapse-Owned Tool Access Policy¶
| Field | Value |
|---|---|
| Status | Accepted (Implemented) |
| Date | 2026-08-31 |
| Authors | Spector Maintainers & Architecture Working Group |
| Deciders | Spector Technical Steering Committee (TSC) |
| Supersedes | None |
| Superseded By | None |
| Last Verified | 2026-09-16 (Verified against main) |
1. Context¶
Issue #222 asks for least-privilege per-agent tool permission scoping (list filter + deny-on-execute).
AgentSoul (in spector-memory) is the agent’s identity — persona, purpose, values, optional capability hints. Tool authorization is an infrastructure / Synapse concern: which registered tools may this agent invoke at runtime.
Mixing access control into the soul record would:
- Couple memory identity to Synapse infra policy
- Tempt OpenAPI/SDK shape changes for security knobs
- Blur “who the agent is” with “what the host permits”
AgentSoul.tools may remain a declarative capability hint (Agent Card / planner prompts). It must not be the sole or authoritative security control for deny-on-execute.
2. Problem Statement¶
Exposing cognitive memory tools (e.g. remember, recall, forget, consolidate, search_graph) through Model Context Protocol (MCP) servers and REST APIs requires strict authorization control:
- Privilege Escalation Hazards: Untrusted external agent sessions must not be allowed to execute destructive administrative actions (e.g. purging historical partitions or modifying tenant identity schemas).
- Client-Side Enforcement Fallacy: Delegating tool filtering to client agent runtimes is unsafe, as compromised or hallucinating agents can invoke raw server endpoints directly.
- Tenant Boundary Leaks: Tool execution must be strictly scoped to the caller's authorized tenant and persona contexts.
3. Decision Drivers¶
- Server-Enforced Access Control: The gateway server (
spector-synapse) must own and enforce tool execution policies definitively. - Role-Based Tool Permissions: Categorize tools into permission tiers (
READ_ONLY,CONVERSATIONAL_WRITE,ADMINISTRATIVE). - Comprehensive Audit Logging: Record every tool invocation, parameters, calling identity, and policy evaluation result.
- Declarative Schema Support: Align with declarative tool specifications defined in ADR-0025.
4. Considered Options¶
Alternatives Evaluated¶
| Option | Why not |
|---|---|
Add allow/deny fields on AgentSoul | Couples identity to infra; memory module owns soul; User directive forbids |
Use only AgentSoul.tools as security allowlist | Treats capability hint as authorization; wrong module boundary |
| MCP/global tool gate only | Does not give per-agent least privilege |
5. Decision Outcome¶
Architectural Decisions¶
Implement #222 entirely inside Synapse:
- Authoritative store —
ToolAccessPolicy(name flexible) owned byspector-synapse, keyed by agent/soul id (or*), with allowlist and optional denylist of tool names. Load from classpath/config under Synapse (e.g.security/tool-access.ymlorapplication.ymlbinding), cached like other security policies. -
Enforcement points — Synapse only:
- List: filter tool specs offered to the LLM (
ToolRegistry/ graph resolve path) via the policy, not by mutatingAgentSoul. - Execute: deny-on-execute in
ToolExecutionNode/ToolRegistry.executewhen the tool is not permitted; clear permission error; never silent success.
- List: filter tool specs offered to the LLM (
-
AgentSoulimmutability for access — Do not addallowedTools/deniedTools(or equivalent) toAgentSoul. Do not move access fields into the memory module. Soul stays identity; access stays Synapse. - Intersection semantics (if soul.tools is non-empty) — Effective tools = Synapse policy ∩ soul.tools (when soul declares a hint list). If soul.tools is empty, Synapse policy alone applies. If no Synapse policy entry exists for the agent, default is configurable: recommend deny-all in STRICT / production, allow-all only for local/dev — default must be explicit in config.
- Public API — No new OpenAPI fields on AgentSoul. Optional Synapse admin/config endpoints later are out of scope for #222 unless needed for ops; v1 is config-file driven.
6. Pros and Cons of the Options¶
Consequences & Trade-offs¶
Positive
- Clear module boundary: memory = identity, synapse = access
- Matches Spector security pattern (classpath/cached policy under Synapse)
- Preserves optionality to evolve policy without soul version churn
Negative / risks
- Two lists to reason about (soul hint vs Synapse policy) — document intersection in code + issue AC
- Existing
AgenticChatGraph.resolveToolSpecssoul.tools filtering must be updated to consult Synapse policy (or compose with it) so list and execute cannot diverge
7. Implementation Plan¶
Implementation Guidelines for Maintainers¶
Rework #222 acceptance criteria away from “fields on AgentSoul.” Deliver Synapse ToolAccessPolicy + deny-on-execute + list filtering; keep soul unchanged. Tests: allow, deny, missing policy default, intersection with non-empty soul.tools.
8. Code Reference & Verification¶
All tool authorization mechanisms, filters, and policies are verified in the repository:
- Synapse Tool Handlers:
synapse/spector-synapse/src/main/java/com/spectrayan/spector/synapse/agent/tools/ - MCP Tool Specification:
synapse/spector-mcp/src/main/java/com/spectrayan/spector/mcp/spec/McpToolSpec.java