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
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
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