Skip to content

feat(agent-relay-claude-code): support Anthropic-managed git - #1144

Draft
matifali wants to merge 1 commit into
matifali/agent-relay-claude-code-graceful-shutdownfrom
matifali/agent-relay-claude-code-git-proxy
Draft

matifali wants to merge 1 commit into
matifali/agent-relay-claude-code-graceful-shutdownfrom
matifali/agent-relay-claude-code-git-proxy

Conversation

@matifali

@matifali matifali commented Sep 24, 2026 •

Copy link
Copy Markdown
Member

Stacked on #1143 — base that, not main. Both touch the same four files, so a PR off main would conflict in all of them. Review #1143 first.

Relates to RELAY-26 (Claude Tag service session identities).

Why

use_anthropic_git_proxy authenticates clones server-side, so the workspace holds no git credentials. A session a person created uses their GitHub OAuth token; one a bot or agent created uses the organization's GitHub App installation token.

That second path is the only git auth that can work when the workspace owner is a service account. It has login_type = "none" and can never sign in, so it can never complete the OAuth flow a coder_external_auth block depends on — not a configuration problem, a dead end.

This is reachable today, not hypothetical: Agent Relay creates each workspace as the resolved session owner (CreateUserWorkspace(ctx, req.Owner.UserID…)), so a service-session identity lands here directly.

Policy is the template's, not the module's

The flag serves human and bot sessions alike, so the module defaults it off and takes no position. A template can gate it:

use_anthropic_git_proxy = data.coder_workspace_owner.me.login_type == "none"

or simply enable it everywhere. Both are documented.

On the detection: login_type == "none" is the indicator of a service-account owner, and coderd enforces that equivalence at creation in both directions — a service account may not use another login type, and login_type: none without service_account is rejected with "Login type 'none' requires a service account." The only runtime mutation path, UpdateUserLoginType, is the OIDC conversion flow, which requires the user to authenticate first and so can never apply to a none user.

Paired with the identity, overridable

configure_git defaults to following the proxy. The proxy replaces the HOME git config with credential settings only, so enabling it alone leaves no user.name/user.email and commits fail. Both overrides are supported and tested:

configure_git = false # image keeps its identity in /etc/gitconfig, which the proxy does not touch
configure_git = true  # sign commits as Claude without the proxy

Testing

terraform test: 16 pass, including that both flags are off by default, that the identity follows the proxy, and both override directions. bun test: 16 pass.

Note for reviewers

The flag is destructive by design — at startup and before every session the runner deletes ~/.gitconfig, the GIT_CONFIG_GLOBAL target and all of $XDG_CONFIG_HOME/git, with no backup. That isolation is the point for an ephemeral single-session workspace, and it is why it defaults off and the README says not to enable it on a workspace a person also works in. I have not exercised it against a live Anthropic-managed clone; that needs a pool credential.

Version: the bump stays 0.2.0 here because #1143 is unmerged, so the version-bump check sees one minor bump against main. Once #1143 lands and is tagged, this rebases onto main and becomes 0.3.0.

Generated with Claude Code using Claude Opus 4.5.

@linear-code

linear-code Bot commented Sep 24, 2026

Copy link
Copy Markdown

RELAY-26

@matifali
matifali force-pushed the matifali/agent-relay-claude-code-git-proxy branch from 1df0357 to 055232a Compare September 24, 2026 15:27
@github-actions

github-actions Bot commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Module Scorecard Check

coder/agent-relay-claude-code: 72 → 60

⚠️ Score regression: 72 → 60 (-12). Check the drilldown for which criteria dropped.

Theme Before After
Presentation & Onboarding 6 / 17 6 / 17
Integration 15 / 25 7.5 / 25
Credential Hygiene 20 / 20 20 / 20
Restricted-Environment 17 / 20 12 / 20
Engineering Quality 8 / 10 10 / 10
Overall 72 / 100 60 / 100
Full scorecard for this PR
Presentation & Onboarding Agent Integration Credential Hygiene Restricted-Environment Readiness Engineering Quality Overall
6 / 17 7.5 / 25 20 / 20 12 / 20 10 / 10 60 / 100
Drilldown

Presentation & Onboarding — 6 / 17

Criterion Max Score Notes
Configuration-mode examples 12 6 Main usage example shown at top (install_cli default). Other modes (install_cli=false, use_anthropic_git_proxy true/false, configure_git overrides, shutdown wiring) are explained in prose with small code snippets, not full standalone module examples with sensible defaults for each mode — partial/under-documented coverage.
Visual preview 5 0 No image, GIF, or video anywhere in the README.

Agent Integration — 7.5 / 25

Criterion Max Score Notes
AI governance 10 0 No mention of Coder AI Gateway or Agent Firewall anywhere; the module governs auth via Agent Relay's own JWT/credential scheme, unrelated to Coder's governance surfaces.
Dashboard entry point 5 0 No coder_app resource or documentation of one; this is a headless runner with no dashboard UI.
Session continuity 5 2.5 README mentions push_outcome_on_release pushing an outcome branch "so ... a resumed session continues from them," but this is git-state continuity across ephemeral workspaces, not a documented resume/session-ID mechanism or persistent session manager (tmux/screen) for the interactive agent process itself.
Managed configuration 5 5 base_dir variable documents a configurable/managed workdir; README shows setting SELF_HOSTED_RUNNER_HOOKS_DIR via coder_env as a managed-config example.

Credential Hygiene — 20 / 20

Criterion Max Score Notes
Secrets marked sensitive 16 16 agent_relay_credential is ephemeral = true with styling.mask_input = true, the masking mechanism for coder_parameter. No README example inlines a literal or placeholder secret value.
Non-hardcoded auth path 4 4 use_anthropic_git_proxy documents a server-side auth path using GitHub OAuth token or GitHub App installation token instead of pasting git credentials into the template; ephemeral work-order JWT credential avoids hardcoding auth in the template too.

Restricted-Environment Readiness — 12 / 20

Criterion Max Score Notes
Mirrorable artifact source 5 0 install.sh.tftpl hardcodes curl https://claude.ai/install.sh -fsSL | bash; no module variable overrides this download URL. cli_binary only overrides the binary path, not the download source.
Bring-your-own binary 10 10 install_cli = false fully disables the download and is clearly documented ("Bake the CLI into the image and set this to false for faster workspaces"), with a documented cli_binary override for a non-default path.
Egress transparency 3 0 No dedicated network/offline/air-gapped section; the README never names the claude.ai/install.sh domain or any Anthropic API/console endpoints at all (only appears in script comments, not README prose).
Runs without sudo 2 2 Install, start, stop, and status scripts never invoke sudo; the CLI installer runs to ~/.local/bin as the current user.

Engineering Quality — 10 / 10

Criterion Max Score Notes
Input quality 6 6 Every variable has a clear description and sensible default; cli_binary, exit_if_unused_min, and drain_wait_sec have validation blocks guarding shell-injection and type correctness.
Test coverage 4 4 Extensive main.tftest.hcl covers parameter contract, script rendering, and budget math; main.test.ts runs real container-based end-to-end tests of install/start/stop/status script behavior, including security-relevant cases (shell injection, permission bypass guard).

Overall — 60 / 100

Raw 55.5 / 92 → round(55.5 / 92 × 100) = 60

Tip

You can run this locally by telling your agent: "review this module against .github/scorecard/SCORECARD.md".


Scored against SCORECARD.md with solstice-1. Language-model scores are advisory.

@matifali
matifali force-pushed the matifali/agent-relay-claude-code-git-proxy branch 2 times, most recently from d2d0be4 to 39651ee Compare September 24, 2026 16:43
@matifali
matifali force-pushed the matifali/agent-relay-claude-code-graceful-shutdown branch from e257dfc to 64d87b2 Compare September 24, 2026 16:49
Add use_anthropic_git_proxy, which authenticates clones server-side so
the workspace holds no git credentials. A session a person created uses
their GitHub OAuth token; one a bot or agent created uses the
organization's GitHub App installation token.

That second path is the only git auth that works when the workspace
owner is a service account: it has login_type "none", can never sign in,
and so can never complete the OAuth flow a coder_external_auth block
depends on. Agent Relay creates each workspace as the resolved session
owner, so this is reachable today rather than hypothetical.

The module takes no position on when to enable it. The flag serves human
and bot sessions alike, so a template can gate it on the owner's
login_type or turn it on everywhere; both are documented.

Pair it with configure_git, defaulting to follow it. The proxy replaces
the HOME git config with credentials only, so enabling it alone leaves
no identity and commits fail. Set configure_git explicitly to override:
false for an image that keeps its identity in /etc/gitconfig, which the
proxy does not touch, or true to sign commits without the proxy.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant