Skip to content

security(daemon): hide shared Codex auth from model-authored tools #383

Description

@philz3906

Problem

AgentConnect's Linux shared-login path deliberately keeps the ACP runtime trusted:

  • the private CODEX_HOME/auth.json is a symlink to the exact host auth.json;
  • the outer SRT sandbox re-opens that exact file so Codex can authenticate and refresh it;
  • the host HOME and unrelated runtime state remain hidden.

That is sufficient for outer host isolation, but it does not separate the trusted Codex parent from model-authored local commands.

@agentclientprotocol/codex-acp@1.1.7 sends a legacy sandbox policy on every turn:

  • read-only -> readOnly
  • agent -> workspaceWrite
  • agent-full-access -> dangerFullAccess

The legacy read-only/workspace-write policies constrain writes, but allow reads of files visible to the Codex process. Because the outer sandbox intentionally exposes the shared auth.json, a model-authored command can read it. AgentConnect already records the file in protectedCredentialRoots, but only the Claude session path consumes those roots today.

This is not an outer SRT escape. It is the missing inner credential boundary inside the trusted Codex runtime namespace.

Verified capability and adapter gap

  • codex-acp 1.1.7 bundles @openai/codex ^0.145.0.
  • codex-acp upstream main still uses the same legacy per-turn sandboxPolicy path as of f41dcf16.
  • Codex 0.145 app-server supports the experimental named permissions field on thread start/resume, and Codex permission profiles support exact filesystem deny rules.
  • codex-acp already opts into the app-server experimental API, but it does not pass a permission-profile id on thread start/resume or mode changes. It also overrides each turn with the legacy policy.
  • Therefore adding default_permissions to CODEX_CONFIG alone is not a sufficient fix: the adapter's explicit legacy turn policy wins.

Primary references:

Implementation direction

  1. Keep codex-acp/Codex as the trusted parent and retain shared host login/refresh.
  2. Add codex-acp support for selecting a named permission profile on thread start, resume, and mode changes; omit the conflicting legacy sandbox field/policy while a profile is active.
  3. Build the profile only from daemon-owned protected credential roots. Agent config and model output must never supply host paths.
  4. Preserve the semantics of all three ACP modes while keeping credential paths denied, including agent-full-access.
  5. Preserve additional workspace directories, AgentConnect-injected MCP, account-app disabling, and session resume.
  6. Prefer an upstream codex-acp change. Do not add an AgentConnect terminal provider or credential broker unless the native permission-profile path proves insufficient.

Acceptance criteria

  • Host codex login, authentication status, token refresh, and subsequent sessions continue to work.
  • A Linux no-secret canary confirms model-authored commands cannot read either the private symlink or its host target.
  • read-only, agent, and agent-full-access retain their advertised write/network/approval behavior while the credential deny remains mandatory.
  • New, resumed, and mode-switched sessions apply the same protected profile.
  • The outer SRT boundary still denies the host HOME, daemon root, sibling agents, shared temp, and unrelated runtime state.
  • The validated/pinned codex-acp version includes the required permission-profile support.

Out of scope

  • A general credential broker/provider proxy.
  • Unsandboxed ACP runtimes.
  • macOS Keychain and Windows credential handling.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions