Summary
Sandbox agents cannot git clone / fetch / pull private repos over HTTPS through iron-proxy. The iron-proxy header_allowlist transform omits content-encoding, so it forwards the gzip-compressed git-upload-pack POST body but strips the Content-Encoding: gzip header. GitHub then tries to parse the gzip bytes as plaintext and returns HTTP 400.
This is a transport bug, not an auth bug — gh api and public clones work fine. It affects every deployment using iron-proxy (the default), regardless of secret source.
error: RPC failed; HTTP 400 curl 22 The requested URL returned error: 400
fatal: the remote end hung up unexpectedly
Steps to reproduce
- Deploy Centaur with iron-proxy (default).
- From a sandbox, with a token that can read a private repo:
gh api user → 200 (auth works)
git clone https://github.com/<org>/<private-repo> → fails with HTTP 400 on git-upload-pack
- Inspect the iron-proxy audit log: the
git-upload-pack POST shows status 400 and header_allowlist stripped_headers containing Content-Encoding.
Audit evidence:
api.github.com GET /user 200 secrets: swapped GITHUB_TOKEN -> header:Authorization
github.com GET /<org>/<repo>/info/refs 401 (git's initial unauth probe — normal)
github.com GET /<org>/<repo>/info/refs 200 secrets: swapped GITHUB_TOKEN -> header:Authorization
github.com POST /<org>/<repo>/git-upload-pack 400 header_allowlist stripped_headers=["Content-Encoding","User-Agent"]
Root cause
git sends the git-upload-pack request body gzip-compressed with Content-Encoding: gzip. iron-proxy's strict outbound header_allowlist does not include content-encoding, so the header is dropped while the compressed body is forwarded as-is. The server then reads compressed bytes as if they were uncompressed and rejects the request with 400.
The same allowlist lives in two places and both are affected:
services/api/api/iron-proxy.base.yaml (authoritative — baked into the centaur-api image and used to render every per-sandbox proxy config)
services/iron-proxy/iron-proxy.yaml (standalone egress proxy copy)
Expected outcome
- Private
git clone over HTTPS from a sandbox succeeds (HTTP 200 on git-upload-pack).
- iron-proxy audit no longer lists
Content-Encoding in stripped_headers for the POST.
gh api and public clones remain unaffected.
Summary
Sandbox agents cannot
git clone/fetch/pullprivate repos over HTTPS through iron-proxy. The iron-proxyheader_allowlisttransform omitscontent-encoding, so it forwards the gzip-compressedgit-upload-packPOST body but strips theContent-Encoding: gzipheader. GitHub then tries to parse the gzip bytes as plaintext and returns HTTP 400.This is a transport bug, not an auth bug —
gh apiand public clones work fine. It affects every deployment using iron-proxy (the default), regardless of secret source.Steps to reproduce
gh api user→200(auth works)git clone https://github.com/<org>/<private-repo>→ fails with HTTP 400 ongit-upload-packgit-upload-packPOST shows status 400 andheader_allowliststripped_headerscontainingContent-Encoding.Audit evidence:
Root cause
git sends the
git-upload-packrequest body gzip-compressed withContent-Encoding: gzip. iron-proxy's strict outboundheader_allowlistdoes not includecontent-encoding, so the header is dropped while the compressed body is forwarded as-is. The server then reads compressed bytes as if they were uncompressed and rejects the request with 400.The same allowlist lives in two places and both are affected:
services/api/api/iron-proxy.base.yaml(authoritative — baked into thecentaur-apiimage and used to render every per-sandbox proxy config)services/iron-proxy/iron-proxy.yaml(standalone egress proxy copy)Expected outcome
git cloneover HTTPS from a sandbox succeeds (HTTP 200 ongit-upload-pack).Content-Encodinginstripped_headersfor the POST.gh apiand public clones remain unaffected.