How it works

Trust boundaries, request flow, and what each component holds.

Trust boundaries

Untrusted: the agent, its commands, repository contents, package scripts, prompts, and issue text.

Trusted: the broker process, host operator, configuration, state directory, private key, and container/network administrator.

In static mode the daemon serves one runtime identity loaded from host-controlled configuration, so deploy one broker per isolated workspace. In fleet mode it holds no workspace token and serves many workspaces, each authenticated by the token its signed assertion is bound to. Requests cannot choose their identity in either mode. Never publish the listener to a shared or public network.

A push, step by step

  1. Rate limit. A per-client token bucket runs before anything else.
  2. Host and origin. Browser-origin requests and unexpected Host values are rejected.
  3. Authenticate. The workspace bearer token and, in assertion mode, a signed runtime assertion are verified; a per-runtime rate limit and, if configured, the delegation check run here.
  4. Parse. The broker buffers only the receive-pack command section (at most 1 MiB) and parses every ref update strictly. Malformed packets and unsupported extensions fail closed.
  5. Decide. Each ref is checked against policy. If any ref is denied, nothing is forwarded.
  6. Approve. If a rule requires approval, the broker stores a pending request and returns 403 REQUIRE_APPROVAL.
  7. Scan. For repositories with scan, the pack is quarantined and every added blob inspected.
  8. Audit. The decision is appended to the hash-chained log. If the write fails, the push is not forwarded.
  9. Forward. A token scoped to one repository is minted, and the pack streams upstream to a fixed GitHub endpoint. Redirects are rejected.

Where secrets live

SecretHolderWorkspace can see it?
GitHub App private keyagentd from a file, or AWS KMS via AGENTGATE_KMS_KEY_ID (the key never exists on the host), or any HSM via AGENTGATE_SIGN_COMMANDNo
Installation tokensagentd memoryNo
Workspace client tokenworkspace + agentdYes — identifies the workspace, not a secret from the agent
Model API keymodel-gatewayNo
Approval-web admin secretagentd + approval-webNo
Issuer private keyissuer-web (or the issuing host running the script)No
Runtime assertionworkspace + agentdYes, it identifies the runtime; useless without the bound token

Networks (Compose)

  • workspace — internal only. Workspace, agentd, egress-proxy, model-gateway.
  • upstream — internet-facing. agentd, egress-proxy, model-gateway, audit-forwarder.
  • approval — internal. approval-web, issuer-web, and oauth2-proxy (compose.enterprise.yaml).
  • monitoring — fixed subnet for the Prometheus metrics listener.

The workspace has no route to GitHub or the internet. Its DNS points at 127.0.0.1, so external names don't resolve and DNS can't be used for exfiltration.

Supported Git

Unsigned SHA-1 pushes, shallow pushes, allowlisted push options, NFC-normalized Unicode refs (opt-in), and Git LFS. Signed pushes (push certificates), SHA-256 repositories, compressed requests, and LFS locking are refused. Signed commits pass through.