sha256:1f7829c3351fd1f3d3b41de238b5a1d6918c7a23723f36cc18a8592720a46e20
Last pushed
5 days by cdupuis
Type
Sandbox Kit
Manifest digest
sha256:1f7829c3351fd1f3d3b41de238b5a1d6918c7a23723f36cc18a8592720a46e20
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