fix(runtime): preserve image ENTRYPOINT so caido-cli actually starts

The SDK's ``DockerSandboxClient._create_container`` overrode both
``entrypoint`` and ``command`` (``tail`` + ``-f /dev/null``), which kept
the container alive but bypassed the image's ``docker-entrypoint.sh``.
That script is what launches ``caido-cli`` and sets up the browser CA
trust. With it skipped, every scan since the harness migration sat in
``bootstrap_caido`` retrying ``loginAsGuest`` for 30 s against a dead
port and then aborted before any agent work happened.

Drop the ``entrypoint`` override and pass ``[tail, -f, /dev/null]`` as
``command``. The image's ENTRYPOINT runs setup, then ``exec \"\$@\"``
swaps PID 1 to ``tail`` for the keep-alive — same long-running
no-op the SDK was after, but with the manifest/init work done first.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
0xallam
2026-04-26 07:26:13 -07:00
parent 8bbb31e075
commit ead54ba82c
+20 -10
View File
@@ -1,15 +1,20 @@
"""StrixDockerSandboxClient — adds NET_ADMIN/NET_RAW capabilities + host-gateway. """StrixDockerSandboxClient — preserves the image's ENTRYPOINT and adds
NET_ADMIN/NET_RAW capabilities + host-gateway.
The SDK's ``DockerSandboxClient._create_container`` does not expose a hook for The SDK's ``DockerSandboxClient._create_container`` does not expose a hook for
extending ``create_kwargs`` before ``containers.create`` is called. We subclass extending ``create_kwargs`` before ``containers.create`` is called. We subclass
and reimplement the method body verbatim from the SDK source, with two and reimplement the method body verbatim from the SDK source, with three
additions before the final create call: deltas:
create_kwargs.setdefault("cap_add", []).extend(["NET_ADMIN", "NET_RAW"]) 1. Drop the SDK's ``entrypoint=["tail"]`` override; supply ``["tail", "-f",
create_kwargs.setdefault("extra_hosts", {})["host.docker.internal"] = "host-gateway" "/dev/null"]`` as ``command`` instead. This lets our image's
``docker-entrypoint.sh`` actually run — without it, ``caido-cli`` never
These are required for raw-socket pentest tools (nmap -sS) and for letting starts inside the container and ``bootstrap_caido`` retries against a
the agent reach host-served apps via ``host.docker.internal``. dead port.
2. Append NET_ADMIN/NET_RAW to ``cap_add`` (required by ``nmap -sS`` and
other raw-socket tools).
3. Add ``host.docker.internal`` → host-gateway to ``extra_hosts`` so the
agent can reach host-served apps.
Pinned to ``openai-agents==0.14.6``. Bumping the SDK requires Pinned to ``openai-agents==0.14.6``. Bumping the SDK requires
re-merging the parent body. Track upstream for an injection hook. re-merging the parent body. Track upstream for an injection hook.
@@ -61,11 +66,16 @@ class StrixDockerSandboxClient(DockerSandboxClient):
environment: dict[str, str] | None = None environment: dict[str, str] | None = None
if manifest: if manifest:
environment = await manifest.environment.resolve() environment = await manifest.environment.resolve()
# Strix delta from the SDK body: drop ``entrypoint`` override and
# supply ``tail -f /dev/null`` as ``command`` so the image's
# ENTRYPOINT (``docker-entrypoint.sh``) runs setup, then ``exec
# "$@"`` becomes ``exec tail -f /dev/null`` for the keep-alive.
# Without this, caido-cli + the in-container CA trust never get
# initialized.
create_kwargs: dict[str, Any] = { create_kwargs: dict[str, Any] = {
"entrypoint": ["tail"],
"image": image, "image": image,
"detach": True, "detach": True,
"command": ["-f", "/dev/null"], "command": ["tail", "-f", "/dev/null"],
"environment": environment, "environment": environment,
} }
if manifest is not None: if manifest is not None: