Compare commits

..

22 Commits

Author SHA1 Message Date
didericis-claude 650f3aa93e refactor(manifest): remove empty EGRESS_ROLES and related plumbing
test / unit (pull_request) Successful in 30s
test / integration (pull_request) Successful in 45s
EGRESS_ROLES, EGRESS_SINGLETON_ROLES, and PROVIDER_EGRESS_ROLES were
all empty frozensets after the codex_auth and claude_code_oauth roles
were removed. Delete the constants and all validation code that iterated
over them (the singleton-role loop and provider-role check in
_validate_egress_routes, the EGRESS_ROLES membership test in
EgressRoute.from_dict). EgressRoute.from_dict now rejects any role
string unconditionally; _validate_egress_routes loses its
agent_provider_template parameter entirely.

Assisted-by: Claude Code
2026-06-02 01:57:55 +00:00
didericis-claude 8a038dcceb refactor(manifest): remove codex_auth egress role
test / unit (pull_request) Successful in 30s
test / integration (pull_request) Successful in 42s
Both provider-owned roles are now gone. Provider auth routes are
provisioner-owned (claude: auth_token, codex: forward_host_credentials);
the role field and validation plumbing stay for future use but EGRESS_ROLES
is empty. Any manifest declaring a role now fails at parse time.

Assisted-by: Claude Code
2026-06-02 01:50:41 +00:00
didericis 3b96de95ab fix(agent): move default claude env vars to the right location
test / unit (pull_request) Successful in 36s
test / integration (pull_request) Successful in 55s
2026-06-01 21:41:38 -04:00
didericis-claude 962f8144fc fix(agent): always emit passthrough egress route for api.anthropic.com
test / unit (pull_request) Successful in 45s
test / integration (pull_request) Successful in 56s
Mirrors the Codex pattern: Claude always gets a tls_passthrough route
for api.anthropic.com so user-set tokens aren't stripped by pipelock,
whether or not auth_token is declared. Auth injection (scheme + token_ref)
and the placeholder env only apply when auth_token is set.

Assisted-by: Claude Code
2026-06-02 01:34:25 +00:00
didericis-claude 200a113cce feat(manifest): add agent_provider.auth_token for Claude OAuth via egress
test / unit (pull_request) Successful in 39s
test / integration (pull_request) Successful in 1m0s
Operators can now declare:

  agent_provider:
    template: claude
    auth_token: BOT_BOTTLE_CLAUDE_OAUTH_TOKEN

and the provisioner injects a provider-owned api.anthropic.com egress
route (Bearer, tls_passthrough) rather than requiring a manually
declared route with the former claude_code_oauth role.

Changes:
- Add auth_token field to AgentProvider; validate claude-only.
- Remove claude_code_oauth from EGRESS_ROLES / PROVIDER_EGRESS_ROLES.
  Manifests that declare the role now fail at parse time with "unknown
  role" — the provisioner owns the route.
- agent_provision_plan: replace manifest_egress_routes/has_provider_auth
  with auth_token; Claude branch injects the api.anthropic.com route,
  placeholder env, and nonessential-traffic flags when auth_token is set.
- Add hidden_env_names: frozenset[str] to AgentProvisionPlan; Claude
  branch populates it with CLAUDE_CODE_OAUTH_TOKEN.
- Remove auth_role from AgentProviderRuntime and placeholder_env_for().
- print_util.visible_agent_env_names: accept hidden_env_names from the
  plan instead of dispatching on agent_provider_template.
- Both backends: drop manifest_egress_routes call, pass auth_token.
- PRD 0029 rescoped to cover both Codex and Claude provider auth.

Assisted-by: Claude Code
2026-06-02 01:24:18 +00:00
didericis-claude 2eb6e02ee1 refactor(agent): move placeholder env injection into agent_provision_plan
test / unit (pull_request) Successful in 29s
test / integration (pull_request) Successful in 42s
The has_provider_auth check and egress-placeholder injection were
duplicated in both backends. Move them into agent_provision_plan so
the provisioner owns that decision entirely:

- Replace has_provider_auth: bool param with manifest_egress_routes,
  compute has_provider_auth internally from the route roles.
- Inject CLAUDE_CODE_OAUTH_TOKEN=egress-placeholder inside the plan
  when has_provider_auth, alongside the existing nonessential-traffic
  vars. Backends no longer touch the placeholder env.
- Remove placeholder_env from AgentProviderRuntime; expose
  placeholder_env_for() for print_util's hide-from-summary logic.

Assisted-by: Claude Code
2026-06-02 00:57:43 +00:00
didericis-claude 86cfd94b72 fix(codex): emit passthrough egress routes when not forwarding host credentials
test / unit (pull_request) Successful in 47s
test / integration (pull_request) Successful in 49s
When forward_host_credentials is false, Codex bottles should still get
tls_passthrough routes for the OpenAI/ChatGPT hosts so that tokens a
user sets via `codex login` after launch aren't stripped by pipelock's
header DLP. Previously no routes were emitted, which would have blocked
those requests entirely once pipelock enforcement tightens.

Rename the test to reflect the new expected behavior.

Assisted-by: Claude Code
2026-06-02 00:39:32 +00:00
didericis-claude 0233b481b1 fix(egress): break circular import with manifest via TYPE_CHECKING
test / unit (pull_request) Successful in 44s
test / integration (pull_request) Successful in 55s
manifest → agent_provider → egress → manifest created a cycle that
caused ImportError on any module import. With from __future__ import
annotations already present, Bottle is only needed at type-check time
(annotations are lazy strings under PEP 563).

Assisted-by: Claude Code
2026-06-02 00:28:57 +00:00
didericis-claude b79b49090f refactor: provision egress routes via AgentProvisionPlan
test / unit (pull_request) Failing after 31s
test / integration (pull_request) Failing after 18s
Remove provider-specific branching from egress.py and pipelock.py.
Previously, `egress_routes_for_bottle` and `pipelock_effective_tls_passthrough`
both contained `template == "codex"` checks — the same pattern the rest
of the PR moved out of the backends.

Root cause: `EgressRoute` had no `tls_passthrough` field, so pipelock
couldn't learn from the synthesised Codex routes that they needed
passthrough. Fix:

- Add `EgressRoute.tls_passthrough: bool`. `egress_manifest_routes` lifts
  the existing `pipelock.tls_passthrough` manifest flag here; provider
  routes set it directly.
- Add `AgentProvisionPlan.egress_routes`. `agent_provision_plan` populates
  it for Codex + `forward_host_credentials`, including `tls_passthrough=True`.
- Replace Codex-specific `egress_routes_for_bottle` logic with a generic
  `_merge_provider_route` helper. Backends call `egress_routes_for_bottle(bottle,
  plan.egress_routes)`; no provider type checks inside egress or pipelock.
- Rewrite `pipelock_effective_tls_passthrough` to read `route.tls_passthrough`
  from the merged route set instead of re-implementing the provider check.
- Both backends now call `agent_provision_plan` before `Egress.prepare` and
  `PipelockProxy.prepare`, threading `plan.egress_routes` to both. `has_provider_auth`
  is derived from `egress_manifest_routes` (manifest routes only — provider
  routes carry no auth roles, so the result is identical).

Assisted-by: Claude Code
2026-06-01 23:27:27 +00:00
didericis-codex 1fceaae8e6 refactor(agent): move claude env defaults into plan
test / unit (pull_request) Successful in 40s
test / integration (pull_request) Successful in 44s
2026-06-01 22:42:36 +00:00
didericis-codex 12f8c37af2 refactor(agent): surface provider env defaults
test / unit (pull_request) Successful in 38s
test / integration (pull_request) Successful in 56s
2026-06-01 22:32:03 +00:00
didericis-codex 10c009c37b refactor(agent): group provider provisioning into plan
test / unit (pull_request) Successful in 33s
test / integration (pull_request) Successful in 46s
2026-06-01 22:07:14 +00:00
didericis-codex a8b2237964 refactor(codex): derive trusted paths from guest home
test / unit (pull_request) Successful in 34s
test / integration (pull_request) Successful in 1m3s
2026-06-01 17:23:27 -04:00
didericis-codex 1d2dfeefa4 fix(codex): trust launch home directory
test / unit (pull_request) Successful in 30s
test / integration (pull_request) Successful in 49s
2026-06-01 17:16:00 -04:00
didericis-codex 3942b51184 fix(codex): trust bottle workspace on launch
test / unit (pull_request) Successful in 27s
test / integration (pull_request) Successful in 44s
2026-06-01 17:13:48 -04:00
didericis-codex 3060dc553c fix(smolmachines): reset codex runtime db before auth check
test / unit (pull_request) Successful in 33s
test / integration (pull_request) Successful in 43s
2026-06-01 17:06:33 -04:00
didericis-codex 8e5262b539 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>
2026-06-01 16:38:34 -04:00
didericis-codex 237afce844 fix(codex): include account claims in dummy auth 2026-06-01 14:44:00 -04:00
didericis-codex 91d6f5d8d2 fix(codex): provision dummy user auth state 2026-06-01 14:44:00 -04:00
didericis-codex 55117c5ff4 fix(codex): forward host credentials to api route 2026-06-01 14:44:00 -04:00
didericis-codex 1a5ea3b713 feat(codex): inject host credentials via egress 2026-06-01 14:44:00 -04:00
didericis-codex 6e7f0756cf docs(prd): add Codex host credentials egress plan 2026-06-01 14:44:00 -04:00
2 changed files with 2 additions and 2 deletions
+1 -1
View File
@@ -23,7 +23,7 @@ FROM node:22-slim
# tool (curl itself, plus anything that shells out to it) works
# against pipelock's bumped TLS without the agent needing local DNS.
RUN apt-get update \
&& apt-get install -y --no-install-recommends git ca-certificates openssh-client socat curl dnsutils python3 python3-pip python3-venv \
&& apt-get install -y --no-install-recommends git ca-certificates openssh-client socat curl dnsutils \
&& rm -rf /var/lib/apt/lists/*
# Install claude-code globally. Pinned to the version verified in the v1
+1 -1
View File
@@ -6,7 +6,7 @@
FROM node:22-slim
RUN apt-get update \
&& apt-get install -y --no-install-recommends git ca-certificates openssh-client socat curl dnsutils python3 python3-pip python3-venv \
&& apt-get install -y --no-install-recommends git ca-certificates openssh-client socat curl dnsutils \
&& rm -rf /var/lib/apt/lists/*
RUN npm install -g --no-fund --no-audit @openai/codex@0.134.0 \