Summary
applyContainerConfig() writes the gateway CA material to fixed filenames in the shared system temp dir and bind-mounts those host paths into containers. When two OneCLI instances run on the same host (e.g. two self-hosted gateways for two isolated agent apps), each instance's container spawn overwrites the other instance's CA files in place. Because the files are bind-mounted, every running container of the other instance immediately loses TLS trust for its own MITM gateway: all proxied HTTPS starts failing with curl exit 60 (SSL certificate problem) until its next spawn rewrites the file back — which then breaks the first instance's containers. A ping-pong outage with no error on the writing side.
Affected code
src/container/ca.ts (verified identical in 2.2.1 and latest 2.7.0):
function writeCaCertificate(caCertificate) {
const outPath = join(tmpdir(), "onecli-proxy-ca.pem"); // fixed name, shared /tmp
...
}
function buildCombinedCaBundle(caCertificate) {
...
const outPath = join(tmpdir(), "onecli-combined-ca.pem"); // fixed name, shared /tmp
...
}
src/container/credentials.ts has the same pattern for credential stubs (tmpdir()/onecli-stubs/onecli-stub-<basename>), which additionally risks one instance's containers mounting another instance's credential stub content.
Reproduction
- Run two self-hosted OneCLI instances on one host (different ports, different CAs).
- App A (SDK pointed at instance A) spawns a container via
applyContainerConfig — container gets /tmp/onecli-combined-ca.pem bind-mounted, HTTPS through gateway A works.
- While A's container is still running, App B (instance B) spawns a container.
- A's running container: any HTTPS call through gateway A now fails with
curl exit 60 / effective HTTP 000. curl -k succeeds, isolating it to CA trust. Host file mtimes match B's spawn time.
Suggested fix
Any of:
- Derive the filenames from the instance, e.g.
onecli-proxy-ca-<sha1(baseUrl).slice(0,8)>.pem (container-side mount path can stay fixed).
- Make the output directory configurable on the SDK constructor /
applyContainerConfig options.
- Write via unique temp name + keep per-config path.
Workaround
Set a distinct TMPDIR per host process (Node's os.tmpdir() honors it on POSIX, read per call). Verified working, but it's easy to miss until the collision bites — the failure appears only in the other app, minutes later, with no log on the writer's side.
Versions: SDK 2.2.1 (where hit) and 2.7.0 (code inspected, same pattern). Node v20.20.1, Linux.
Summary
applyContainerConfig()writes the gateway CA material to fixed filenames in the shared system temp dir and bind-mounts those host paths into containers. When two OneCLI instances run on the same host (e.g. two self-hosted gateways for two isolated agent apps), each instance's container spawn overwrites the other instance's CA files in place. Because the files are bind-mounted, every running container of the other instance immediately loses TLS trust for its own MITM gateway: all proxied HTTPS starts failing withcurlexit 60 (SSL certificate problem) until its next spawn rewrites the file back — which then breaks the first instance's containers. A ping-pong outage with no error on the writing side.Affected code
src/container/ca.ts(verified identical in 2.2.1 and latest 2.7.0):src/container/credentials.tshas the same pattern for credential stubs (tmpdir()/onecli-stubs/onecli-stub-<basename>), which additionally risks one instance's containers mounting another instance's credential stub content.Reproduction
applyContainerConfig— container gets/tmp/onecli-combined-ca.pembind-mounted, HTTPS through gateway A works.curlexit 60 / effective HTTP 000.curl -ksucceeds, isolating it to CA trust. Host file mtimes match B's spawn time.Suggested fix
Any of:
onecli-proxy-ca-<sha1(baseUrl).slice(0,8)>.pem(container-side mount path can stay fixed).applyContainerConfigoptions.Workaround
Set a distinct
TMPDIRper host process (Node'sos.tmpdir()honors it on POSIX, read per call). Verified working, but it's easy to miss until the collision bites — the failure appears only in the other app, minutes later, with no log on the writer's side.Versions: SDK 2.2.1 (where hit) and 2.7.0 (code inspected, same pattern). Node v20.20.1, Linux.