Security: guest/public principals and tool capability isolation for service-plugin turns #223

Open
opened 2026-09-02 17:27:43 +00:00 by nsaspy · 0 comments
Owner

zara-discord currently submits Discord turns through PluginRuntime.dispatch(SubmitTurn(...)), which executes under the RuntimeHost's bound principal. That means a public Discord user can reach the same backend/tool/memory surface as the local operator unless every tool independently defends against it.

This is not a prompt-level privacy problem; it needs a structural capability boundary.

Required design

  • Service plugins must be able to submit a turn under a constrained derived principal/capability profile without choosing arbitrary ownership.
  • Public/guest turns must not inherit operator-private memory, conversation history, files, account data, or privileged tools.
  • Tool registry/selection must enforce per-turn capabilities; prompt instructions are not an authorization layer.
  • Memory/session/conversation persistence must remain principal-owned per #131 invariants.
  • Service plugin may supply an untrusted external subject identifier (e.g. Discord guild/channel/user) only as namespaced metadata; runtime maps it to an opaque derived principal and prevents cross-subject state access.
  • Event subscriptions and reconnect paths must preserve the same derived principal.
  • Audit records should contain bounded opaque IDs and action outcomes, not raw external usernames/message content.

Acceptance tests

  1. A Discord guest turn cannot call/read operator memory tools or operator files even if the user explicitly asks for them or prompt-injects the model.
  2. Two Discord users in the same channel cannot see each other's durable conversation/memory state.
  3. A guest turn can use explicitly granted plugin tools such as scoped Discord moderation while privileged local-only tools remain unavailable.
  4. A service plugin cannot forge another principal or escalate its capability profile.
  5. Existing single-user/local RuntimeHost behavior remains compatible.

Related plugin work: lost-rob0t/zara-plugins#26.

`zara-discord` currently submits Discord turns through `PluginRuntime.dispatch(SubmitTurn(...))`, which executes under the RuntimeHost's bound principal. That means a public Discord user can reach the same backend/tool/memory surface as the local operator unless every tool independently defends against it. This is not a prompt-level privacy problem; it needs a structural capability boundary. ## Required design - Service plugins must be able to submit a turn under a constrained derived principal/capability profile without choosing arbitrary ownership. - Public/guest turns must not inherit operator-private memory, conversation history, files, account data, or privileged tools. - Tool registry/selection must enforce per-turn capabilities; prompt instructions are not an authorization layer. - Memory/session/conversation persistence must remain principal-owned per #131 invariants. - Service plugin may supply an untrusted external subject identifier (e.g. Discord guild/channel/user) only as namespaced metadata; runtime maps it to an opaque derived principal and prevents cross-subject state access. - Event subscriptions and reconnect paths must preserve the same derived principal. - Audit records should contain bounded opaque IDs and action outcomes, not raw external usernames/message content. ## Acceptance tests 1. A Discord guest turn cannot call/read operator memory tools or operator files even if the user explicitly asks for them or prompt-injects the model. 2. Two Discord users in the same channel cannot see each other's durable conversation/memory state. 3. A guest turn can use explicitly granted plugin tools such as scoped Discord moderation while privileged local-only tools remain unavailable. 4. A service plugin cannot forge another principal or escalate its capability profile. 5. Existing single-user/local RuntimeHost behavior remains compatible. Related plugin work: lost-rob0t/zara-plugins#26.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
nsaspy/zara#223
No description provided.