fix(codex): make host-credential bottles actually authenticate
test / unit (pull_request) Successful in 37s
test / integration (pull_request) Successful in 45s

Debugging a live codex smolmachines bottle surfaced three independent
failures past the sign-in screen; fix each so forward_host_credentials
works end to end:

- codex_auth: dummy access/id tokens now inherit the *real* host token's
  exp instead of now+1h. Codex (0.135) refreshes when its local token's
  JWT exp lapses; with a placeholder refresh_token that refresh fails and
  drops to the sign-in screen. Aligning exp tracks the real token's life.

- prepare: set CODEX_CA_CERTIFICATE to the agent CA bundle for codex
  bottles. Codex is rustls and ignores the system store / NODE_EXTRA_CA_
  CERTS; it reads CODEX_CA_CERTIFICATE (fallback SSL_CERT_FILE) for custom
  roots across HTTPS + wss, so it must be pointed at the egress MITM CA or
  injection can't work without tls_passthrough.

- pipelock: auto tls_passthrough the Codex API hosts when
  forward_host_credentials is on. Egress injects the bearer before
  pipelock, whose header DLP then flags the JWT ("request header contains
  secret") and the retry storm trips its 429. passthrough host-gates the
  CONNECT but skips decrypt+rescan of egress-owned auth. The auto-added
  routes aren't in bottle.egress.routes, so the hosts are added explicitly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-01 16:38:34 -04:00
parent 237afce844
commit 8e5262b539
11 changed files with 197 additions and 58 deletions
+24
View File
@@ -211,6 +211,7 @@ class TestProvisionProviderAuth(unittest.TestCase):
) as cp, patch(
"bot_bottle.backend.smolmachines.provision.provider_auth._smolvm.machine_exec"
) as ex:
ex.return_value = SmolvmRunResult(0, "Logged in using ChatGPT\n", "")
_provider_auth.provision_provider_auth(
_plan(codex_auth_file=Path("/tmp/codex-auth.json")),
"bot-bottle-demo-abc12",
@@ -226,6 +227,29 @@ class TestProvisionProviderAuth(unittest.TestCase):
argv_seen,
)
self.assertIn(["chmod", "600", "/home/node/.codex/auth.json"], argv_seen)
self.assertIn(
[
"runuser", "-u", "node", "--",
"env",
"HOME=/home/node",
"CODEX_HOME=/home/node/.codex",
"codex", "login", "status",
],
argv_seen,
)
def test_dies_when_codex_rejects_dummy_auth(self):
with patch(
"bot_bottle.backend.smolmachines.provision.provider_auth._smolvm.machine_cp"
), patch(
"bot_bottle.backend.smolmachines.provision.provider_auth._smolvm.machine_exec"
) as ex:
ex.return_value = SmolvmRunResult(1, "Not logged in\n", "")
with self.assertRaises(SystemExit):
_provider_auth.provision_provider_auth(
_plan(codex_auth_file=Path("/tmp/codex-auth.json")),
"bot-bottle-demo-abc12",
)
class TestProvisionSkills(unittest.TestCase):