Git Access for Coding Agents
Git Proxy lets a background agent run ordinary git clone, fetch, pull, and push against GitHub without a personal access token. Each agent gets an allowlist of repositories. Git talks to Willow rather than to GitHub, and Willow attaches a short-lived GitHub App token scoped to that one repository on the way out. No GitHub token is ever present in the agent's environment, so there is nothing for the agent to print, copy, or misuse.
This is separate from the GitHub MCP connector. The connector gives an agent tools for issues, pull requests, and the REST API. Git Proxy gives it the git command line.
How it works
- You create a GitHub App, install it on the repositories agents may use, and store its credentials in Willow.
- On each agent, you list the repositories it may use and whether it may push.
- The agent runs
willow-git setupfrom the@mcp-s/gitpackage. This points git at the Willow gateway instead ofgithub.comand attaches the agent's own Willow credential. - On a remote git command, the gateway checks the allowlist, mints a GitHub App token scoped to that one repository, attaches it to the request, and streams GitHub's response back. The token stays inside Willow and expires within the hour.
Local commands such as status, add, and commit never call Willow.
Because the allowlist is enforced in the gateway, the agent cannot get around it. Rewriting git config, calling the gateway with curl, or skipping willow-git entirely all hit the same check, and none of them yields a GitHub credential.
Where willow-git comes from depends on the platform:
| Platform | What you do |
|---|---|
| Willow Agents | Nothing beyond the allowlist. Willow sets it up on Deploy. |
| Claude Managed Agents | Nothing beyond the allowlist. Willow sets it up in your Anthropic workspace on Deploy. |
| AWS AgentCore | Nothing beyond the allowlist. Willow sets it up on the harness on Sync. |
| Custom, your own type, or the Kubernetes harness | Install the CLI and set three environment variables in your runtime (shell / session startup). See Custom runtimes. |
On Willow Agents and Claude Managed Agents, Deploy installs git tooling and appends short operating instructions to the system prompt (run willow-git setup, allowed repos, use willow-git pr create). On AWS AgentCore, Sync sets the three WILLOW_* variables on the harness and appends plain git config steps instead. The agent secret is never written into the prompt.
On custom runtimes, the Agent runtime env block under the agent's Git repositories section is for the sandbox shell only. Do not paste it into the agent's instructions or system prompt.
Create the GitHub App
Create an App under your GitHub organization at Settings > Developer settings > GitHub Apps > New GitHub App:
| Field | Value |
|---|---|
| GitHub App name | Anything, for example Willow Coding Agents. Commits and pushes show this name. |
| Homepage URL | Your Willow dashboard URL. |
| Webhook | Inactive. |
| Repository permissions > Contents | Read and write. This is what lets the agent push commits and branches. Read-only is enough only when agents never push. |
| Repository permissions > Pull requests | Read and write if the agent should open pull requests. Read-only lets it see pull requests, not create or update them. |
| Repository permissions > Metadata | Read-only (required). |
| Where can this GitHub App be installed? | Only on this account. |
Opening a pull request needs both write permissions. Pull requests Read and write is what creates the pull request. Contents Read and write is what pushes the branch it points at. On the agent, that repository's access must be write as well: a read repository gets a read-only token, so it can neither push nor open a pull request.
Then:
- Select Generate a private key and keep the downloaded
.pemfile. - Select Install App and choose the repositories agents may use. Willow can only mint tokens for repositories in this installation.
- Copy the App ID from the App's settings page.
- Copy the Installation ID from the installation URL,
https://github.com/organizations/<org>/settings/installations/<installation-id>.
Connect the App to Willow
Open Build > Background Agents, select the gear icon, and find the GitHub App (coding agents) card. Select Set up.
- Paste the App ID, Installation ID, and Private key (PEM).
- Under Token permissions, leave Contents (and Pull requests, if agents open PRs) as
writeunless every agent is clone-only. Setting Contents toreadhere blocks push for every agent even when a repository is allowlisted aswrite. The GitHub App itself must also grant at least these permissions. - Select Test connection & Save. Willow lists the installation's repositories to prove the credentials work.
The card then reads Configured with the App and installation IDs. The private key is encrypted and never shown again; to replace it, open Manage and paste a new one.
Choose an agent's repositories
Open the agent, go to Settings, and expand Git repositories.
- Pick a repository from Select repository, which lists what the App installation can reach, or choose Custom… and type
owner/name. Type in the picker's search box to filter the list byowner/name; the match ignores case, and Enter picks the only match. - Optionally set the default branch.
- Set access to
writeorread. The default iswrite. - Save.
A read repository is refused at the gateway on push, before the request reaches GitHub, and its token is read-only in any case. An agent with an empty list has no git access at all.
The allowlist is checked on every git request, so removing a repository or switching it to read takes effect on the agent's next git command.
Willow Agents, Claude Managed Agents, and AWS AgentCore
Nothing to install. Save the repository list and select Deploy (Sync on AWS AgentCore); Willow sets up git for the agent. Deploy again whenever you change the list.
To check it, open Test on the agent's Overview tab and ask it to clone one of its repositories and list the files.
On Claude Managed Agents, the agent's Willow token is stored in your Anthropic vault as Willow git proxy token and is never visible inside the sandbox.
On AWS AgentCore, the harness's default image has no Node.js, so Willow doesn't install willow-git. Instead, it sets WILLOW_GATEWAY_URL, WILLOW_AGENT_SLUG, and WILLOW_AGENT_TOKEN as harness environment variables. It also tells the agent to run the same git config commands that willow-git setup writes, and to open pull requests with a curl call to the same Willow endpoint. Unlike on Claude Managed Agents, WILLOW_AGENT_TOKEN is readable inside the harness. It is the same agent token the harness already uses for the Willow gateway, it only reaches this agent's tools and repository allowlist, and every Sync replaces it. Removing every repository and syncing clears the variables.
Open pull requests
After pushing a branch, the agent opens a pull request with:
willow-git pr create --title "Fix README title" --body "What changed and why"
It runs from inside the clone and uses the current branch as the head and the repository's default branch as the base. Pass --base, --head, --repo, or --draft to change that. Willow calls the GitHub API itself, so the repository must be write on the agent and the App needs Pull requests Read and write. The pull request is opened by the GitHub App.
Willow Agents and Claude Managed Agents are told to use this command. AWS AgentCore agents send the same request to <gateway>/agent-api/<slug>/git/pulls with curl. gh will not work, because there is no GitHub token in the environment for it to use.
Custom runtimes
On Custom, a type you register, or the Kubernetes harness, Willow does not control the machine the agent runs on, so install the CLI in your image or startup script — not in the agent's system prompt:
npm i -g @mcp-s/git
export WILLOW_GATEWAY_URL=https://<your-run-gateway>
export WILLOW_AGENT_SLUG=<agent-slug>
export WILLOW_AGENT_TOKEN=<access_key>:<secret>
willow-git setup
Take these values from the agent's Git repositories section (Agent runtime env), which has a copy button for the whole block. That block is shell / session startup only. Copying requires a revealed secret, so create or recreate a token first if you no longer have it. Deploying replaces the platform token but not manual tokens, so use a manual token for WILLOW_AGENT_TOKEN and it keeps working across deploys.
Sandboxes that start fresh need willow-git setup again at the beginning of each session. Until it runs, git talks to github.com directly and may ask for a username.
willow-git setup writes ~/.willow/git/config (mode 0600) and rewrites every GitHub remote form to <gateway>/agent-api/<slug>/git/github.com/, with the agent's Willow bearer attached as an HTTP header. Plain git clone, fetch, pull, and push then work on their own; the willow-git git wrapper and the shim below only add a clearer allowlist error before the request goes out.
export PATH="$(npm root -g)/@mcp-s/git/git-shim:$PATH"
SSH remotes such as git@github.com:owner/repo.git are rewritten too, so existing clones keep working.
The agent's runtime must be able to reach your run gateway. It no longer needs outbound access to github.com.
FAQ
Does git setup go in the system prompt?
No secrets, and not the full runtime env block. On managed platforms, Deploy adds short operating instructions (run willow-git setup, which repos are allowed, how to open a PR). On custom runtimes you run the Agent runtime env exports yourself in the sandbox; putting them in the system prompt does not configure git and risks exposing the token if the model echoes it.
Why does git ask for a username?
willow-git setup has not run in this session, so git is still calling github.com instead of the Willow proxy. Run the setup block again (custom runtimes) or tell the agent to follow its git setup instructions (managed platforms).
Push fails even though the repository is write on the agent
Check three places: the agent allowlist entry is write, org Token permissions → Contents is write on the GitHub App (coding agents) card, and the GitHub App itself has Contents: Read and write (and Pull requests: Read and write if opening PRs).
Troubleshooting
willow-git prints the error Willow returns:
| Error | Cause | Fix |
|---|---|---|
git_proxy_not_configured | The agent has no repositories, or the GitHub App is not set up. | Add repositories to the agent, or finish Connect the App to Willow. |
repo_not_allowed | The repository is not on the agent's list, or belongs to a different owner than the installation. | Add it under Git repositories. |
repo_is_read_only | The agent tried to push to a repository allowlisted as read. | Switch it to write under Git repositories. |
repo_not_in_installation | The repository is on the list, but the GitHub App is not installed on it. | In GitHub, add the repository to the App installation. |
git_proxy_disabled | Git Proxy is not enabled for your organization. | Ask your Willow contact. |
WILLOW_GATEWAY_URL is required | willow-git ran before setup. | Run the exports and willow-git setup first. On managed platforms, tell the agent to follow its git setup instructions. |
Git still goes to github.com, or asks for a username | willow-git setup has not run in this session. | Run willow-git setup. Managed sandboxes start fresh, so this is needed once per session. |
Security
- No GitHub credential exists inside the agent's environment. Git authenticates to Willow with the agent's own credential, and Willow attaches the GitHub App token server-side. There is no command the agent can run to obtain a GitHub token.
- Tokens are scoped to one repository, carry only the permissions the allowlist entry allows, and expire within the hour. They live only in Willow's memory for the duration of the request.
- The allowlist and the push gate are enforced in the gateway, not in the CLI, so they apply to any client the agent uses.
- The GitHub App private key stays encrypted in Willow.
- Commits and pushes are attributed to the GitHub App.
- Every token Willow issues is recorded in the security audit log as
backgroundAgent.gitToken, with the agent and repository, and every pull request asbackgroundAgent.gitPullRequest. The token itself is never logged.