Frontmatter
| id | 10146 |
| title | Cross-tenant permission edges + multi-tenant validation test suite |
| state | Closed |
| labels | enhancementaitestingarchitecturecore |
| assignees | neo-gemini-pro |
| createdAt | Apr 21, 2026, 11:29 AM |
| updatedAt | May 20, 2026, 11:01 PM |
| githubUrl | https://github.com/neomjs/neo/issues/10146 |
| author | tobiu |
| commentsCount | 0 |
| parentIssue | 10016 |
| subIssues | [] |
| subIssuesCompleted | 0 |
| subIssuesTotal | 0 |
| blockedBy | [x] 10145 OAuth2 authentication layer for Memory Core MCP connections, [x] 10144 AgentIdentity node type + GitHub account binding for model identities |
| blocking | [ ] 10139 Extend Memory Core with Explicit A2A Primitive |
| closedAt | Apr 21, 2026, 11:25 PM |
Cross-tenant permission edges + multi-tenant validation test suite
tobiu added parent issue #10016 on Apr 21, 2026, 11:32 AM
tobiu marked this issue as being blocked by #10144 on Apr 21, 2026, 11:33 AM
tobiu marked this issue as being blocked by #10145 on Apr 21, 2026, 11:33 AM
tobiu marked this issue as blocking #10139 on Apr 21, 2026, 11:33 AM
tobiu cross-referenced by #10016 on Apr 21, 2026, 4:28 PM
tobiu cross-referenced by PR #10162 on Apr 21, 2026, 4:54 PM
tobiu cross-referenced by #9999 on Apr 21, 2026, 7:03 PM
tobiu cross-referenced by #10145 on Apr 21, 2026, 8:43 PM
tobiu cross-referenced by PR #10166 on Apr 21, 2026, 9:06 PM
tobiu cross-referenced by #10139 on Apr 21, 2026, 10:27 PM
tobiu cross-referenced by #10147 on Apr 21, 2026, 10:30 PM
tobiu cross-referenced by PR #10167 on Apr 21, 2026, 10:55 PM
tobiu cross-referenced by #10168 on Apr 21, 2026, 11:24 PM
tobiu cross-referenced by #10169 on Apr 21, 2026, 11:24 PM
tobiu closed this issue on Apr 21, 2026, 11:25 PM
tobiu assigned to @neo-gemini-pro on May 20, 2026, 11:01 PM
Cross-tenant permission edges + multi-tenant validation test suite
Context
Once OAuth2 MC auth lands and AgentIdentity nodes populate, multi-tenant boundaries become enforceable. This ticket adds the cross-tenant permission edge type + the test suite validating isolation + reach. The test suite is load-bearing for #9999 — production-shape validation, with mailbox as workload.
Scope-rebalance note (2026-04-21, session
d69ac7a0-9fe8-4416-b766-cd9edb8bee71): relocated AC #5 from #10147 ("Permission check integration: caller-identity = SENT_BY on write; read scoped to tenant + permission edges") into this ticket. Rationale: #10147 ships the Message schema + 4 core tools with server-stampedSENT_BYbut without cross-tenant read-scoping via permission edges. This ticket adds theCAN_READ_*/CAN_REPLY_TOedge types and wires them into mailbox read paths atop the already-landed primitives. Splitting this way avoids circular PR dependency and addresses the Stage 3 scope-overlap concern I flagged in my epic-review on #10016 ("#10146 bundles permission-edge implementation and cross-cutting test suite — bundling risks weak coverage for whichever half loses the scope-contest"). The split now makes the two concerns symmetrical: #10147 = mailbox primitives, #10146 = tenant-boundary enforcement on those primitives.The Problem
Tenancy without explicit grants: either strict isolation (no A2A cooperation) or implicit trust via shared tenancy. Both break MX at swarm scale — multi-agent A2A needs selective cross-tenant reach (Opus-4-7 reading Gemini-3-1-pro's mailbox) by explicit consent only.
The Architectural Reality
RequestContextService(#10145 ✓ shipped).Messagenode + 4 MCP tools) land in #10147 — the workload this ticket's permission-edge-check middleware protects.The Fix
CAN_READ_INBOX_OF,CAN_READ_MEMORIES_OF,CAN_READ_SESSIONS_OF,CAN_REPLY_TO— allAgentIdentity_A → AgentIdentity_BlistMessages/getMessageon inbox whereSENT_TO = caller→ always allowed (own data)listMessages/getMessageon inbox whereSENT_TO = other→ requiresCAN_READ_INBOX_OFedge from caller to targetaddMessagewithto = other-identity→ requiresCAN_REPLY_TOedge if the addressee is not already a reachable counterpartygrantPermission(from, to, scope),revokePermission,listPermissions(for: identity)test/playwright/unit/ai/mcp/server/memory-core/:listMessages({to: me})scopes to callerfrom: Bby identity A fails auth (already landed in #10145'sAuthMiddleware; this suite confirms integration)Acceptance Criteria
CAN_READ_INBOX_OF,CAN_READ_MEMORIES_OF,CAN_READ_SESSIONS_OF,CAN_REPLY_TO)AuthMiddleware(#10145) +RequestContextService(#10000 + #10145) stackSENT_BYon write; read paths scope to tenant + check permission edges for cross-tenant reachlearn/agentos/or extendsMemoryCoreMcpAuth.mdOut of Scope
Avoided Traps
callTooldispatch path alongsideAuthMiddleware(shipped in #10145) so the permission model and the anti-spoof model share a single integration point.Related
test/playwright/unit/ai/mcp/server/memory-core/Origin Session ID:
71dc3cd8-d39d-48e1-ac62-e240ca67d1a5(ticket creation) Reshape Session ID:d69ac7a0-9fe8-4416-b766-cd9edb8bee71(scope rebalance 2026-04-21, Claude Opus 4.7 / Claude Code)