Follow-up from #7, which deliberately shipped the credential-isolation proxy as a GitHub-only proof of concept. Both remaining bearer-token providers are near-1:1 ports of the same pattern:
--tfe — app.terraform.io, bearer token, single hostname.
--glab — gitlab.com, bearer token (PRIVATE-TOKEN / Authorization), single hostname. Note this one currently mounts the host glab config dir read-only as well, so the port has to decide what happens to that mount.
Same wins as GitHub: the token leaves the agent container entirely, plus a policy point and an audit log per provider.
Decide the architecture before implementing
Preference: one multi-site proxy — a single sidecar per session serving all enabled providers as additional Caddyfile site blocks, rather than one sidecar per provider. Rationale: less runtime overhead (one container instead of up to three), one lifecycle/teardown path instead of N, one CA and one trust-store install, and a single audit-log stream. The Caddyfile is already multi-site (three GitHub hostnames), so provider blocks are additive.
Trade-off to weigh explicitly: a shared sidecar means one process holds all enabled provider tokens, so a hypothetical sidecar compromise widens the blast radius versus isolated per-provider sidecars — and the blocks share a process/config, so a broken policy snippet for one provider can take down the others (mitigated by the startup fail-closed + exited-sidecar detection added in #7).
Write the decision down (OpenSpec design doc) before coding, since it determines the lifecycle shape that the TFC and GitLab ports both build on. Refactoring lifecycle later is the expensive path.
Out of scope here
AWS needs its own design: SigV4 request signing means static header injection does not transfer. Candidates to evaluate separately are a re-signing proxy (e.g. awslabs/aws-sigv4-proxy with dummy credentials and AWS_ENDPOINT_URL redirection instead of DNS interception) versus vending short-lived scoped STS credentials via the ECS container-credentials endpoint.
Follow-up from #7, which deliberately shipped the credential-isolation proxy as a GitHub-only proof of concept. Both remaining bearer-token providers are near-1:1 ports of the same pattern:
--tfe—app.terraform.io, bearer token, single hostname.--glab—gitlab.com, bearer token (PRIVATE-TOKEN/Authorization), single hostname. Note this one currently mounts the host glab config dir read-only as well, so the port has to decide what happens to that mount.Same wins as GitHub: the token leaves the agent container entirely, plus a policy point and an audit log per provider.
Decide the architecture before implementing
Preference: one multi-site proxy — a single sidecar per session serving all enabled providers as additional Caddyfile site blocks, rather than one sidecar per provider. Rationale: less runtime overhead (one container instead of up to three), one lifecycle/teardown path instead of N, one CA and one trust-store install, and a single audit-log stream. The Caddyfile is already multi-site (three GitHub hostnames), so provider blocks are additive.
Trade-off to weigh explicitly: a shared sidecar means one process holds all enabled provider tokens, so a hypothetical sidecar compromise widens the blast radius versus isolated per-provider sidecars — and the blocks share a process/config, so a broken policy snippet for one provider can take down the others (mitigated by the startup fail-closed + exited-sidecar detection added in #7).
Write the decision down (OpenSpec design doc) before coding, since it determines the lifecycle shape that the TFC and GitLab ports both build on. Refactoring lifecycle later is the expensive path.
Out of scope here
AWS needs its own design: SigV4 request signing means static header injection does not transfer. Candidates to evaluate separately are a re-signing proxy (e.g.
awslabs/aws-sigv4-proxywith dummy credentials andAWS_ENDPOINT_URLredirection instead of DNS interception) versus vending short-lived scoped STS credentials via the ECS container-credentials endpoint.