fix(gateway): enforce owner boundary for agent runs

This commit is contained in:
Peter Steinberger
2026-03-02 00:27:32 +00:00
parent 9005e8bc0a
commit 58659b931b
10 changed files with 123 additions and 1 deletions

View File

@@ -188,6 +188,30 @@ describe("agentCommand", () => {
});
});
it("defaults senderIsOwner to true for local agent runs", async () => {
await withTempHome(async (home) => {
const store = path.join(home, "sessions.json");
mockConfig(home, store);
await agentCommand({ message: "hi", to: "+1555" }, runtime);
const callArgs = vi.mocked(runEmbeddedPiAgent).mock.calls.at(-1)?.[0];
expect(callArgs?.senderIsOwner).toBe(true);
});
});
it("honors explicit senderIsOwner override", async () => {
await withTempHome(async (home) => {
const store = path.join(home, "sessions.json");
mockConfig(home, store);
await agentCommand({ message: "hi", to: "+1555", senderIsOwner: false }, runtime);
const callArgs = vi.mocked(runEmbeddedPiAgent).mock.calls.at(-1)?.[0];
expect(callArgs?.senderIsOwner).toBe(false);
});
});
it("resumes when session-id is provided", async () => {
await withTempHome(async (home) => {
const store = path.join(home, "sessions.json");

View File

@@ -163,6 +163,7 @@ function runAgentAttempt(params: {
onAgentEvent: (evt: { stream: string; data?: Record<string, unknown> }) => void;
primaryProvider: string;
}) {
const senderIsOwner = params.opts.senderIsOwner ?? true;
const effectivePrompt = resolveFallbackRetryPrompt({
body: params.body,
isFallbackRetry: params.isFallbackRetry,
@@ -209,7 +210,7 @@ function runAgentAttempt(params: {
currentThreadTs: params.runContext.currentThreadTs,
replyToMode: params.runContext.replyToMode,
hasRepliedRef: params.runContext.hasRepliedRef,
senderIsOwner: true,
senderIsOwner,
sessionFile: params.sessionFile,
workspaceDir: params.workspaceDir,
config: params.cfg,

View File

@@ -60,6 +60,8 @@ export type AgentCommandOpts = {
accountId?: string;
/** Context for embedded run routing (channel/account/thread). */
runContext?: AgentRunContext;
/** Whether this caller is authorized for owner-only tools (defaults true for local CLI calls). */
senderIsOwner?: boolean;
/** Group id for channel-level tool policy resolution. */
groupId?: string | null;
/** Group channel label for channel-level tool policy resolution. */