Expose trusted persistent agent homes to native Codex shells

This commit is contained in:
Dotta committed 2026-10-10 09:11:24 -05:00
1 parent 440482b396
commit 63a9e1a168
3 files changed
+18 -1

No files matched your search

@@ -1,3 +1,4 @@
import { createRunnerdCodexAppServerArgs } from "../live/runnerd-codex-transport.js";
import {
chmod,
lstat,
@@ -517,3 +518,12 @@ command = "untrusted-command"
await expect(stat(join(symlinkCodexHome, "auth.json"))).rejects.toThrow();
});
});
it("exposes a trusted persistent personal directory without instruction files", () => {
const options = { environment: { AGENT_HOME: "/untrusted", HOME: "/ambient" }, codexHome: "/private-provider" };
const supplied = createRunnerdCodexAppServerArgs({ ...options, persistentAgentHome: "/personal/agent" }).join("\n");
expect(supplied).toContain('AGENT_HOME="/personal/agent"');
expect(supplied).toContain('"/private-provider"="none"');
expect(supplied).not.toContain('AGENT_HOME="/untrusted"');
expect(createRunnerdCodexAppServerArgs(options).join("\n")).not.toContain("AGENT_HOME");
});
@@ -1207,6 +1207,8 @@ export interface CapabilityRunnerdProcessEvidence {
export interface CapabilityRunnerdCodexTransportOptions {
/** Server-authorized local computer MCP on the selected execution environment. */
computerTool?: { command: string; args: readonly string[] } | null;
/** Controller-authorized durable personal directory, independent of instructions. */
persistentAgentHome?: string;
provider?: "codex" | "opencode" | "claude_managed" | "aws_agentcore" | "acpx";
opencodePermissionMode?: NativeOpenCodePermissionMode;
acpxAgent?: QualifiedAcpxAgent;
@@ -3447,6 +3449,7 @@ export function createRunnerdCodexAppServerArgs(input: {
codexCommand?: string;
readOnlyRoots?: string[];
instructionWorkingCopyRoot?: string;
persistentAgentHome?: string;
}): string[] {
// The filesystem policy denies HOME and CODEX_HOME to keep credentials and
// runner state outside provider reach. Always bind those names to the actual
@@ -3457,9 +3460,10 @@ export function createRunnerdCodexAppServerArgs(input: {
...input.environment,
HOME: input.codexHome,
CODEX_HOME: input.codexHome,
...(input.persistentAgentHome ? { AGENT_HOME: input.persistentAgentHome } : {}),
},
[...(input.readOnlyRoots ?? []), ...codexExecutableReadOnlyRoots(input.environment ?? {}, input.codexCommand)],
input.instructionWorkingCopyRoot,
input.instructionWorkingCopyRoot ?? input.persistentAgentHome,
);
}
@@ -4969,6 +4973,7 @@ class DurablePrpCodexTransport implements CodexAppServerTransport {
codexHome,
codexCommand: effectiveCodexCommand,
instructionWorkingCopyRoot: runtimeContext?.instructions.workingCopy?.rootPath,
persistentAgentHome: this.options.persistentAgentHome,
readOnlyRoots: [
...trustedRuntimeReadOnlyRoots(
this.options.environment,
@@ -5453,6 +5458,7 @@ class DurablePrpCodexTransport implements CodexAppServerTransport {
codexHome,
codexCommand: typeof recordedCommand === "string" ? recordedCommand : this.options.codexCommand,
instructionWorkingCopyRoot: runtimeContext?.instructions.workingCopy?.rootPath,
persistentAgentHome: this.options.persistentAgentHome,
readOnlyRoots: [
...trustedRuntimeReadOnlyRoots(this.options.environment),
...(runtimeContext
@@ -13411,6 +13411,7 @@ async function createRunnerdBackendWithinSessionClaim(
resumeWorkingDirectory: runnerExecution.workspace.cwd,
externallySandboxed: adapterExecutionTargetIsCommandBacked(remoteTarget),
computerTool: remoteTarget?.transport === "computer" ? remoteTarget.computerTool : undefined,
persistentAgentHome: remoteTarget?.transport === "computer" ? remoteTarget.fileAuthority.agentHome : undefined,
opencodeRuntimeDirectory: remoteRunnerFilesystemRoot
? posix.join(remoteRunnerFilesystemRoot, "opencode")
: undefined,