Skip to content

iron-proxy strips Content-Encoding header, breaking private git clone over HTTPS from sandboxes #402

@pkobielak

Description

@pkobielak

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

  1. Deploy Centaur with iron-proxy (default).
  2. From a sandbox, with a token that can read a private repo:
    • gh api user200 (auth works)
    • git clone https://github.com/<org>/<private-repo> → fails with HTTP 400 on git-upload-pack
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions