Skip to content

feat(orchestrator): github PAT via credential proxy — spawned agents push with zero raw PAT (#11536 E3) - #11977

Merged
lalalune merged 1 commit into
developfrom
feat/11536-e3-credential-proxy-pat
Jul 3, 2026
Merged

lalalune merged 1 commit into
developfrom
feat/11536-e3-credential-proxy-pat

Conversation

@lalalune

@lalalune lalalune commented Jul 3, 2026

Copy link
Copy Markdown
Member

What / why

Phase E3 of #11536 (credential-broker integration, Priority:High/security): coding sub-agents access github (and other non-model APIs) without a raw PAT in their env. The PAT is injected outbound by the credential proxy; the agent gets a proxy redirection + a scoped handle. This is the NON-MODEL sibling of the merged E1 (#11660) / E2 (#11651) model-gateway path.

Acceptance (issue E3): a spawned sub-agent pushes a branch with zero PAT in its env. Met — the child env in proxy mode carries no raw PAT and git obtains a broker-minted credential at push time via a credential helper.

Deliverables

1. Credential-proxy client util (packages/core/src/features/credential-proxy/)

  • createCredentialProxyFetch — an HMAC-signed fetch wrapper mirroring @stwd/proxy-client semantics: header-only injection (agent-scoped bearer, never the raw credential), a narrow per-host route allowlist (explicit host + method + path prefix), off-list targets rejected before any network call. The transport to the proxy runs through the existing packages/core/src/network SSRF guard with the trusted proxy host explicitly allowlisted (a private/localhost sidecar must not be blocked, while redirects/DNS-rebind stay guarded).
  • Vendor-neutral config: ELIZA_CREDENTIAL_PROXY_URL / _TOKEN / _SIGNING_KEY / _STRICT / _ROUTES, matching the E1/E2 ELIZA_MODEL_GATEWAY_* naming. Both-or-nothing mode gate; a malformed routes override fails closed.

2. Git credential-helper bridge — a dependency-free Node helper (node built-ins only, so it runs inside a child agent that may not resolve @elizaos/core), materialized at spawn. On git get for an allowlisted https host it POSTs a signed request to the proxy's /git-credential endpoint and returns the broker-minted username/password to git. Signing stays byte-for-byte in lockstep with core's canonical scheme (pinned by a cross-check test).

3. Orchestrator wiring (plugin-agent-orchestrator)

Tests (22, all green locally)

Core (13): sign + forward correctness (independently recomputed HMAC), per-host allowlist rejects off-list host/method/path before any call, no-signing-key path, body-hash determinism, config gate + strict + routes-override fail-closed.

Orchestrator (9): applyCredentialProxyEnv scrub + inject; strict throws; the git credential helper run by the REAL node binary against a REAL mock proxy HTTP server returns broker-minted creds with a valid HMAC signature and no PAT, and fails closed for an off-allowlist host (no proxy call, non-zero exit); the real AcpService.buildEnv spawn seam yields a child env with no raw PAT + helper wiring; strict mode refuses to spawn with a PAT on the box; helper↔core signing lockstep cross-check.

core:  Test Files 2 passed  Tests 13 passed
orch:  Test Files 1 passed  Tests  9 passed
adjacent (model-gateway-env, acp-service, task-agent-frameworks): 74 passed (no regression)

bun run typecheck (orchestrator) clean; biome clean.

Evidence / follow-up

  • Real-LLM trajectories: N/A — no agent/action/prompt/model behavior changes (env-assembly + a signed HTTP client only).
  • Frontend/UI: N/A — no UI surface.
  • Live github push: the proxy /git-credential endpoint is exercised end-to-end against a real local HTTP mock proxy (real node runs the helper, real HMAC verified server-side). A push against a live broker is a documented follow-up — no broker is reachable in this environment.

Refs #11536

🤖 Generated with Claude Code

…push with zero raw PAT (#11536 E3)

Non-model credential brokering: the E3 sibling of the E1/E2 model gateway.
Coding sub-agents access github (and other non-model APIs) WITHOUT a raw PAT
in their env — the PAT is injected outbound by the credential proxy; the agent
gets a proxy redirection plus a scoped handle.

Core (packages/core/src/features/credential-proxy):
- client.ts: createCredentialProxyFetch — an HMAC-signed fetch wrapper mirroring
  @stwd/proxy-client semantics (header-only injection, agent-scoped bearer, a
  narrow per-host route allowlist with explicit method + path prefix). Off-list
  targets are rejected before any network call. The transport to the proxy goes
  through the SSRF guard with the trusted proxy host allowlisted.
- config.ts: vendor-neutral ELIZA_CREDENTIAL_PROXY_URL / _TOKEN / _SIGNING_KEY /
  _STRICT / _ROUTES (mirrors the ELIZA_MODEL_GATEWAY_* convention). Both-or-
  nothing mode gate; malformed routes override fails closed.

Orchestrator (plugin-agent-orchestrator):
- credential-proxy-env.ts: a dependency-free git credential helper (materialized
  at spawn) that brokers auth through the proxy so `git push` needs no PAT in
  env; applyCredentialProxyEnv deletes every raw VCS PAT and points the child's
  git at the helper via GIT_CONFIG_*. Fail-closed strict mode refuses the spawn
  when a raw PAT is present on the box.
- acp-service.ts buildEnv: a separate, clearly-commented credential-proxy block
  after the E2 model-gateway block (distinct env keys — the two #11536 lanes
  never touch the same lines).

Tests (22): proxy client signs + forwards correctly and rejects off-allowlist
hosts; config gate + strict; the git credential helper run by the REAL node
binary against a REAL mock proxy returns broker-minted creds with a valid HMAC
signature and no PAT, and fails closed for off-allowlist hosts; the real
AcpService.buildEnv spawn seam yields a child env with no raw PAT; strict mode
refuses to spawn with a PAT on the box; helper↔core signing lockstep cross-check.

A real end-to-end push against a live broker is a documented follow-up (no
broker reachable here); the proxy endpoint is mocked with a real HTTP server.

Refs #11536

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 13fdd8d1-e89c-41da-8248-ef6768ff0ec4

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/11536-e3-credential-proxy-pat

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@lalalune
lalalune merged commit d2ed356 into develop Jul 3, 2026
40 of 63 checks passed
@lalalune
lalalune deleted the feat/11536-e3-credential-proxy-pat branch July 3, 2026 17:48
@lalalune

lalalune commented Jul 3, 2026

Copy link
Copy Markdown
Member Author

QA review (orchestrator/security, E3 companion to the merged #11979 E2): sound design. applyCredentialProxyEnv deletes every raw VCS PAT (GITHUB_TOKEN/GH_TOKEN/GH_ENTERPRISE_TOKEN/GITHUB_PAT) from the child env and points git at a dependency-free (node-builtins-only) credential helper that fetches broker-minted creds at push time via an HMAC-signed proxy request; the per-host route allowlist (host+method+path) rejects off-list targets before any network call, and the proxy transport goes through the core SSRF guard with the trusted proxy host explicitly allowlisted. Fail-closed strict mode refuses to spawn with a PAT on the box; opt-in both-or-nothing config gate. The core credential-proxy module is a new isolated feature; index.node.ts export is purely additive (zero removed lines); the E3 env block is distinct keys from E2 so the lanes merge cleanly (verified merge-clean). Verified on the head: core credential-proxy 13/13; orchestrator credential-proxy-env 9/9 after rebuilding core dist (the initial red was stale-dist resolution of the new @elizaos/core exports, not a defect) — includes the real-node-helper-vs-real-mock-proxy HMAC test and the off-allowlist fail-closed case. Merging.

@claude

claude Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error —— View job


I'll analyze this and get back to you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants