Sign inSign up

docker/sbx-kit-codex-acp-set:1.0.7

Multi-platform
Manifest digest

sha256:1f7829c3351fd1f3d3b41de238b5a1d6918c7a23723f36cc18a8592720a46e20

Last pushed

5 days by cdupuis

Type

Sandbox Kit

Manifest digest

sha256:1f7829c3351fd1f3d3b41de238b5a1d6918c7a23723f36cc18a8592720a46e20

yaml
schemaVersion: "3"
displayName: Codex over ACP
author: Docker, Inc.
description: 'A sandbox an ACP client can drive: a shell base, Codex CLI, and the Agent Client Protocol adapter that fronts it — published as one kit. The same three kits compose by hand; this exists so an editor can be pointed at one reference instead of three that have to agree.'
sourceUrl: https://github.com/docker/sandbox-kit-spec
version: 1.0.7
licenses:
    - Apache-2.0
kind: workload
provides:
    - [email protected]
    - [email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/ca-certificates-java@20240118
    - deb/ca-certificates@20250419
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/iputils-ping@20240905
    - deb/[email protected]
    - deb/[email protected]
    - deb/less@668
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
    - deb/[email protected]
capabilities:
    - group:
        capabilities:
            - source:
                kit: docker.io/docker/sbx-kit-codex-mixin:0.166.0
                path: capabilities[0]
              type: com.docker.sandbox/network-policy@1
              config:
                runtime:
                    allow:
                        - api.openai.com:443
                        - openai.com:443
                        - auth.openai.com:443
                        - chatgpt.com:443
                        - files.openai.com:443
                        - releases.openai.com:443
                        - api.github.com:443
                        - github.com:443
                        - release-assets.githubusercontent.com:443
                        - codeload.github.com:443
      declarationBlocks:
        - "0:0"
      source:
        kit: docker.io/docker/sbx-kit-codex-mixin:0.166.0
        path: capabilities[0]
    - group:
        description: OpenAI API access (API key or ChatGPT OAuth)
        optional: true
        capabilities:
            - source:
                kit: docker.io/docker/sbx-kit-codex-mixin:0.166.0
                path: capabilities[1]
              type: com.docker.sandbox/credential@1
              config:
                apiKey:
                    inject:
                        - domain: api.openai.com
                          format: Bearer %s
                          header: Authorization
                        - domain: openai.com
                          format: Bearer %s
                          header: Authorization
                    name: OPENAI_API_KEY
                    proxyManaged: true
                oauth:
                    resourceHosts:
                        - chatgpt.com
                    sentinels:
                        accessToken: oai-oat01-proxy-managed
                        refreshToken: oai-ort01-proxy-managed
                    tokenEndpoint:
                        host: auth.openai.com
                        path: /oauth/token
                phase: runtime
                service: openai
              description: OpenAI API access (API key or ChatGPT OAuth)
      declarationBlocks:
        - "0:0"
      source:
        kit: docker.io/docker/sbx-kit-codex-mixin:0.166.0
        path: capabilities[1]
    - group:
        capabilities:
            - source:
                kit: docker.io/docker/sbx-kit-codex-mixin:0.166.0
                path: capabilities[2]
              type: com.docker.sandbox/lifecycle@1
              config:
                install:
                    - command: |
                        set -e
                        mkdir -p /home/agent/.codex /home/agent/.agents
                        MODE="${SBX_CRED_OPENAI_MODE:-none}"
                        cat > /home/agent/.codex/config.toml << 'EOF'
                        # Codex configuration for Docker sandbox
                        # This configuration enables "yolo mode" - no approvals, full access

                        approval_policy = "never"
                        sandbox_mode = "danger-full-access"
                        mcp_oauth_credentials_store = "file"
                        # Turn-complete hook for Narwhal (see /usr/local/bin/sbx-codex-hook):
                        # raises the desktop notification and forwards the session's model,
                        # effort, token usage and git state read from this thread's rollout
                        # file. `notify` is top-level and needs no hook trust; Codex spawns
                        # it fire-and-forget with the event JSON as the last argument, and
                        # the script is a silent no-op when no desktop server is loaded.
                        notify = ["/usr/local/bin/sbx-codex-hook", "codex"]
                        EOF
                        # Model selection from the create-phase args. These are
                        # top-level keys, so they must land here, before the
                        # model_providers and projects tables below would capture
                        # them. The args' patterns admit no quote or backslash, so
                        # the expanded value is safe inside the TOML string.
                        model=''
                        effort=''
                        [ -z "$model" ] || printf 'model = "%s"\n' "$model" >> /home/agent/.codex/config.toml
                        [ -z "$effort" ] || printf 'model_reasoning_effort = "%s"\n' "$effort" >> /home/agent/.codex/config.toml
                        # Managed modes must not let remote clients replace the proxy
                        # placeholder with sandbox-local ChatGPT OAuth. None mode
                        # deliberately permits login.
                        case "$MODE" in
                          oauth|apikey)
                            cat >> /home/agent/.codex/config.toml << 'EOF'
                        forced_login_method = "api"
                        EOF
                            ;;
                        esac
                        if [ "$MODE" = oauth ]; then
                          cat >> /home/agent/.codex/config.toml << 'EOF'

                        model_provider = "sandboxd"

                        [model_providers.sandboxd]
                        name = "Sandbox Proxy"
                        base_url = "https://chatgpt.com/backend-api/codex"
                        experimental_bearer_token = "oai-oat01-proxy-managed"
                        requires_openai_auth = false
                        EOF
                        fi
                        # Pre-trust the workspace so codex skips its "do you trust this
                        # directory" onboarding — the v2 kit skipped it via its
                        # --dangerously-bypass-approvals-and-sandbox entrypoint, which a
                        # mixin (plain `codex` from the base shell) doesn't have. MUST
                        # stay after every top-level key append: [projects."…"] opens a
                        # TOML table, and any key appended after it would silently land
                        # inside that table (which is exactly how model_provider once
                        # vanished, sending codex to api.openai.com with a ChatGPT
                        # token and a scopes 401).
                        ws="${WORKSPACE_DIR:-/home/agent/workspace}"
                        esc=$(printf '%s' "$ws" | sed 's/\\/\\\\/g; s/"/\\"/g')
                        cat >> /home/agent/.codex/config.toml <<EOF

                        [projects."$esc"]
                        trust_level = "trusted"
                        EOF
                        case "$MODE" in
                          oauth|apikey)
                            cat > /home/agent/.codex/auth.json << 'EOF'
                        {
                          "OPENAI_API_KEY": "proxy-managed"
                        }
                        EOF
                            ;;
                          *)
                            rm -f /home/agent/.codex/auth.json
                            ;;
                        esac
                      description: Seed Codex config/auth from SBX_CRED_OPENAI_MODE
                      env:
                        - SBX_CRED_OPENAI_MODE
                        - WORKSPACE_DIR
                      user: agent
                startup:
                    - command: |
                        set -e
                        [ -n "$MCP_GATEWAY_URL" ] || exit 0
                        cfg="$HOME/.codex/config.toml"
                        touch "$cfg"
                        grep -q "^\[mcp_servers.mcp-gateway\]" "$cfg" && exit 0
                        esc() { printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g'; }
                        url=$(esc "$MCP_GATEWAY_URL")
                        auth=$(esc "$MCP_SENTINEL_TOKEN_NAME")
                        # Codex's grammar for a streamable HTTP server: the transport
                        # is implied by `url` (a `command` would make it stdio; there
                        # is no `type` key), and static headers go in `http_headers`.
                        # A `[...headers]` sub-table is not read, so the gateway
                        # would be reached without its bearer token and codex would
                        # warn about both keys at startup.
                        cat >> "$cfg" <<EOF

                        [mcp_servers.mcp-gateway]
                        url = "$url"
                        http_headers = { Authorization = "Bearer $auth" }
                        EOF
                      description: Register the sandbox MCP gateway in ~/.codex/config.toml
                      env:
                        - MCP_GATEWAY_URL
                        - MCP_SENTINEL_TOKEN_NAME
                      user: agent
      declarationBlocks:
        - "0:0"
      source:
        kit: docker.io/docker/sbx-kit-codex-mixin:0.166.0
        path: capabilities[2]
    - group:
        optional: true
        capabilities:
            - source:
                kit: docker.io/docker/sbx-kit-codex-mixin:0.166.0
                path: capabilities[3]
              type: com.docker.sandbox/agent-skills@1
              config:
                path: /home/agent/.agents/skills
      declarationBlocks:
        - "0:0"
      source:
        kit: docker.io/docker/sbx-kit-codex-mixin:0.166.0
        path: capabilities[3]
    - group:
        optional: true
        capabilities:
            - source:
                kit: docker.io/docker/sbx-kit-codex-mixin:0.166.0
                path: capabilities[4]
              type: com.docker.sandbox/agent-context@1
              config:
                contentFile: /usr/share/sandbox/kit/codex-acp-set/context.md.parts/0.md
                directory: /home/agent/.codex
                filename: AGENTS.md
      declarationBlocks:
        - "0:0"
      source:
        kit: docker.io/docker/sbx-kit-codex-mixin:0.166.0
        path: capabilities[4]
    - group:
        optional: true
        capabilities:
            - source:
                kit: docker.io/docker/sbx-kit-codex-mixin:0.166.0
                path: capabilities[5]
              type: com.docker.sandbox/agent-context@2
              config:
                content: |
                    Codex CLI is installed at `/usr/local/bin/codex`. Run `codex` for an
                    interactive session or `codex exec "<prompt>"` for a one-shot run.

                    Authentication is proxy-mediated: `OPENAI_API_KEY` in this container is a
                    sentinel — the sandbox proxy substitutes the real key bound on the host
                    (`sbx secret set openai`) on requests to `api.openai.com`. Without a
                    bound key, `codex` will ask you to log in.
                directory: /home/agent/.codex
                filename: AGENTS.md
      declarationBlocks:
        - "0:0"
      source:
        kit: docker.io/docker/sbx-kit-codex-mixin:0.166.0
        path: capabilities[5]
    - group:
        description: Drive codex sessions over the Agent Client Protocol
        optional: true
        capabilities:
            - source:
                kit: docker.io/docker/sbx-kit-codex-acp:2.5.0
                path: capabilities[0]
              type: com.docker.sandbox/acp@1
              config:
                agent: codex
                command:
                    - codex-acp
                env:
                    INITIAL_AGENT_MODE: agent-full-access
              description: Drive codex sessions over the Agent Client Protocol
      declarationBlocks:
        - "1:0"
      source:
        kit: docker.io/docker/sbx-kit-codex-acp:2.5.0
        path: capabilities[0]
    - group:
        optional: true
        capabilities:
            - source:
                kit: docker.io/docker/sbx-kit-codex-acp:2.5.0
                path: capabilities[1]
              type: com.docker.sandbox/agent-context@1
              config:
                contentFile: /usr/share/sandbox/kit/codex-acp-set/context.md.parts/1.md
      declarationBlocks:
        - "1:0"
      source:
        kit: docker.io/docker/sbx-kit-codex-acp:2.5.0
        path: capabilities[1]
    - group:
        optional: true
        capabilities:
            - source:
                kit: docker.io/docker/sbx-kit-codex-acp:2.5.0
                path: capabilities[2]
              type: com.docker.sandbox/agent-context@2
              config:
                content: |
                    ## Codex ACP adapter

                    `codex-acp` is installed at `/usr/local/bin/codex-acp`. It is an Agent
                    Client Protocol (ACP) server on stdio: a client spawns it and drives a
                    Codex session through the protocol. It is not an interactive command —
                    with no client on the other end of stdio it sits silent, so do not run it
                    from this shell to "check" it.

                    Host tools must attach it to a non-TTY stdin/stdout stream, for example
                    `sbx exec -i <sandbox> codex-acp`. In Zed, configure an agent server
                    whose command runs that.

                    The adapter drives the same `codex` binary this sandbox already has
                    (`CODEX_PATH=/usr/local/bin/codex`), so authentication is the surface
                    `codex` uses: the proxy-mediated OpenAI credential behind
                    `~/.codex/auth.json` and the `~/.codex/config.toml` this composition
                    seeds. If `codex` works here, the adapter works with no extra setup and
                    nothing separate to log in to. Sessions created through ACP and
                    interactive `codex` runs share the same `~/.codex` state, which this
                    composition keeps in the sandbox filesystem rather than on a volume.

                    The Kit declares an optional `acp@1` endpoint, so supporting hosts can
                    find the adapter without hard-coding its command. It starts in
                    `agent-full-access` mode to match the interactive Codex entrypoint.

                    Pinned `codex-acp` 2.5.0 handles stdin closure but has no `SIGTERM`
                    cleanup handler. Cancellation and session flushing on `SIGTERM` have
                    not been verified against `acp@1`'s shutdown guarantee. Hosts should
                    close the ACP stdin stream and allow the adapter to finish before
                    terminating it.
                    The optional declaration enables discovery; it does not certify full
                    adapter conformance.
      declarationBlocks:
        - "1:0"
      source:
        kit: docker.io/docker/sbx-kit-codex-acp:2.5.0
        path: capabilities[2]
    - group:
        capabilities:
            - source:
                kit: docker.io/docker/sbx-kit-shell:1.0.0
                path: capabilities[0]
              type: com.docker.sandbox/sbx@1
      declarationBlocks:
        - "2:0"
      source:
        kit: docker.io/docker/sbx-kit-shell:1.0.0
        path: capabilities[0]
    - group:
        capabilities:
            - source:
                kit: docker.io/docker/sbx-kit-shell:1.0.0
                path: capabilities[1]
              type: com.docker.sandbox/network-policy@1
              config:
                runtime:
                    allow:
                        - deb.debian.org
                        - dhi.io
      declarationBlocks:
        - "2:0"
      source:
        kit: docker.io/docker/sbx-kit-shell:1.0.0
        path: capabilities[1]
    - group:
        optional: true
        capabilities:
            - source:
                kit: docker.io/docker/sbx-kit-shell:1.0.0
                path: capabilities[2]
              type: com.docker.sandbox/agent-context@1
              config:
                contentFile: /usr/share/sandbox/kit/codex-acp-set/context.md.parts/2.md
                filename: AGENTS.md
      declarationBlocks:
        - "2:0"
      source:
        kit: docker.io/docker/sbx-kit-shell:1.0.0
        path: capabilities[2]
    - group:
        optional: true
        capabilities:
            - source:
                kit: docker.io/docker/sbx-kit-shell:1.0.0
                path: capabilities[3]
              type: com.docker.sandbox/agent-context@2
              config:
                content: |
                    This is a plain shell sandbox on the shell-docker template: bash,
                    git, apt, Docker (compose/buildx), curl, gh, jq, make, gcc,
                    Python 3, and Node/npm. Install more with apt; composed kits list
                    their own capabilities below.
                filename: AGENTS.md
      declarationBlocks:
        - "2:0"
      source:
        kit: docker.io/docker/sbx-kit-shell:1.0.0
        path: capabilities[3]
    - group:
        optional: true
        capabilities:
            - source:
                kit: the set descriptor
                path: capabilities[0]
              type: com.docker.sandbox/agent-context@1
              config:
                contentFile: /usr/share/sandbox/kit/codex-acp-set/context.md.parts/3.md
                directory: /home/agent/.codex
                filename: AGENTS.md
      declarationBlocks:
        - "3:0"
      source:
        kit: the set descriptor
        path: capabilities[0]
    - group:
        optional: true
        capabilities:
            - source:
                kit: the set descriptor
                path: capabilities[1]
              type: com.docker.sandbox/agent-context@2
              config:
                content: |
                    # Codex over ACP

                    This sandbox is a published *set*: one kit whose content was merged from
                    a shell base, Codex CLI, and the Agent Client Protocol adapter. Run
                    `cat /usr/share/sandbox/kit/codex-acp-set/kit.yaml` to see the three, each pinned
                    by digest, and `ls /usr/share/sandbox/kit/` to see their own sources
                    staged beside each other.

                    Two ways to work here, and they are the same agent either way:

                    - Interactively, `codex` — the binary at `/usr/local/bin/codex`.
                    - Over ACP, `codex-acp` on stdio, which an editor spawns and speaks the
                      protocol to. It execs the same binary, so editor-driven and terminal
                      sessions share the version, credential, configuration, and state.

                    The adapter opens no sockets of its own. Its egress and OpenAI credential
                    are the ones Codex already has, so the merged policy does not need a
                    second copy of either declaration.
                directory: /home/agent/.codex
                filename: AGENTS.md
      declarationBlocks:
        - "3:0"
      source:
        kit: the set descriptor
        path: capabilities[1]
args:
    registry:
        default: docker.io/docker
        description: Registry namespace the listed kits were pushed to
        pattern: ^[a-z0-9][a-z0-9._/:-]*$
        buildArg: KIT_REGISTRY
kits:
    - ref: docker.io/docker/sbx-kit-shell:1.0.0
      digest: sha256:a72c2ead8a2ab26ac552e4578ea0e23b5e777e81e8a90108e676be09cffa69a4
    - ref: docker.io/docker/sbx-kit-codex-mixin:0.166.0
      digest: sha256:41cb2df315d9ec195461e328616e0502d1117dca1998b8c1ccd0940e7b7e7c67
    - ref: docker.io/docker/sbx-kit-codex-acp:2.5.0
      digest: sha256:87a6dfd54dfd18adf73cdf772aeb6fc8d3c9c2a4a497e30d35638159e03dddbc