Skip to main content
Agentgateway is configured through YAML or JSON files (the two formats are fully equivalent). Configuration is split into three forms: static config for global process settings, local config for full proxy configuration with hot-reload, and XDS config for remote control plane management.

File format

Configuration files use the following top-level structure:
# yaml-language-server: $schema=https://agentgateway.dev/schema/config

# Global process settings (static — requires restart to change)
config:
  logging:
    format: json
  adminAddr: "0.0.0.0:9901"

# Traffic configuration (dynamic — hot-reloaded on file change)
binds:
- port: 3000
  listeners:
  - routes:
    - backends:
      - host: upstream:8080
Adding the # yaml-language-server comment at the top of your config file enables schema validation and autocompletion in editors that support the YAML Language Server.
JSON is fully equivalent to YAML:
binds:
- port: 3000
  listeners:
  - routes:
    - backends:
      - host: upstream:8080

Static configuration

The config block contains settings that are read once at startup. These control global behaviors that apply to the entire process.
config:
  # Logging
  logging:
    format: json          # "json" or "text"
    level: info           # trace, debug, info, warn, error

  # Observability servers
  adminAddr: "0.0.0.0:9901"      # Admin UI
  statsAddr: "0.0.0.0:9902"      # Prometheus metrics
  readinessAddr: "0.0.0.0:9903"  # Readiness probe

  # DNS resolver
  dns:
    lookupFamily: Auto    # All, Auto, V4Preferred, V4Only, V6Only

  # OpenTelemetry tracing
  tracing:
    otlpEndpoint: "http://otel-collector:4317"
    randomSampling: "0.1"  # 10% sampling (CEL expression)

  # Backend connection pool
  backend:
    connectTimeout: 10s
    poolIdleTimeout: 90s
    poolMaxSize: 100

  # Session management
  session:
    key: "<openssl rand -hex 32>"  # AES-256-GCM key for session tokens
Static configuration changes require a process restart. Use local config or XDS for anything that needs to change at runtime.

Static config reference

FieldDescription
config.logging.formatLog format: json or text
config.logging.levelLog level: trace, debug, info, warn, error
config.adminAddrAdmin UI address (ip:port)
config.statsAddrPrometheus metrics address (ip:port)
config.readinessAddrReadiness probe address (ip:port)
config.dns.lookupFamilyIP family preference for DNS lookups
config.tracing.otlpEndpointOTLP endpoint for OpenTelemetry traces
config.tracing.randomSamplingCEL expression evaluating to 0.0–1.0 or bool
config.backend.connectTimeoutUpstream connection timeout
config.backend.poolMaxSizeMax idle connections per host
config.session.keyAES-256-GCM key for encrypted session tokens
config.workerThreadsNumber of async worker threads
config.enableIpv6Enable IPv6 support

Local configuration

The dynamic part of the configuration — binds, listeners, routes, backends, and policies — lives outside the config block. When you run Agentgateway with a config file, it watches the file for changes and hot-reloads the configuration without restarting.

File watch reloads

1

Initial load

At startup, Agentgateway reads the config file and translates it into the Internal Representation (IR). The proxy begins handling traffic.
2

File change detected

When the file is modified (saved), the file watcher detects the change and re-reads the file.
3

Validation and translation

The new configuration is validated and translated into a new IR. If validation fails, the old configuration stays in place and an error is logged.
4

Atomic swap

The new IR atomically replaces the old one. In-flight requests complete against the old configuration. New requests use the new configuration.
You can also point config.localXdsPath to a separate file that contains only the dynamic configuration (binds, listeners, routes, backends). This keeps static and dynamic config cleanly separated.

Configuration hierarchy

The dynamic configuration follows a strict hierarchy: bindslistenersroutesbackends, with policies attachable at the route level.

Binds

A Bind defines a TCP port to listen on.
binds:
- port: 3000        # Required: TCP port number
  listeners: [...]  # One or more listeners on this port

Listeners

A Listener defines how connections on a port are handled. Multiple listeners on the same port are distinguished by hostname.
binds:
- port: 3000
  listeners:
  - name: my-listener
    hostname: api.example.com    # Optional; supports wildcards
    protocol: http               # http (default)
    tls:
      cert: /certs/tls.crt
      key: /certs/tls.key
      minTLSVersion: "1.2"
    routes: [...]
FieldDescription
nameOptional listener name
hostnameHostname to match; supports wildcards like *.example.com
protocolProtocol: http
tls.certPath to TLS certificate
tls.keyPath to TLS private key
tls.minTLSVersionMinimum TLS version (1.2 or 1.3)
tls.maxTLSVersionMaximum TLS version (1.2 or 1.3)
tls.cipherSuitesOptional cipher suite allowlist (order preserved)

Routes

A Route matches incoming requests and applies policies before forwarding to backends.
routes:
- name: my-route
  hostnames:
  - api.example.com
  matches:
  - path:
      pathPrefix: /v1/
    method: GET
    headers:
    - name: x-api-version
      value:
        exact: "2"
  policies:
    cors:
      allowOrigins: ["*"]
    auth:
      jwt:
        issuer: https://auth.example.com
  backends:
  - host: api-service:8080
Match types:
Match typeFieldsDescription
Pathexact, pathPrefix, regexMatch by request path
Headername + exact or regexMatch by header value
MethodmethodMatch by HTTP method
Queryname + exact or regexMatch by query parameter

Backends

A Backend defines an upstream target. The type is inferred from the fields you provide.
backends:
- host: api-service:8080

Policies

Policies are attached at the route level and control authentication, authorization, rate limiting, observability, and traffic shaping.
routes:
- policies:
    # CORS
    cors:
      allowOrigins: ["*"]
      allowHeaders: ["mcp-protocol-version", "content-type", "cache-control"]
      exposeHeaders: ["Mcp-Session-Id"]

    # JWT authentication
    auth:
      jwt:
        issuer: https://auth.example.com
        jwksUri: https://auth.example.com/.well-known/jwks.json

    # CEL-based authorization
    authz:
      rules:
      - expression: 'jwt.sub == "allowed-user"'

    # Rate limiting
    rateLimit:
      requests: 100
      window: 60s
  backends:
  - host: upstream:8080

Real-world examples

# yaml-language-server: $schema=https://agentgateway.dev/schema/config
binds:
- port: 3000
  listeners:
  - routes:
    - policies:
        cors:
          allowOrigins:
          - "*"
          allowHeaders:
          - mcp-protocol-version
          - content-type
          - cache-control
          exposeHeaders:
          - "Mcp-Session-Id"
      backends:
      - mcp:
          targets:
          - name: everything
            stdio:
              cmd: npx
              args: ["@modelcontextprotocol/server-everything"]

Architecture

Understand how static config, local config, and XDS map to the proxy’s Internal Representation

CEL expressions

Write authorization rules and transformation expressions using CEL