GUIDE · COMPARISON 13 min ·

Forward proxy vs process-tree credential brokersTwo architectures. One decision.

Both patterns sit between your agent and its secrets. They just sit at different boundaries. Choosing the wrong one for your stack adds complexity without reducing risk.

TL;DR· the answer, in twenty seconds

What: Forward proxies intercept HTTP/S traffic from an agent and inject credentials as headers or strip them before they reach downstream systems. Process-tree brokers deliver credentials into a child process's environment at exec time and revoke them when the process exits.

Fix: Use a proxy (mitmproxy, Envoy with ext_authz, Cloudflare egress) when you need multi-host policy or when credentials travel over the wire to third-party APIs. Use a process-tree broker (hasp run, 1Password CLI's op run, Doppler's doppler run) when secrets must never reach the network layer and scope-to-command is the goal.

Lesson: The boundary type determines what you can audit, what breaks under TLS pinning, and how much container friction you accept. Match the boundary to the threat, not to the tool you already have deployed.

Both patterns exist to solve the same problem: an AI agent needs credentials to do its job, and you do not want those credentials sitting in ambient environment variables where every subprocess can read them for the rest of the session.

Forward proxies intercept at the network layer. They sit between the agent's outbound connections and the internet, inspect or rewrite traffic, and inject or strip authorization headers in flight. Process-tree brokers intercept at the process boundary. They wrap a child process at exec time, deliver credentials into its environment, watch the process tree, and revoke the grant when the root process exits.

Pick the wrong architecture and you get either a proxy that breaks every time a dependency pins its TLS certificate, or a process broker that cannot enforce policy across a fleet of containers on different hosts. Most teams reach for one because they already have it deployed, not because they compared tradeoffs. This article does that comparison.

What to know in 60 seconds

  • A forward proxy sees network traffic. It can log every outbound request, inject auth headers, and block unwanted destinations. It cannot see secrets that never touch the network (env vars, temp files, in-memory values).
  • A process-tree broker sees the exec boundary. It controls what enters a child process's environment and watches when the process exits. It cannot see what that process sends over the network after it has the credential.
  • Proxies break under TLS pinning. Any agent dependency that pins its server certificate will refuse connections from a proxy running a self-signed CA. Debugging this failure takes hours the first time.
  • Process-tree brokers add no network overhead. The credential is in the child's environment from the start. No intercepted connections, no injected headers, no cert chain to manage.
  • Both patterns can produce audit trails. They audit different things: proxies log per-request egress; process brokers log per-process grants.
  • Multi-host enforcement requires a proxy or a distributed credential service. A local process broker has no reach beyond the machine it runs on.

What a forward proxy does

A forward proxy intercepts outbound TCP connections from the agent process, establishes its own TLS session with the upstream server, and sits in the middle of every request. The classic deployment uses mitmproxy in transparent mode or Envoy as a sidecar with the ext_authz filter pointing at an authorization service.

# mitmproxy in transparent mode, injecting an auth header
mitmproxy --mode transparent \
  --modify-headers '/~q/Authorization/Bearer ${VAULT_TOKEN}'
# Envoy ext_authz filter excerpt
http_filters:
  - name: envoy.filters.http.ext_authz
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
      grpc_service:
        envoy_grpc:
          cluster_name: authz_service
      failure_mode_allow: false

In both cases the proxy injects the credential into the request after it leaves the agent. The agent itself never holds the secret; it sends a request without auth and the proxy adds it.

Cloudflare-style egress proxies work the same way at the network edge. The agent's outbound traffic routes through a Cloudflare Worker or Tunnel that rewrites or adds headers before the request reaches the target API. Truffle Security's CanaryTokens uses the same intercept point in reverse: tokens that look like real credentials trip an alert the moment a proxy sees them in a request, which gives you visibility into where credentials end up going.

Proxies log every outbound request with full URL, method, response code, and latency. They block destinations the agent should not reach and inject credentials without the agent needing any credential-handling code. The intercept runs at the TCP level, so it works across language runtimes.

The cost is certificate management. Every HTTPS connection requires your CA to be trusted. You install the proxy's root cert into the system trust store, or into each runtime's trust store if it maintains its own (Node.js, Python's certifi, and Go's standard library all have opinions about this). You repeat that step in every container. When a dependency uses its own cert bundle or pins to a specific CA, the proxy connection fails with a TLS handshake error.

A local mitmproxy instance adds roughly 1-5ms per request on a modern laptop. For a coding agent making 20-30 API calls per session, that is negligible. For a data pipeline agent making thousands of calls per minute, it accumulates.

What a process-tree broker does

A process-tree broker wraps a child process at exec time. You call the broker instead of calling your agent directly. The broker fetches the credential from its store, injects it into the child's environment, tracks the process tree, and cleans up when the root process exits.

The Unix primitive: pass credentials as environment variables to the child at exec, scoped only to that invocation, without exporting them into your current shell session.

# 1Password CLI: inject secrets at exec time
op run --env-file=.env.1p -- claude code

# Doppler: inject per-environment secrets into a specific process
doppler run -- claude code

# hasp: process-tree scoped grant with HMAC-chained audit log
hasp run -- claude code

Each of these commands does the same thing at the OS level: the child process gets specific env vars; your current shell does not. When claude code exits, nothing in your shell session holds the values. If claude code spawns subprocesses (tool calls, shell commands, git operations), those inherit the env vars too, because Unix process inheritance flows down the tree.

The broker tracks the process tree using OS-level mechanisms. On Linux, prctl(PR_SET_CHILD_SUBREAPER, 1) makes the broker the reaper for the subtree, so orphaned grandchildren stay visible rather than reparenting to PID 1. On macOS, kqueue with EVFILT_PROC and NOTE_EXIT delivers exit events for watched PIDs. When the root process exits, the broker records the grant end in the audit log.

Process-tree brokers add zero network overhead and no certificate management. They work with any TLS configuration, including pinned certs, because they never touch the connection. Credential scope is tied to process lifetime, which maps naturally to the duration of an agent task. Audit log entries record the credential identifier, the PID, the command, and the exact start and end times of the grant.

The cost is visibility into what happens inside the process. The credential is in the child's environment, readable by any code the child runs. The broker controls the delivery boundary, not the usage boundary. If the agent writes STRIPE_KEY to a log file or a state file, the value escapes the tree. The broker does not see that. A proxy does, because it catches the outbound request the value travels in.

Double-forking daemons escape process-tree scope. A process that calls fork() twice and lets the intermediate child exit produces a grandchild attached to PID 1. The broker loses track. TTL-based expiry is the fallback: set a ceiling on the grant duration that is shorter than any plausible daemon lifetime.

Where they overlap

Either pattern can scope credential access to a specific task window. A proxy enforces a time-bounded policy that stops injecting auth after a certain timestamp. A process broker expires the grant when the root process exits, which typically maps to the same task boundary.

Audit logging is table stakes for both, but the unit differs. Proxies log per-request: URL, method, headers (sanitized), response code, latency. Process brokers log per-grant: credential ID, process ID, command, wall-clock start and end. "Did the agent make a request to api.stripe.com at 14:32?" is a proxy question. "Did the agent hold the production Stripe key during this session?" is a broker question.

Least privilege is enforceable with either. A proxy blocks requests to destinations the agent should not reach. A process broker grants only the specific credentials a task needs and withholds others.

1Password illustrates how the two approaches can coexist around the same vault. The 1Password CLI's op run is a process-tree broker. 1Password service accounts can also generate short-lived tokens that a proxy fetches at request time. Same vault, two boundary points.

Where they diverge

TLS pinning and certificate pinning. A proxy breaks when a client pins its server certificate. HTTP/2 with TLS 1.3 and certificate pinning is common in mobile SDKs and in some AI provider client libraries. The Anthropic Python client does not pin, but dependencies it pulls in might. Every time you add a new npm or pip package that uses its own TLS stack, you create a potential proxy compatibility problem. Process brokers have zero TLS involvement and break nothing.

Container boundaries. A proxy deployed as a sidecar (Envoy next to your agent container) survives container restarts and works across the container's network namespace. A process broker running inside the container is scoped to that container's process tree, which is usually what you want. The problem comes when you need to enforce the same credential policy across a fleet: 50 containers on 10 hosts, each running a coding agent. A proxy at the egress point covers all of them. A process broker on each host needs a mechanism to sync policy, which usually means running a distributed credential service alongside it (HashiCorp Vault, AWS Secrets Manager, Doppler) and using the broker only for the last-mile delivery.

HTTP/2 and streaming. Standard mitmproxy intercepts HTTP/1.1 well. HTTP/2 streams are harder because they multiplex requests over a single connection, which complicates per-request auth injection. Envoy handles HTTP/2 natively because it speaks H2 at both sides. A process broker is indifferent to the protocol: it delivers the env var before the connection opens, so the client library handles the protocol however it wants.

On-host vs net-layer. A process broker is entirely local. It requires no network infrastructure, no sidecar, no PKI. You can run it on a developer's laptop with one command. A proxy requires either a local listener (mitmproxy on the same machine) or a network hop to a proxy service (Envoy, Cloudflare). For developer-local use, a process broker is far less infrastructure. For fleet-wide enforcement, the proxy wins.

Audit trail granularity. Proxies give you request-level forensics: reconstruct every API call the agent made, with timing. Process brokers give you grant-level forensics: the agent held credential X from 14:00 to 14:47. Each answers a question the other cannot. Running only one means you cannot answer the other question at all.

Comparison table

Dimension Forward proxy Process-tree broker
Intercept point Network layer (TCP/TLS) Process boundary (exec/env)
Example tools mitmproxy, Envoy + ext_authz, Cloudflare Tunnel 1Password CLI op run, Doppler doppler run, hasp run
TLS pinning compat Breaks on pinned certs No TLS involvement
HTTP/2 support Envoy yes; mitmproxy partial Indifferent
Container deployment Sidecar or gateway; works across containers Process-local; one instance per host
Multi-host enforcement Yes, at egress point Requires distributed credential service
Network overhead 1-5ms per request (local proxy) Zero
Cert management CA must be trusted by every runtime None
Audit log unit Per request Per process grant
Credential in child env No (proxy injects into headers) Yes (env var inheritance)
Sees credential value? Injects it; yes Delivers it; yes
Escaping the boundary Redirect traffic around the proxy Double-fork daemonization
Developer laptop friction Medium (CA install, iptables rules) Low (one command wrap)
Fleet-scale friction Low (one egress point) High without a sync mechanism
Works with mTLS apps Breaks; proxy cannot impersonate both sides No issue

When the proxy is the wrong choice

mTLS applications cannot route through a MITM proxy. When the agent connects to a service that requires client certificate authentication, the proxy cannot present the correct client cert. The connection fails before any request is made. If your agent stack includes mTLS-secured internal services (common in service meshes using Istio or Linkerd), a transparent MITM proxy is incompatible.

Pinned TLS is the same problem with a different error message. The client expects a specific certificate or CA. The proxy presents its own CA. The client rejects it. You see CERTIFICATE_VERIFY_FAILED or SSL_ERROR_RX_UNEXPECTED_CERTIFICATE in the agent logs, and the fix is either to unpin the dependency (which you often cannot do) or to exclude that traffic from proxy interception (which creates a gap in your audit).

Performance-sensitive pipelines pay the proxy tax on every call. For a coding agent running interactively, 1-5ms per request is invisible. For a batch agent making 10,000 API calls in a loop, that is 5-50 additional seconds of latency per run. This is rarely the deciding factor, but it is a real cost.

Maintaining a proxy CA across a team is operational work. Every new container image, every new developer machine, every new CI runner needs the CA installed. Miss one and you get TLS errors that look like network failures. The diagnosis path is not obvious to engineers who did not set up the proxy.

When the process broker is the wrong choice

Multi-host enforcement does not work with a purely local process broker. If you have agents running across a fleet, a process broker on each host means your policy lives on each host. Rotating a credential requires touching every host. Revoking access mid-session requires a mechanism to signal each running broker instance. None of this is impossible, but it is work that a centralized proxy or a distributed credential service handles by default.

Cross-machine audit is fragmented. Each host's broker produces its own audit log. Correlating events across hosts requires shipping those logs to a central collector. A proxy at the egress point produces one log stream for all traffic through it.

Process brokers cannot enforce network-level policy. If the agent has a credential in its environment and decides to call an endpoint it should not, the broker cannot stop that call. A proxy can. If your threat model includes agents calling out to unexpected destinations, a proxy gives you the enforcement point that a process broker lacks.

Long-running agents that daemonize or spawn persistent background jobs escape process-tree scope. The broker sees the root process exit and records the grant end. The background job continues with the credential it inherited. TTL-based expiry mitigates this, but it requires setting a ceiling short enough to matter without interrupting legitimate long-running work.

Checklist: choosing your credential delivery boundary

## Credential broker architecture decision

- [ ] List all agent dependencies that use TLS; check each for cert pinning
- [ ] Check for mTLS requirements on any internal services the agent calls
- [ ] Count agent hosts: local dev only? single CI runner? distributed fleet?
- [ ] Identify whether per-request or per-grant audit granularity satisfies your compliance requirement
- [ ] Assess whether HTTP/2 streaming (Claude API, OpenAI streaming) is affected by proxy TLS intercept
- [ ] Check if existing infra (Envoy service mesh, Cloudflare gateway) already terminates TLS in a useful place
- [ ] Evaluate container cert-injection burden (proxy CA must be trusted by every image)
- [ ] Confirm whether agents ever daemonize or spawn persistent background jobs (broker TTL required)
- [ ] Decide whether you need network-destination enforcement (proxy wins) or env isolation (broker wins)
- [ ] If combining both: define which audit log owns which question (per-request vs per-grant)
- [ ] Test proxy compatibility with streaming API responses before committing to MITM architecture
- [ ] Verify process broker handles subreaper correctly on Linux (PR_SET_CHILD_SUBREAPER) and EVFILT_PROC on macOS

What this means for your stack

The proxy wins when you need fleet-wide enforcement, network-destination policy, or per-request audit trails. The process broker wins when TLS compatibility is a hard constraint, when you want nothing to install beyond one binary for developer-local use, or when scope should end when the process ends rather than when a policy rule says so.

Most teams with a mature AI agent deployment end up running both: a proxy at the egress point for fleet-level visibility and a process broker for last-mile delivery that keeps credentials out of ambient shell environments. Running both lets you answer "what did the agent call?" at the network layer and "what did the agent hold?" at the process boundary. A single architecture answers one; the other question stays open.

hasp is one working implementation of the process-tree broker pattern. curl -fsSL https://gethasp.com/install.sh | sh, hasp setup, connect a project, and hasp run -- your-agent-command gives you process-scoped credential delivery with an HMAC-chained audit log you can verify with hasp audit --verify. It covers the developer-local and single-host cases. For fleet-wide proxy deployment, pair it with Envoy or Cloudflare at the egress layer. Source-available (FCL-1.0), local-first, macOS and Linux, no account.

Credential delivery needs a defined boundary, a defined lifetime, and a record. Both architectures can provide all three. The question is which boundary fits the threat you are actually defending against.

Sources· cited above, in one place

NEXT STEP~90 seconds

Stop handing the agent your real keys.

hasp keeps secrets in one local encrypted vault, brokers them into the child process at exec, and never lets the agent read the value.

  • Local, encrypted vault — no account, no cloud, no telemetry by default.
  • Brokered run — agent gets a reference, the child process gets the value.
  • Pre-commit + pre-push hooks catch managed values before they ship.
  • Append-only HMAC audit log answers "did the agent touch the prod token?" in seconds.
→ okvault unlocked · binding ./api
→ okgrant once · pid 88421
→ okagent never read

macOS & Linux. Source-available (FCL-1.0, converts to Apache 2.0). No account.

Browse all clusters· eight threads, one index