Skip to content

Added callout proxy - #1286

Merged
kristin-kronstain-brown merged 7 commits into
mainfrom
kkb-callout-proxy
Oct 16, 2026
Merged

kristin-kronstain-brown merged 7 commits into
mainfrom
kkb-callout-proxy

Conversation

@kristin-kronstain-brown

@kristin-kronstain-brown kristin-kronstain-brown commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

Documents the callout proxy from agentgateway/agentgateway#3864 (Allow sending callout requests through CONNECT tunnel), which merged to main on 2026-10-09. The change is not in a tagged release yet, so the docs go in the main trees only. Both modes get a page, because the data plane is the same binary in standalone and Kubernetes.

Changes

Standalone

  • New page: standalone/main/documentation/configuration/callout-proxy.md. Covers:
    • Which requests count as callouts.
    • The two ways to configure the proxy, config.callouts.tunnel in the configuration file or the standard proxy environment variables, and which one takes precedence.
    • The destinations that always bypass the proxy.
    • A worked example that sends a remote JWKS fetch through a proxy with config.callouts.tunnel, and then repeats it with HTTPS_PROXY.
  • egress-proxy.md: one sentence that points to the new page. Egress proxy covers the opposite direction, clients sending CONNECT requests through agentgateway, so the two pages are easy to mix up.
  • Release notes: a callout proxy entry under New features, and an upgrade note under Other behavior changes, because callouts now honor proxy environment variables.

Kubernetes

  • New page: kubernetes/main/documentation/setup/customize/callout-proxy.md. Covers:
    • Which requests count as callouts, and two that do not: client traffic to backends, and remote JWKS fetches (see the JWKS row below).
    • The two ways to configure the proxy on AgentgatewayParameters: spec.env or spec.rawConfig.config.callouts.tunnel.
    • The destinations that bypass the proxy, including Kubernetes Services, and the gotcha that an AgentgatewayBackend with a static host goes through the proxy even for a svc.cluster.local hostname.
    • A worked example that deploys Squid, sets HTTPS_PROXY, and sends an external authorization callout to httpbin.org through it.
  • Backend tunnel proxy page (shared asset): one sentence, gated to main, that points to the new page. The tunnel policy covers one backend; the callout proxy covers every callout, and a backend's own tunnel takes precedence.
  • Release notes: a callout proxy entry under New features, and the upgrade note under Other behavior changes, worded for spec.env and including the static-host gotcha.

Testing

Tested with the nightly build 0.0.0-alpha.c0354ea4, which includes #3864, against a CONNECT proxy that logs each request. Where the docs claim a change from 1.6, the claim was compared against the v1.6.0 release binary.

Standalone (local binary):

  • Example YAML: both blocks validate against schema/config.json from main, and agentgateway --validate-only accepts the example.
  • Steps 1 to 5 as written: the remote JWKS fetch goes through the proxy at startup, and the log line on the page matches the real output.
  • Environment variables:
    • HTTPS_PROXY and lowercase https_proxy both work.
    • NO_PROXY=* bypasses the proxy, and so does a subdomain match in NO_PROXY.
    • With the same config, v1.6.0 ignores HTTPS_PROXY, which confirms the upgrade note.
  • Config fields:
    • noProxy bypasses matching hosts.
    • Credentials in the URL reach the proxy as a Proxy-Authorization header.
    • config.callouts.tunnel takes precedence over the environment variables.
  • Guardrail webhooks:
    • A webhook callout goes through the proxy.
    • A plaintext webhook is sent as a forward-proxy request (POST http://host/...), not a CONNECT tunnel.
    • A webhook target with its own backendTunnel uses that tunnel instead.
    • A target of localhost:<port> goes through the proxy, because the loopback bypass applies only to IP addresses.
  • Failure behavior:
    • --validate-only accepts an unsupported scheme such as socks5://, and agentgateway then fails at startup with invalid callouts config.
    • When the proxy is unreachable, the startup JWKS fetch fails and agentgateway exits with failed to load JWKS.

Kubernetes (kind, nightly c0354ea4 controller and proxy):

  • Proxy is used: with spec.env or spec.rawConfig pointing at an unreachable address, an external auth callout to a static AgentgatewayBackend fails with external authorization failed. With Squid, the Squid log shows TCP_TUNNEL/200 CONNECT httpbin.org:443.
  • Bypass: an external auth callout to a Kubernetes Service goes direct. A static backend with a *.svc.cluster.local host goes through the proxy, and NO_PROXY=svc.cluster.local makes it go direct.
  • Startup log: the callouts will use proxy line appears with both configuration methods.
  • Squid logging: Squid writes the CONNECT entry only when the tunnel closes, which is why the page restarts the proxy when the log is empty.
  • Steps 1 to 7 and the cleanup, as written, against a cluster's existing Gateway. The patch in step 3 keeps the Gateway's other settings, and the cleanup returns the Gateway spec to its original state.

Not tested yet. After the style review, steps 8 to 10 and the cleanup's parametersRef path changed and were not rerun. Steps 8 and 9 were also not run against the real Gateway, because that cluster had an unrelated JWT policy on it. These are the first candidates for the doc-tests run.

Resolved during review

Question Answer Source
Did a Kubernetes callout proxy topic already exist? Partly. The Backend tunnel proxy page covers the per-backend tunnel policy, with JWKS as its example. The gateway-wide callout proxy is new, so it gets its own page, and the tunnel page now points to it. Docs
Does the callout proxy cover JWKS fetches in Kubernetes? No. In Kubernetes the controller fetches remote JWKS, and its HTTP client ignores proxy environment variables. Only a backend tunnel policy applies. The Kubernetes page and release note no longer list JWKS. Code: controller/pkg/agentgateway/jwks/fetcher.go
Do callouts from Kubernetes proxies honor the environment variables? Yes. Both spec.env and spec.rawConfig.config.callouts.tunnel work, and callouts to Kubernetes Services bypass the proxy. Tested in kind
Does the services bypass apply to standalone? Yes. A service: reference resolves from the top-level services list, and those backends skip the callout proxy. Code: proxy/httpproxy.rs, proxy/mod.rs
Which requests are callouts? Every request made through the policy client that is not primary or mirror traffic: external authorization, external processing, remote rate limiting, guardrails, OIDC (including MCP authentication), the virtual-model callout router, and cloud credential fetches. The page lists all of them now. Code: internal_call_with_policies; webhook tested
Does the upgrade note overstate? Slightly, for GCP only. The GCP auth library uses reqwest, which already read proxy environment variables, so GCP behavior is unchanged. The AWS SDK client had proxying disabled by default. The upgrade note now says that only GCP credential fetches used these variables in 1.6. Code: aws-smithy-http-client, reqwest; JWKS tested on v1.6.0
Should the two pages share content? No. Their callout lists, bypass lists, configuration methods, and examples differ, so each mode keeps its own page. Review

The intro also claimed that every callout uses a CONNECT tunnel. That claim was wrong for plaintext callouts, which go to the proxy as forward-proxy requests, so the intro is corrected.

Still open

  • Release notes structure. The main release notes still use the 1.6 headings (#v16-…). Entries from after 1.6, such as #3722, #3746, and #3773, sit under those headings even though latest doesn't list them in its 1.6 notes. These entries follow the same pattern. The main file probably needs a next-release skeleton.
  • Squid image. The Kubernetes example uses ubuntu/squid:latest, not a pinned tag.

🤖 Generated with Claude Code

Signed-off-by: Kristin Brown <kristin.brown@solo.io>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Deploying agentproxy with  Cloudflare Pages  Cloudflare Pages

Latest commit: bd43580
Status:⚡️  Build in progress...

View logs

Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>

## Configure the callout proxy

You configure the callout proxy on the agentgateway proxy deployment through an {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource, in either of the following ways. If you use both, `config.callouts.tunnel` takes precedence, and the agentgateway proxy ignores the proxy environment variables for callouts.

@Nadine2016 Nadine2016 Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move If you use both, config.callouts.tunnel takes precedence, and the agentgateway proxy ignores the proxy environment variables for callouts. to after the options (next paragraph)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. The precedence sentence now comes after the two options. I made the same move on the standalone page.

| `HTTPS_PROXY` | The forward proxy for callouts that use TLS. |
| `HTTP_PROXY` | The forward proxy for plaintext callouts. |
| `ALL_PROXY` | The forward proxy for callouts when you omit `HTTPS_PROXY` or `HTTP_PROXY`. |
| `NO_PROXY` | A comma-separated list of destinations that bypass the forward proxy. Each entry is a hostname, an IP address, a Classless Inter-Domain Routing (CIDR) range, or `*` for every destination. A hostname also matches its subdomains. |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would I se NO_PROXY alongside HTTPS_PROXY, etc? Also, I think it would be good to show an example config, because I am not sure what exactly to put into these variables

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you set NO_PROXY alongside HTTPS_PROXY. I added a sentence that says so, plus an example spec.env block that sets HTTPS_PROXY, HTTP_PROXY, and NO_PROXY. The standalone page gets the same example as export commands.

* Destinations that match `noProxy` or `NO_PROXY`.
* Loopback and link-local IP addresses, such as `127.0.0.1` and the cloud metadata server at `169.254.169.254`. A remote forward proxy cannot reach these addresses.
* Callouts to an {{< reuse "agw-docs/snippets/backend.md" >}} that has its own `tunnel` policy. These callouts use that tunnel instead.
* GCP credential fetches, when you configure the callout proxy with `config.callouts.tunnel`. To send these fetches through a forward proxy, use the environment variables instead.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for completion this should probably also list the jwks fetch that you have earlier

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I added a bullet for remote JWKS fetches that says the control plane makes them, and links back to About callouts.


To use `rawConfig` instead, replace `spec.env` with `spec.rawConfig.config.callouts.tunnel.url`, as shown in [rawConfig](#rawconfig).

3. Attach the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource to your Gateway with `infrastructure.parametersRef`. The patch keeps the rest of your Gateway as it is. If your Gateway already references an {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource, add the `spec.env` setting to that resource instead, because a Gateway references one resource only.

@Nadine2016 Nadine2016 Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
3. Attach the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource to your Gateway with `infrastructure.parametersRef`. The patch keeps the rest of your Gateway as it is. If your Gateway already references an {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource, add the `spec.env` setting to that resource instead, because a Gateway references one resource only.
3. Attach the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource to your Gateway. The patch keeps the rest of your Gateway as it is. If your Gateway already references an {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource, add the `spec.env` setting to that resource instead, because a Gateway can reference one {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource only.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied.

kubectl rollout status deployment/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}}
```

5. Check the agentgateway proxy logs for the line that names the forward proxy. The label selector reads every agentgateway proxy pod, so the command also works while an old pod is still shutting down.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
5. Check the agentgateway proxy logs for the line that names the forward proxy. The label selector reads every agentgateway proxy pod, so the command also works while an old pod is still shutting down.
5. Check the agentgateway proxy logs for the line that names the forward proxy.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied.

EOF
```

7. Create an {{< reuse "agw-docs/snippets/policy.md" >}} that sends an external authorization request for every request to the httpbin route. The `/status/200` path makes `httpbin.org` allow every request. The `http.path` value is a CEL expression, so the path is a string literal in double quotes.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
7. Create an {{< reuse "agw-docs/snippets/policy.md" >}} that sends an external authorization request for every request to the httpbin route. The `/status/200` path makes `httpbin.org` allow every request. The `http.path` value is a CEL expression, so the path is a string literal in double quotes.
7. Create an {{< reuse "agw-docs/snippets/policy.md" >}} that sends an external authorization request for every request to the httpbin stand-in authorization server. The `/status/200` path makes `httpbin.org` allow every request. The `http.path` value is a CEL expression, so the path is a string literal in double quotes.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied.

kubectl rollout restart deployment/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}}
kubectl rollout status deployment/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}}
kubectl exec -n squid deployment/squid -- cat /var/log/squid/access.log
```

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what would be nice as another verification step when we would also show that the request got forwarded to the httpbin.org backend so you have the full flow. httpbin > squid > httpbin.org

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. The Squid log line in step 9 already shows the full path, but the page didn't explain it. I added a sentence and a small table that explains the fields: the source IP is the agentgateway pod, TCP_TUNNEL/200 means Squid opened the tunnel, and HIER_DIRECT/<ip> means Squid connected to httpbin.org. Would you also want a negative check, such as switching the path to /status/403 to show the request gets denied? I left that out for now because I haven't tested it.

You configure the callout proxy on the agentgateway proxy deployment through an {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource, in either of the following ways. If you use both, `config.callouts.tunnel` takes precedence, and the agentgateway proxy ignores the proxy environment variables for callouts.

* **[With environment variables](#environment-variables)**: Set the standard proxy environment variables, such as `HTTPS_PROXY`, in `spec.env`. Use this configuration for most setups. Note that this configuration is also the only way to send GCP credential fetches through the forward proxy.
* **[In `rawConfig`](#rawconfig)**: Set `config.callouts.tunnel` in `spec.rawConfig`. Use this way to keep the forward proxy settings separate from environment variables that other tools in the pod read. The control plane reads `rawConfig` only from an {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource that a Gateway references.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude: rawConfig claim contradicts the controller (Kubernetes page, line 29). It says "The control plane reads rawConfig only from an AgentgatewayParameters resource that a Gateway references." ApplyToHelmValues runs for the GatewayClass parameters and then the Gateway parameters, and both apply RawConfig (controller/pkg/deployer/agentgateway_parameters.go:180 and :301-308). setIfNonNil means the Gateway's rawConfig replaces the GatewayClass's wholesale instead of merging.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, I checked agentgateway_parameters.go. The GatewayClass parameters apply first, and then the Gateway parameters, and setIfNonNil swaps in the Gateway's rawConfig as a whole. I removed the wrong sentence. The rawConfig section now says you can set it on parameters that a Gateway or a GatewayClass references, and that the Gateway's rawConfig replaces the GatewayClass's instead of merging with it.

You configure the callout proxy on the agentgateway proxy deployment through an {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource, in either of the following ways. If you use both, `config.callouts.tunnel` takes precedence, and the agentgateway proxy ignores the proxy environment variables for callouts.

* **[With environment variables](#environment-variables)**: Set the standard proxy environment variables, such as `HTTPS_PROXY`, in `spec.env`. Use this configuration for most setups. Note that this configuration is also the only way to send GCP credential fetches through the forward proxy.
* **[In `rawConfig`](#rawconfig)**: Set `config.callouts.tunnel` in `spec.rawConfig`. Use this way to keep the forward proxy settings separate from environment variables that other tools in the pod read. The control plane reads `rawConfig` only from an {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource that a Gateway references.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Broken in-page anchors. The links point at #environment-variables, #rawconfig and #configuration-file, but the headings are "Option 1: …" and "Option 2: …"

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. I added explicit anchors to the headings ({#environment-variables}, {#rawconfig}, and {#configuration-file} on the standalone page). The links now resolve, and the headings can still say "Option 1" and "Option 2".


You configure the callout proxy on the agentgateway proxy deployment through an {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource, in either of the following ways. If you use both, `config.callouts.tunnel` takes precedence, and the agentgateway proxy ignores the proxy environment variables for callouts.

* **[With environment variables](#environment-variables)**: Set the standard proxy environment variables, such as `HTTPS_PROXY`, in `spec.env`. Use this configuration for most setups. Note that this configuration is also the only way to send GCP credential fetches through the forward proxy.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude thinks this is not true: The pages say the env vars are ignored when config.callouts.tunnel is set. That is not quite true for GCP, whose library still reads them if they are set.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The anchors are also wrong, the built HTML has #option-1-environment-variables, #option-2-rawconfig, #option-1-configuration-file, and #option-2-environment-variables

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. In callout.rs, config.callouts.tunnel makes agentgateway's own callout client skip the env vars. GCP credential fetches don't go through that client, though, and the GCP library still reads the env vars. I reworded both pages: tunnel takes precedence for most callouts, but GCP fetches never use the tunnel and still use the env vars if you set them.

- **Streaming guardrails**: Agentgateway now rejects content if a provider guard fails while checking a streamed response or realtime connection. To keep the 1.5 behavior, set `failureMode: FailOpen` on the guard. For example, set it in `spec.backend.ai.promptGuard.response[].bedrockGuardrails` of an {{< reuse "agw-docs/snippets/policy.md" >}}. For more information, see [Provider failures]({{< link-hextra path="/documentation/llm/guardrails/overview/#provider-failures" >}}).
- **Token usage in responses**: The `usage` that agentgateway returns to clients now follows the conventions of the API that the client calls, whichever provider serves the request. Anthropic Messages responses leave cache tokens out of `input_tokens` and report them in `cache_read_input_tokens` and `cache_creation_input_tokens`. OpenAI Chat Completions and Responses include cache tokens in the input and total token counts. For example, a Chat Completions request to an Anthropic or Amazon Bedrock model that writes to the prompt cache now reports those cache tokens in `prompt_tokens`. If a client calculates usage or cost from these fields, review its counts after you upgrade.
- **Deployer ownership**: The controller no longer overwrites an existing resource of the same name that it does not own. It reports an error instead.
- **Proxy environment variables**: Callouts from the proxy, such as external authorization requests, guardrail requests, and AWS and Azure credential fetches, now use the `HTTPS_PROXY`, `HTTP_PROXY`, `ALL_PROXY`, and `NO_PROXY` environment variables. If you set these variables in `spec.env` of the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource for another purpose, callouts go through that proxy after you upgrade. Callouts to a Kubernetes Service go directly to the Service. Callouts to an {{< reuse "agw-docs/snippets/backend.md" >}} with a `static` host go through the proxy, even for a `svc.cluster.local` hostname, unless `NO_PROXY` lists `svc.cluster.local`. To keep all callouts direct, set `NO_PROXY` to `*`. In 1.6, only Google Cloud Platform (GCP) credential fetches used these variables. For more information, see [Callout proxy]({{< link-hextra path="/documentation/setup/customize/callout-proxy/" >}}).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- **Proxy environment variables**: Callouts from the proxy, such as external authorization requests, guardrail requests, and AWS and Azure credential fetches, now use the `HTTPS_PROXY`, `HTTP_PROXY`, `ALL_PROXY`, and `NO_PROXY` environment variables. If you set these variables in `spec.env` of the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource for another purpose, callouts go through that proxy after you upgrade. Callouts to a Kubernetes Service go directly to the Service. Callouts to an {{< reuse "agw-docs/snippets/backend.md" >}} with a `static` host go through the proxy, even for a `svc.cluster.local` hostname, unless `NO_PROXY` lists `svc.cluster.local`. To keep all callouts direct, set `NO_PROXY` to `*`. In 1.6, only Google Cloud Platform (GCP) credential fetches used these variables. For more information, see [Callout proxy]({{< link-hextra path="/documentation/setup/customize/callout-proxy/" >}}).
- **Proxy environment variables**: Callouts from the proxy, such as external authorization requests, guardrail requests, and AWS and Azure credential fetches, now use the `HTTPS_PROXY`, `HTTP_PROXY`, `ALL_PROXY`, and `NO_PROXY` environment variables to configure a forward proxy that these requests must be routed through. For more information, see [Callout proxy]({{< link-hextra path="/documentation/setup/customize/callout-proxy/" >}}).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took most of this, but I kept two parts of the old text. Without them, this bullet doesn't say why it's in Behavior changes. The bullet now uses your first sentence, and then keeps "In 1.6, only GCP fetches used these variables," the warning about existing spec.env variables, and the NO_PROXY=* opt-out. I dropped the static-host detail, because the page covers it. More on why it stays in Behavior changes in the standalone thread.

- **Telemetry**: OTLP access logs use the `agentgateway.access` instrumentation scope. The request duration metric records failed requests with an `error_type` label.
- **Istio permissions**: Set the `istio.enabled=false` Helm value to drop the Istio permissions from the controller ClusterRole. For more information, see [Istio resource discovery]({{< link-hextra path="/documentation/install/advanced/#istio-discovery" >}}).
- **Gateway name in proxy metrics**: When `monitoring.enabled` is `true`, the Helm chart creates a PodMonitor. The PodMonitor now copies the `gateway.networking.k8s.io/gateway-name` pod label onto proxy metrics. This label lets the Grafana dashboard filter by Gateway. To change the copied labels, set the `monitoring.proxy.podMonitor.podTargetLabels` Helm value.
- **Callout proxy**: You can now send the requests that the agentgateway proxy makes on its own behalf, such as external authorization requests, guardrail requests, and cloud provider credential fetches, through a forward proxy. Set the standard proxy environment variables in `spec.env` of an {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource, or set `config.callouts.tunnel` in `spec.rawConfig`. For more information, see [Callout proxy]({{< link-hextra path="/documentation/setup/customize/callout-proxy/" >}}).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- **Callout proxy**: You can now send the requests that the agentgateway proxy makes on its own behalf, such as external authorization requests, guardrail requests, and cloud provider credential fetches, through a forward proxy. Set the standard proxy environment variables in `spec.env` of an {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource, or set `config.callouts.tunnel` in `spec.rawConfig`. For more information, see [Callout proxy]({{< link-hextra path="/documentation/setup/customize/callout-proxy/" >}}).
- **Callout proxy**: You can now send the requests that the agentgateway proxy makes on its own behalf, such as external authorization requests, guardrail requests, and cloud provider credential fetches, through a forward proxy. For more information, see [Callout proxy]({{< link-hextra path="/documentation/setup/customize/callout-proxy/" >}}).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied, without the double space.

You can configure the callout proxy in either of the following ways. If you use both, `config.callouts.tunnel` takes precedence, and agentgateway ignores the proxy environment variables for callouts.

* **[In the configuration file](#configuration-file)**: Set `config.callouts.tunnel`. Use this method to keep the proxy settings with the rest of your configuration.
* **[With environment variables](#environment-variables)**: Set the standard proxy environment variables, such as `HTTPS_PROXY`. Use this method to send GCP credential fetches through the proxy, or to reuse variables that your environment already sets.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar comments regarding wording, link anchors, etc. as in kube

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I made the same changes as on the Kubernetes page: moved the precedence sentence, pinned the anchors, added the GCP exception, and added an env var example with NO_PROXY.


### Option 1: Configuration file

Set `config.callouts.tunnel` in your configuration file. Settings in the `config` section take effect at startup, so restart agentgateway after you change this setting. For more information, see [Static configuration]({{< link-hextra path="/documentation/configuration/static-configuration/" >}}).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Set `config.callouts.tunnel` in your configuration file. Settings in the `config` section take effect at startup, so restart agentgateway after you change this setting. For more information, see [Static configuration]({{< link-hextra path="/documentation/configuration/static-configuration/" >}}).
Set `config.callouts.tunnel` in your configuration file to configure the forward proxy that you want to route requests through. Settings in the `config` section take effect at startup, so restart agentgateway after you change this setting. For more information, see [Static configuration]({{< link-hextra path="/documentation/configuration/static-configuration/" >}}).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied.


| Setting | Description |
| -- | -- |
| `config.callouts.tunnel.url` | The URL of the proxy. This proxy handles every callout, whether the callout uses Transport Layer Security (TLS) or plaintext. The scheme must be `http` or `https`. With `https`, the connection to the proxy uses TLS, and the proxy certificate is verified against the system trust bundle. If you omit the port, the default is `80` for `http` and `443` for `https`. To authenticate to the proxy with basic authentication, include the credentials in the URL, such as `http://user:password@proxy.example.com:3128`. The `--validate-only` flag does not check the scheme. A URL with an unsupported scheme, such as `socks5://`, passes validation, and then agentgateway fails to start with an `invalid callouts config` error. |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| `config.callouts.tunnel.url` | The URL of the proxy. This proxy handles every callout, whether the callout uses Transport Layer Security (TLS) or plaintext. The scheme must be `http` or `https`. With `https`, the connection to the proxy uses TLS, and the proxy certificate is verified against the system trust bundle. If you omit the port, the default is `80` for `http` and `443` for `https`. To authenticate to the proxy with basic authentication, include the credentials in the URL, such as `http://user:password@proxy.example.com:3128`. The `--validate-only` flag does not check the scheme. A URL with an unsupported scheme, such as `socks5://`, passes validation, and then agentgateway fails to start with an `invalid callouts config` error. |
| `config.callouts.tunnel.url` | The URL and port of the forward proxy. This proxy handles every callout, whether the callout uses Transport Layer Security (TLS) or plaintext. The scheme must be `http` or `https`. With `https`, the connection to the proxy uses TLS, and the proxy certificate is verified against the system trust bundle. If you omit the port, the default is `80` for `http` and `443` for `https`. To authenticate to the proxy with basic authentication, include the credentials in the URL, such as `http://user:password@proxy.example.com:3128`. The `--validate-only` flag does not check the scheme. A URL with an unsupported scheme, such as `socks5://`, passes validation, and then agentgateway fails to start with an `invalid callouts config` error. |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is the --validate-only flag set?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied. About --validate-only: it's a flag on the agentgateway command, and step 2 of the example uses it. I reworded the table to "The agentgateway --validate-only command, which checks a configuration file without starting agentgateway, does not check the scheme."


{{< reuse "agw-docs/snippets/prereq-agentgateway.md" >}}

You also need an HTTP proxy that supports the CONNECT method and logs the requests that it receives, such as Squid. The following steps assume that the proxy listens on `http://127.0.0.1:3128`.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we might want to give them a docker command to bring up this container in Docker

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude had this to say, too about the Docker command. Also, this is not in ordered steps.

With docker run -p 3128:3128 ubuntu/squid, a request from the host returns 403 on CONNECT, because the default ACL rejects the Docker bridge address. A permissive squid.conf fixed it: http_port 3128, acl all src all, http_access allow all. Squid then returned 200 and logged the CONNECT. I ran that recipe against curl, not against the standalone binary. Please add a short working recipe, for example a minimal squid.conf that allows the test client, or link to a proxy setup that works.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Before you begin is now a numbered list. Step 2 has two substeps: create a squid.conf that allows any client, and run ubuntu/squid with that file mounted and port 3128 published. The squid.conf is your recipe (http_port 3128, acl all src all, http_access allow all), and the page says why it's needed: the default config returns 403 for the Docker bridge address.

| Setting | Description |
| -- | -- |
| `config.callouts.tunnel.url` | The address of the proxy. The loopback bypass applies to callout destinations, not to the proxy. A proxy on `127.0.0.1` still receives the callouts. |
| `jwtAuth.jwks.url` | The remote JWKS. The JWKS fetch is a callout and goes through the proxy. |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| `jwtAuth.jwks.url` | The remote JWKS. The JWKS fetch is a callout and goes through the proxy. |
| `jwtAuth.jwks.url` | The remote JWKS. The JWKS fetch is a callout and goes through the forward proxy. |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

general feedback: I would try to use forward proxy as much as possible since agentgateway is also a proxy and it is sometimes hard to understand which proxy we are talking about

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied. I also switched to "forward proxy" across the whole standalone page and the standalone release note. The page now says "proxy" alone only in env var names and in the "callout proxy" feature name.

- **Token usage in responses**: The `usage` that agentgateway returns to clients now follows the conventions of the API that the client calls, whichever provider serves the request. Anthropic Messages responses leave cache tokens out of `input_tokens` and report them in `cache_read_input_tokens` and `cache_creation_input_tokens`. OpenAI Chat Completions and Responses include cache tokens in the input and total token counts. For example, a Chat Completions request to an Anthropic or Amazon Bedrock model that writes to the prompt cache now reports those cache tokens in `prompt_tokens`. If a client calculates usage or cost from these fields, review its counts after you upgrade.
- **Policy service timeouts**: Calls to external services default to a timeout of 2 seconds for gRPC external authorization and 10 seconds for rate limit and external processing services.
- **Streaming guardrails**: Agentgateway now rejects content if a provider guard fails while checking a streamed response or realtime connection. To keep the 1.5 behavior, set `failureMode: failOpen` on the guard. For example, set it in `ai.promptGuard.response[].bedrockGuardrails`. For more information, see [Provider failures]({{< link-hextra path="/documentation/llm/prompt-guards/overview/#provider-failures" >}}).
- **Proxy environment variables**: Callouts, such as JWKS fetches, external authorization requests, and AWS and Azure credential fetches, now use the `HTTPS_PROXY`, `HTTP_PROXY`, `ALL_PROXY`, and `NO_PROXY` environment variables when `config.callouts.tunnel` is omitted. In 1.6, only Google Cloud Platform (GCP) credential fetches used these variables. If the environment that runs agentgateway exports these variables for other tools, callouts go through that proxy after you upgrade. To keep callouts direct, set `NO_PROXY` to `*`. For more information, see [Callout proxy]({{< link-hextra path="/documentation/configuration/callout-proxy/" >}}).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wondering if we need it under behavior changes. isn't this just a new feature? same comment for kube

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd keep it in both places. The new feature is the callout proxy itself, so it goes under New features. The behavior change is that callouts now read HTTPS_PROXY and friends with no opt-in. So if someone already exports these variables for another tool, or sets them in spec.env, their ext auth, guardrail, and AWS or Azure credential calls start going through that proxy after upgrade. 1.6.0 ignored them (I tested this). That can break a working setup, so I think upgraders need to see it under Behavior changes. Happy to drop it if you disagree, though.

info client::callout callouts will use proxy Matcher { http: Intercept { uri: http://127.0.0.1:3128/ }, https: Intercept { uri: http://127.0.0.1:3128/ } }
```

4. Check the access log of your proxy for a CONNECT request to `www.googleapis.com:443`, the JWKS host. The log format depends on your proxy.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No log example output.

Also, claude thinks that Squid writes the CONNECT log entry only when the tunnel closes, just curious if you noticed this when you tried it? if so, might be worth a line like:

"Squid writes the entry when the tunnel closes. If the log is empty, stop agentgateway with Ctrl+C, and then check again."

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I saw this in Kubernetes too, and step 10 there covers it. Added to step 4: a docker exec squid cat /var/log/squid/access.log command for the Squid container from Before you begin, an example log line, and your note about stopping agentgateway with Ctrl+C if the log is empty.

Signed-off-by: Kristin Brown <kristin.brown@solo.io>
@kristin-kronstain-brown
kristin-kronstain-brown merged commit e9779d0 into main Oct 16, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants