> ## Documentation Index
> Fetch the complete documentation index at: https://cosmo-docs.wundergraph.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Router Configuration

> Router Configuration Reference

The router provides three different ways of customization:

1. **Configure the router runtime:** You can specify a for convenience or pass [environment variables](/router/configuration#environment-variables). In both ways, you can configure the global behavior of the router. For a full reference of all available options see below or use your [IDE of choice](/router/configuration#config-validation-and-auto-completion).
2. **Configure how your graph is served:** This file can be provided as config option or is pulled automatically from the cdn. It contains information on how to resolve your federated schema. The engine uses the information to build a highly optimized query planner. For more information see to build the file locally for development or to download the latest production version.
3. **Customize the router programatically through** Go [modules](/router/custom-modules). It is unlikely that we will provide every possible feature as an in-built functionality. For advanced use cases or more control, you can build Go modules and compile the Router in a few commands. If you are uncertain about if your use case should be implemented as a custom module, don't hesitate to open an issue. We might already have a plan for this or can assist you with the implementation.

<Info>
  **Recommendation** Create a config file and use environment variable expansion
  to avoid storing secrets on the file system.
</Info>

<Warning>
  **Experimental options**

  Options starting with the prefix `experiment_` are unstable, and do not fall under any API stability guarantees. They may be updated or removed in future versions without a deprecation notice.
</Warning>

## Config File

For convenience, you can create a `config.yaml` to specify all router options. Start the router in the same directory or pass the path to the file as a `CONFIG_PATH` environment variable.

```yaml config.yaml theme={"system"}
version: "1"

graph:
  token: "${GRAPH_API_TOKEN}"
```

<Note>
  Values specified in the config file have **precedence** over Environment
  variables. This also includes empty values so only specify values that should
  be overwritten. That means, you can see the config file as a single source of
  truth.
</Note>

### Multiple Config Files

The router allows you to have multiple configuration files, enabling you to override and separate configurations into more manageable chunks. When specifying configuration files, you can simply provide a comma-separated list of file names. You can read more about this [here](/router/configuration/config-design).

### Expand Environment Variables

You can expand environment variables in the file like this:

```yaml config.yaml theme={"system"}
version: "1"

log_level: "${LOG_LEVEL}"
```

This will replace the value of the environment variable `LOG_LEVEL` with the value of the key `log_level` in your config file. For numeric values, ensure quotes are omitted.

### Config Validation & Auto-completion

We know configuration is hard, especially for a software component like the router that can be customized entirely to your needs. In order to simplify this, we use [JSON schema](https://json-schema.org/) to validate the router configuration. This comes with huge benefits, all right at your fingertips:

* Auto-completion
* Documentation (Usage, Examples)
* Detect deprecated fields
* Detect typos or invalid values.

Some options require the router to validate them. This requires starting the router. Once your router has started successfully, you can be sure that your configuration is valid.

### IDE Configuration

* **VSCode**: Install the [YAML](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml) extension in your IDE.
* **JetBrains**: Support out of the box but in some circumstances it conflicts with other default mappings. **Go to** `Languages & Frameworks` -> `Schemas and DTDs` -> `JSON Schemas Mappings` configure the mapping yourself.

As the next step, add the following line to the head of your `config.yaml`file. This line informs your IDE, to download the correct JSON schema file to validate the config file.

```yaml config.yaml theme={"system"}
# yaml-language-server: $schema=https://raw.githubusercontent.com/wundergraph/cosmo/main/router/pkg/config/config.schema.json

version: "1"
```

If you want to pin to a specific router version use the following URL:

```yaml config.yaml theme={"system"}
# yaml-language-server: $schema=https://raw.githubusercontent.com/wundergraph/cosmo/router%400.67.0/router/pkg/config/config.schema.json
```

Now, you should get auto-completion <Icon icon="star" />.

## Environment Variables

Many configuration options can be set as environment variables. For a complete list of options, please look at the [Router](/router/configuration#router) config tables.

## Regular Expressions

Many configuration options support regular expressions (Go RE2 syntax). Test patterns at [regex101.com](https://regex101.com/) using the "Golang" flavor.

<Warning>
  **Escape dots in metric names:** OpenTelemetry metrics contain dots that must be escaped in regex patterns:

  * **Incorrect:** `"wg.operation.hash"` (matches any character)
  * **Correct:** `"wg\\.operation\\.hash"` or `'^wg\.operation\.hash$'` (single quotes recommended)
</Warning>

**Common examples:**

```yaml theme={"system"}
# Metric exclusion
exclude_metrics:
  - '^wg\.operation\.hash$'       # Exact match
  - '^router\.http\.request\..*'  # Prefix match

# Header matching  
headers:
  all:
    request:
      - op: "propagate"
        matching: '(?i)^x-custom-.*'  # Case-insensitive prefix
```

## Router

The following sections describe each configuration in detail with all available options and their defaults.

<Info>
  Intervals, timeouts, and delays are specified in Go [duration](https://pkg.go.dev/maze.io/x/duration#ParseDuration) syntax e.g 1s, 5m or 1h.

  Sizes can be specified in 2MB, 1mib.
</Info>

| Environment Variable                | YAML                                | Required                                      | Description                                                                                                                                                                                        | Default Value                                                        |
| ----------------------------------- | ----------------------------------- | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| LISTEN\_ADDR                        | listen\_addr                        | <Icon icon="square" />                        | The server listener address.                                                                                                                                                                       | localhost:3002                                                       |
| CONTROLPLANE\_URL                   | controlplane\_url                   | <Icon icon="square-check" iconType="solid" /> | The controlplane url. Not required when a static execution config is provided.                                                                                                                     | [https://cosmo-cp.wundergraph.com](https://cosmo-cp.wundergraph.com) |
| PLAYGROUND\_ENABLED                 | playground\_enabled                 | <Icon icon="square" />                        | Enables the GraphQL playground on (`$LISTEN_ADDR/`)                                                                                                                                                | true                                                                 |
| PLAYGROUND\_PATH                    | playground\_path                    | <Icon icon="square" />                        | The path where the playground is served                                                                                                                                                            | "/"                                                                  |
| INTROSPECTION\_ENABLED              | introspection\_enabled              | <Icon icon="square" />                        | **Deprecated**, use ["introspection.enabled"](/router/configuration#introspection) instead. Enables the GraphQL introspection.                                                                     | true                                                                 |
| QUERY\_PLANS\_ENABLED               | query\_plans\_enabled               | <Icon icon="square" />                        | The Router can return Query plans as part of the response, which might be useful to understand the execution.                                                                                      | true                                                                 |
| LOG\_LEVEL                          | log\_level                          | <Icon icon="square" />                        | The log level to use. Allowed levels are `"debug"`, `"info"`, `"warn"`, `"error"`, `"panic"`, `"fatal"`.                                                                                           | info                                                                 |
| JSON\_LOG                           | json\_log                           | <Icon icon="square" />                        | Render the log output in JSON format (true) or human readable (false)                                                                                                                              | true                                                                 |
| LOG\_SERVICE\_NAME                  | log\_service\_name                  | <Icon icon="square" />                        | The service name used in the `service` field of log entries.                                                                                                                                       | @wundergraph/router                                                  |
| SHUTDOWN\_DELAY                     | shutdown\_delay                     | <Icon icon="square" />                        | Maximum time in seconds the server has to shutdown gracefully. Should be higher than `GRACE_PERIOD`                                                                                                | 60s                                                                  |
| GRACE\_PERIOD                       | grace\_period                       | <Icon icon="square" />                        | Maximum time in seconds the server has between schema updates to gracefully clean up all resources. Should be smaller than `SHUTDOWN_DELAY`                                                        | 30s                                                                  |
| POLL\_INTERVAL                      | poll\_interval                      | <Icon icon="square" />                        | The interval of how often the router should check for new schema updates                                                                                                                           | 10s                                                                  |
| POLL\_JITTER                        | poll\_jitter                        | <Icon icon="square" />                        | The maximum delay added to the poll interval to mitigate thundering herd issues in router fleets scenarios.                                                                                        | 5s                                                                   |
| HEALTH\_CHECK\_PATH                 | health\_check\_path                 | <Icon icon="square" />                        | Health check path. Returns `200` when the router is alive                                                                                                                                          | /health                                                              |
| READINESS\_CHECK\_PATH              | readiness\_check\_path              | <Icon icon="square" />                        | Readiness check path. Return `200` when the router is ready to accept traffic, otherwise `503`                                                                                                     | /health/ready                                                        |
| LIVENESS\_CHECK\_PATH               | liveness\_check\_path               | <Icon icon="square" />                        | Liveness check path. Return 200 when the router is alive                                                                                                                                           | /health/live                                                         |
| GRAPHQL\_PATH                       | graphql\_path                       | <Icon icon="square" />                        | The path where the GraphQL Handler is served                                                                                                                                                       | /graphql                                                             |
| PLAYGROUND\_PATH                    | playground\_path                    | <Icon icon="square" />                        | The path where the playground is served                                                                                                                                                            | /                                                                    |
| LOCALHOST\_FALLBACK\_INSIDE\_DOCKER | localhost\_fallback\_inside\_docker | <Icon icon="square" />                        | Enable fallback for requests that fail to connect to localhost while running in Docker                                                                                                             | true                                                                 |
| DEV\_MODE                           | dev\_mode                           | <Icon icon="square" />                        | Enables pretty log output and allows to use [Advanced Request Tracing (ART)](/router/advanced-request-tracing-art) without further security protection.                                            | false                                                                |
| INSTANCE\_ID                        | instance\_id                        | <Icon icon="square" />                        | If not specified, a new ID will be generated with each router start. A stable ID ensures that metrics with the same ID are grouped together and the same server can be identified on the platform. |                                                                      |
| DEMO\_MODE                          | demo\_mode                          | <Icon icon="square" />                        | Launch the router in demo mode. If no execution config is found, the router will start with a demo execution config and deploy a demo federated graph that can be used for testing purposes.       |                                                                      |

### Example configuration:

```yaml config.yaml theme={"system"}
version: "1"

log_level: "info"
listen_addr: "localhost:3002"
controlplane_url: "https://cosmo-cp.wundergraph.com"
playground_enabled: true
playground_path: "/"
introspection:
  enabled: true
json_log: true
shutdown_delay: 15s
grace_period: 20s
poll_interval: 10s
health_check_path: "/health"
readiness_check_path: "/health/ready"
liveness_check_path: "/health/live"
router_config_path: ""
```

## Config watcher hot reloading

The router is capable of reloading itself using an updated config without a full process restart. You can trigger a reload in one of two ways:

* Sending a `SIGHUP` signal to the router process.
* Configuring the `watch_config` section to automatically check the configuration for changes at regular intervals.

```yaml config.yaml theme={"system"}
watch_config:
  enabled: true
  interval: "10s"

  startup_delay:
    enabled: false
    maximum: "10s"
```

### `watch_config` options

| Environment Variable                   | YAML                                 | Required               | Description                                                                                               | Default Value |
| -------------------------------------- | ------------------------------------ | ---------------------- | --------------------------------------------------------------------------------------------------------- | ------------- |
| WATCH\_CONFIG\_ENABLED                 | watch\_config.enabled                | <Icon icon="square" /> | Enable automatic configuration reloading at regular intervals.                                            | false         |
| WATCH\_CONFIG\_INTERVAL                | watch\_config.interval               | <Icon icon="square" /> | The interval at which the router checks for configuration changes.                                        | 10s           |
| WATCH\_CONFIG\_STARTUP\_DELAY\_ENABLED | watch\_config.startup\_delay.enabled | <Icon icon="square" /> | Enable a random delay before the first configuration check to avoid thundering herd problems in clusters. | false         |
| WATCH\_CONFIG\_STARTUP\_DELAY\_MAXIMUM | watch\_config.startup\_delay.maximum | <Icon icon="square" /> | The maximum random delay before the first configuration check.                                            | 10s           |

<Note>
  Hot reloading has some limitations:

  * Changes to the `watch_config` section are not hot-reloaded.
  * Changes to flags and environment variables are not possible.
  * `watch_config` based reloads are based on the filesystem's modification time, edits that somehow circumvent this mechanism will not trigger a reload.
</Note>

## Access Logs

For a detailed example, please refer to the [Access Logs](/router/access-logs) section.

| Environment Variable                              | YAML                                                | Required               | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Default Value  |
| ------------------------------------------------- | --------------------------------------------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- |
|                                                   | access\_logs                                        | <Icon icon="square" /> | Enable the access logs. The access logs are used to log the incoming requests. By default, the access logs are enabled and logged to the standard output.                                                                                                                                                                                                                                                                                                                                                                               |                |
| ACCESS\_LOGS\_ENABLED                             | access\_logs.enabled                                | <Icon icon="square" /> | Enable the access logs. The access logs are used to log the incoming requests. By default, the access logs are enabled and logged to the standard output.                                                                                                                                                                                                                                                                                                                                                                               | true           |
| ACCESS\_LOGS\_LEVEL                               | access\_logs.level                                  | <Icon icon="square" /> | Minimum level required for an access log entry to be emitted. One of: <code>debug</code>, <code>info</code>, <code>warn</code>, <code>error</code>, <code>panic</code>, <code>fatal</code>.                                                                                                                                                                                                                                                                                                                                             | info           |
| ACCESS\_LOGS\_ADD\_STACKTRACE                     | access\_logs.add\_stacktrace                        | <Icon icon="square" /> | When true, include stack traces in access logs for error cases. Panics always include stack traces regardless.                                                                                                                                                                                                                                                                                                                                                                                                                          | false          |
|                                                   | access\_logs.buffer                                 | <Icon icon="square" /> | The buffer is used to buffer the logs before writing them to the output.                                                                                                                                                                                                                                                                                                                                                                                                                                                                |                |
| ACCESS\_LOGS\_BUFFER\_ENABLED                     | access\_logs.buffer.enabled                         | <Icon icon="square" /> | Enable the buffer.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | false          |
| ACCESS\_LOGS\_BUFFER\_SIZE                        | access\_logs.buffer.size                            | <Icon icon="square" /> | The size of the buffer. The default value is 256KB.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |                |
| ACCESS\_LOGS\_FLUSH\_INTERVAL                     | access\_logs.buffer.flush\_interval                 | <Icon icon="square" /> | The interval at which the buffer is flushed. The period is specified as a string with a number and a unit, e.g. 10ms, 1s, 1m, 1h. The supported units are 'ms', 's', 'm', 'h'.                                                                                                                                                                                                                                                                                                                                                          |                |
|                                                   | access\_logs.output                                 | <Icon icon="square" /> | The log destination. The supported destinations are stdout and file. Only one option can be enabled. The default destination is stdout.                                                                                                                                                                                                                                                                                                                                                                                                 |                |
| ACCESS\_LOGS\_OUTPUT\_STDOUT\_ENABLED             | access\_logs.output.stdout.enabled                  | <Icon icon="square" /> |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | true           |
| ACCESS\_LOGS\_OUTPUT\_FILE\_ENABLED               | access\_logs.output.file.enabled                    | <Icon icon="square" /> |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | false          |
| ACCESS\_LOGS\_FILE\_OUTPUT\_PATH                  | access\_logs.output.file.path                       | <Icon icon="square" /> | The path to the log file. The path is used to specify the path to the log file.                                                                                                                                                                                                                                                                                                                                                                                                                                                         |                |
| ACCESS\_LOGS\_FILE\_OUTPUT\_MODE                  | access\_logs.output.file.mode                       | <Icon icon="square" /> | The file mode (permissions) for the log file as an octal string. Must be exactly 3 octal digits (0-7), optionally prefixed with '0' (e.g., '640', '0640', '755', '0755'). The default value is '0640'.                                                                                                                                                                                                                                                                                                                                  |                |
|                                                   | access\_logs.router                                 | <Icon icon="square" /> | The configuration for access logs for the router.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |                |
| ACCESS\_LOGS\_ROUTER\_FIELDS                      | access\_logs.router.fields                          | <Icon icon="square" /> | The fields to add to the access logs for router. The fields are added to the logs as key-value pairs.                                                                                                                                                                                                                                                                                                                                                                                                                                   | \[]            |
|                                                   | access\_logs.router.fields.key                      | <Icon icon="square" /> | The key of the field to add to the logs.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |                |
|                                                   | access\_logs.router.fields.default                  | <Icon icon="square" /> | The default value of the field. If the value is not set, value\_from is used. If both value and value\_from are set, value\_from has precedence and in case of a missing value\_from, the default value is used.                                                                                                                                                                                                                                                                                                                        |                |
|                                                   | access\_logs.router.value\_from                     | <Icon icon="square" /> | Defines a source for the field value e.g. from a request header. If both default and value\_from are set, value\_from has precedence.                                                                                                                                                                                                                                                                                                                                                                                                   |                |
|                                                   | access\_logs.router.value\_from.request\_header     | <Icon icon="square" /> | The name of the request header from which to extract the value. The value is only extracted when a request context is available otherwise the default value is used.                                                                                                                                                                                                                                                                                                                                                                    |                |
|                                                   | access\_logs.router.value\_from.context\_field      | <Icon icon="square" /> | The field name of the context from which to extract the value. The value is only extracted when a context is available otherwise the default value is used. **One of:** \[ "operation\_name", "operation\_type", "operation\_service\_names", "operation\_hash", "persisted\_operation\_sha256", "operation\_sha256", "response\_error\_message", "graphql\_error\_codes", "graphql\_error\_service\_names", "operation\_parsing\_time", "operation\_validation\_time", "operation\_planning\_time", "operation\_normalization\_time" ] |                |
| ACCESS\_LOGS\_ROUTER\_IGNORE\_QUERY\_PARAMS\_LIST | access\_logs.router.ignore\_query\_params\_list     | <Icon icon="square" /> | A list of query parameter names to ignore/exclude from the query field in access logs. This is useful for filtering out sensitive information from query parameters, especially when GraphQL requests are made over GET.                                                                                                                                                                                                                                                                                                                | \["variables"] |
|                                                   | access\_logs.subgraphs                              | <Icon icon="square" /> | The subgraph access logs configuration                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |                |
| ACCESS\_LOGS\_SUBGRAPH\_ENABLED                   | access\_logs.subgraphs.enabled                      | <Icon icon="square" /> | Enable the subgraphs access logs.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | false          |
| ACCESS\_LOGS\_SUBGRAPH\_FIELDS                    | access\_logs.subgraphs.fields                       | <Icon icon="square" /> | The fields to add to the logs when printing subgraph access logs. The fields are added to the logs as key-value pairs.                                                                                                                                                                                                                                                                                                                                                                                                                  |                |
|                                                   | access\_logs.subgraphs.fields.key                   | <Icon icon="square" /> | The key of the field to add to the logs.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |                |
|                                                   | access\_logs.subgraphs.fields.default               | <Icon icon="square" /> | The default value of the field. If the value is not set, value\_from is used. If both value and value\_from are set, value\_from has precedence and in case of a missing value\_from, the default value is used.                                                                                                                                                                                                                                                                                                                        |                |
|                                                   | access\_logs.subgraphs.value\_from                  | <Icon icon="square" /> | Defines a source for the field value e.g. from a request header. If both default and value\_from are set, value\_from has precedence.                                                                                                                                                                                                                                                                                                                                                                                                   |                |
|                                                   | access\_logs.subgraphs.value\_from.request\_header  | <Icon icon="square" /> | The name of the request header from which to extract the value. The value is only extracted when a request context is available otherwise the default value is used.                                                                                                                                                                                                                                                                                                                                                                    |                |
|                                                   | access\_logs.subgraphs.value\_from.response\_header | <Icon icon="square" /> | The name of the response header from which to extract the value. The value is only extracted when a request context is available otherwise the default value is used.                                                                                                                                                                                                                                                                                                                                                                   |                |
|                                                   | access\_logs.subgraphs.value\_from.context\_field   | <Icon icon="square" /> | The field name of the context from which to extract the value. The value is only extracted when a context is available otherwise the default value is used. **One of:** \[ "operation\_name", "operation\_type", "operation\_hash", "persisted\_operation\_sha256", "operation\_sha256", "operation\_parsing\_time", "operation\_validation\_time", "operation\_planning\_time", "operation\_normalization\_time" ]                                                                                                                     |                |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

access_logs:
  enabled: true
  level: info
  add_stacktrace: true
  buffer:
    enabled: false
    size: 256KB
    flush_interval: 10s
  output:
    file:
      enabled: true
      path: "access.log"
      mode: "0640"
  router:
    ignore_query_params_list:
      - "extensions"
    fields:
      - key: "service"
        value_from:
          request_header: "x-service"
      - key: "operationName"
        value_from:
          context_field: operation_name
  subgraphs:
    fields:
      - key: "service"
        value_from:
          request_header: "x-service"
      - key: "response-service"
        value_from:
          response_header: "x-response-service"
      - key: "operationName"
        value_from:
          context_field: operation_name
```

## Telemetry

## Graph

Overall configuration for the Graph that's configured for this Router.

| Environment Variable | YAML  | Required                                      | Description                                                                                                                                                                                                                                 | Default Value |
| -------------------- | ----- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| GRAPH\_API\_TOKEN    | token | <Icon icon="square-check" iconType="solid" /> | The token permits the router to communicate with the controlplane and export telemetry. Created with . (Can be empty when providing a static router configuration through `ROUTER_CONFIG_PATH`but will disable the default telemetry stack) |               |

Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

graph:
  token: "<your-graph-token>"
```

## Introspection

Overall configuration for managing introspection queries on this Router.

| Environment Variable   | YAML    | Required               | Description                                                                                                                               | Default Value |
| ---------------------- | ------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| INTROSPECTION\_ENABLED | enabled | <Icon icon="square" /> | Enable or disable introspection queries                                                                                                   | true          |
| INTROSPECTION\_SECRET  | secret  | <Icon icon="square" /> | Optional, dedicated secret used for instrospection authentication. Only used when `authentication.ignore_introspection` is set to `true`. |               |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

introspection:
  enabled: true
  secret: "dedicated_secret_for_introspection"
```

## MCP (Model Context Protocol)

The Model Context Protocol (MCP) server allows AI models to discover and interact with your GraphQL API in a secure way.

| Environment Variable               | YAML                              | Required               | Description                                                                                                                                                                   | Default Value  |
| ---------------------------------- | --------------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- |
| MCP\_ENABLED                       | mcp.enabled                       | <Icon icon="square" /> | Enable or disable the MCP server                                                                                                                                              | false          |
| MCP\_SERVER\_LISTEN\_ADDR          | mcp.server.listen\_addr           | <Icon icon="square" /> | The address and port where the MCP server will listen for requests                                                                                                            | localhost:5025 |
| MCP\_ROUTER\_URL                   | mcp.router\_url                   | <Icon icon="square" /> | Custom URL to use for the router GraphQL endpoint in MCP. Use this when your router is behind a proxy; used in MCP responses to provide the real router URL.                  | -              |
| MCP\_STORAGE\_PROVIDER\_ID         | mcp.storage.provider\_id          | <Icon icon="square" /> | The ID of a storage provider to use for loading GraphQL operations. Only file\_system providers are supported.                                                                | -              |
| MCP\_SESSION\_STATELESS            | mcp.session.stateless             | <Icon icon="square" /> | Whether the MCP server should operate in stateless mode. When true, no server-side session state is maintained between requests.                                              | true           |
| MCP\_GRAPH\_NAME                   | mcp.graph\_name                   | <Icon icon="square" /> | The name of the graph this router exposes via MCP. Used to build the MCP server name (wundergraph-cosmo-\$graph\_name) and for logging; it does not select a different graph. | mygraph        |
| MCP\_EXCLUDE\_MUTATIONS            | mcp.exclude\_mutations            | <Icon icon="square" /> | Whether to exclude mutation operations from being exposed                                                                                                                     | false          |
| MCP\_ENABLE\_ARBITRARY\_OPERATIONS | mcp.enable\_arbitrary\_operations | <Icon icon="square" /> | Whether to allow arbitrary GraphQL operations to be executed. <Warning>   Security risk: Should only be enabled in secure, internal environments. </Warning>                  | false          |
| MCP\_EXPOSE\_SCHEMA                | mcp.expose\_schema                | <Icon icon="square" /> | Whether to expose the full GraphQL schema. <Warning>   Security risk: Should only be enabled in secure, internal environments. </Warning>                                     | false          |
| MCP\_OMIT\_TOOL\_NAME\_PREFIX      | mcp.omit\_tool\_name\_prefix      | <Icon icon="square" /> | When enabled, MCP tool names generated from GraphQL operations omit the `execute_operation_` prefix.                                                                          | false          |

Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

mcp:
  enabled: true
  server:
    listen_addr: "localhost:5025"
  router_url: "https://your-public-router-url.example.com/graphql" # Optional: Used in MCP responses when your router is behind a proxy.
  storage:
    provider_id: "mcp" # References a file_system provider defined below
  session:
    stateless: true # Optional: When true, no server-side session state is kept
  graph_name: "my-graph"
  exclude_mutations: true
  enable_arbitrary_operations: false
  expose_schema: false

# Configure storage providers
storage_providers:
  file_system:
    - id: "mcp"
      path: "operations" # Relative to the router binary
```

For more details on how to use the MCP server, see the [MCP Integration documentation](/router/mcp).

## TLS

The Router supports TLS and mTLS for secure communication with your clients and infrastructure components like load balancer.

### Server TLS

| Environment Variable    | YAML       | Required               | Description                              | Default Value |
| ----------------------- | ---------- | ---------------------- | ---------------------------------------- | ------------- |
| TLS\_SERVER\_ENABLED    | enabled    | <Icon icon="square" /> | Enables server TLS support.              | false         |
| TLS\_SERVER\_CERT\_FILE | cert\_file | <Icon icon="square" /> | The path to the server certificate file. |               |
| TLS\_SERVER\_KEY\_FILE  | key\_file  | <Icon icon="square" /> | The path to the server private key file. |               |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

tls:
  server:
    enabled: true
    key_file: ../your/key.pem
    cert_file: ../your/cert.pem
```

### Client Authentication

| Environment Variable          | YAML       | Required               | Description                                                                                            | Default Value |
| ----------------------------- | ---------- | ---------------------- | ------------------------------------------------------------------------------------------------------ | ------------- |
| TLS\_CLIENT\_AUTH\_CERT\_FILE | cert\_file | <Icon icon="square" /> | Enables client authentication support. The file to the certificate file used to authenthicate clients. | " "           |
| TLS\_CLIENT\_AUTH\_REQUIRED   | required   | <Icon icon="square" /> | Enforces a valid client certificate to establish a connection.                                         | false         |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

tls:
  server:
    enabled: true # Required for client_auth
    key_file: ../your/key.pem
    cert_file: ../your/cert.pem
    client_auth:
      required: true
      cert_file: ../your/cert.pem
```

### Outbound TLS to Subgraphs

Configure TLS for outbound connections from router to subgraphs.
See [TLS](/router/security/tls) for details.

#### HTTP Subgraphs

Configuring a subgraph URL with a `https://` scheme activates TLS to subgraphs.
Specifying `ca_file` additionally verifies a subgraphs certificate against that CA certificate.\
Additionally specifying `cert_file` and `key_file` enables mTLS on subgraph connections.

The following settings configure TLS for HTTP based subgraphs.

| Environment Variable                               | YAML                                            | Required               | Description                                                                                         | Default Value |
| -------------------------------------------------- | ----------------------------------------------- | ---------------------- | --------------------------------------------------------------------------------------------------- | ------------- |
| TLS\_CLIENT\_ALL\_CA\_FILE                         | tls.client.all.ca\_file                         | <Icon icon="square" /> | Path to a custom CA certificate file for verifying subgraph server certificates.                    |               |
| TLS\_CLIENT\_ALL\_CERT\_FILE                       | tls.client.all.cert\_file                       | <Icon icon="square" /> | Path to the client certificate chain file for authenticating the router to subgraphs. Enables mTLS. |               |
| TLS\_CLIENT\_ALL\_KEY\_FILE                        | tls.client.all.key\_file                        | <Icon icon="square" /> | Path to the client private key file. Enables mTLS.                                                  |               |
| TLS\_CLIENT\_ALL\_INSECURE\_SKIP\_CA\_VERIFICATION | tls.client.all.insecure\_skip\_ca\_verification | <Icon icon="square" /> | Skip verification of the subgraph server certificate. Only use for development or testing.          | false         |

##### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

tls:
  client:
    all: # global tls configuration affecting all HTTP subgraphs
      cert_file: /path/to/client.crt
      key_file: /path/to/client.key
      ca_file: /path/to/ca.crt
    subgraphs: # additional overwrites for specific HTTP subgraphs
      products:
        cert_file: /path/to/products-client.crt
        key_file: /path/to/products-client.key
```

#### gRPC Subgraphs

The configuration settings above are not applied to gRPC subgraphs.
For gRPC subgraphs, TLS must be explicitly enabled with `enabled: true`.

| Environment Variable                                     | YAML                                                  | Required                     | Description                                                                                              | Default Value |
| -------------------------------------------------------- | ----------------------------------------------------- | ---------------------------- | -------------------------------------------------------------------------------------------------------- | ------------- |
| TLS\_CLIENT\_GRPC\_ALL\_ENABLED                          | tls.client\_grpc.all.enabled                          | <Icon icon="check-square" /> | Enable TLS for all gRPC subgraph connections.                                                            |               |
| TLS\_CLIENT\_GRPC\_ALL\_CA\_FILE                         | tls.client\_grpc.all.ca\_file                         | <Icon icon="square" />       | Path to a custom CA certificate file for verifying gRPC subgraph server certificates.                    |               |
| TLS\_CLIENT\_GRPC\_ALL\_CERT\_FILE                       | tls.client\_grpc.all.cert\_file                       | <Icon icon="square" />       | Path to the client certificate chain file for authenticating the router to gRPC subgraphs. Enables mTLS. |               |
| TLS\_CLIENT\_GRPC\_ALL\_KEY\_FILE                        | tls.client\_grpc.all.key\_file                        | <Icon icon="square" />       | Path to the client private key file. Enables mTLS.                                                       |               |
| TLS\_CLIENT\_GRPC\_ALL\_INSECURE\_SKIP\_CA\_VERIFICATION | tls.client\_grpc.all.insecure\_skip\_ca\_verification | <Icon icon="square" />       | Skip verification of the gRPC subgraph server certificate. Only use for development or testing.          | false         |

##### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

tls:
  client_grpc:
    all: # global TLS configuration for all gRPC subgraphs
      enabled: true
      cert_file: /path/to/client.crt
      key_file: /path/to/client.key
      ca_file: /path/to/ca.crt
    subgraphs: # per-subgraph overrides
      products:
        enabled: true
        cert_file: /path/to/products-client.crt
        key_file: /path/to/products-client.key
      projects:
        enabled: false # specifically disable TLS for this subgraph
```

## Compliance

The configuration for the compliance. Includes for example the configuration for the anonymization of the IP addresses.

### IP Anonymization

| Environment Variable             | YAML    | Required               | Description                                                     | Default Value |
| -------------------------------- | ------- | ---------------------- | --------------------------------------------------------------- | ------------- |
| SECURITY\_ANONYMIZE\_IP\_ENABLED | enabled | <Icon icon="square" /> | Enables IP anonymization in traces and logs.                    | true          |
| SECURITY\_ANONYMIZE\_IP\_METHOD  | method  | <Icon icon="square" /> | The metod to anonymize IP addresses. Can be "hash" or "redact". | "redact"      |

### Example YAML config:

```bash config.yaml theme={"system"}
version: "1"

compliance:
  anonymize_ip:
    enabled: true
    method: redact # hash or redact
```

## Cluster

| Environment Variable | YAML | Required               | Description                                                                    | Default Value |
| -------------------- | ---- | ---------------------- | ------------------------------------------------------------------------------ | ------------- |
| CLUSTER\_NAME        | name | <Icon icon="square" /> | The logical name of the router cluster. The name is used for analytic purpose. |               |

### Example YAML config:

```bash config.yaml theme={"system"}
version: "1"

# See "https://cosmo-docs.wundergraph.com/studio/cluster-management" for more information
cluster:
  name: "us-central1-cosmo-cloud "
```

## Telemetry

| Environment Variable     | YAML                                   | Required                                      | Description                                                                                                                                                                                                                | Default Value |
| ------------------------ | -------------------------------------- | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| TELEMETRY\_SERVICE\_NAME | service\_name                          | <Icon icon="square-check" iconType="solid" /> | The name of the service.                                                                                                                                                                                                   | cosmo-router  |
|                          | resource\_attributes                   | <Icon icon="square" />                        | The resource attributes to add to OTEL metrics and traces. The resource attributes identify the entity producing the traces and metrics.                                                                                   |               |
|                          | resource\_attributes.key               | <Icon icon="square-check" iconType="solid" /> | The key of the attribute.                                                                                                                                                                                                  |               |
|                          | resource\_attributes.value             | <Icon icon="square-check" iconType="solid" /> | The value of the attribute.                                                                                                                                                                                                |               |
|                          | attributes                             | <Icon icon="square" />                        | The attributes to add to OTEL metrics and traces. Because Prometheus metrics rely on the OpenTelemetry metrics, the attributes are also added to the Prometheus metrics.                                                   | \[]           |
|                          | attributes.key                         | <Icon icon="square" />                        | The key of the attribute.                                                                                                                                                                                                  |               |
|                          | attributes.default                     | <Icon icon="square" />                        | The value of the attribute.                                                                                                                                                                                                |               |
|                          | attributes.value\_from                 | <Icon icon="square" />                        | Defines a source for the attribute value e.g. from a request header. If both default and value\_from are set, value\_from has precedence.                                                                                  |               |
|                          | attributes.value\_from.request\_header | <Icon icon="square" />                        | The name of the request header from which to extract the value. The value is only extracted when a request context is available otherwise the default value is used. Don't forget to add the header to your CORS settings. |               |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

# Only needed when setting attributes based on a request header
cors:
  allow_headers:
    - "x-service"

# See "https://cosmo-docs.wundergraph.com/router/metrics-and-monitoring" for more information
telemetry:
  # Common options
  service_name: "cosmo-router"
  resource_attributes:
    - key: env
      value: "prod"
  attributes:
    - key: service
      default: "static"
      value_from:
        request_header: "x-service"
```

## Tracing

| Environment Variable                        | YAML                              | Required                                      | Description                                                                                                                                                                                                                                                                          | Default Value |
| ------------------------------------------- | --------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- |
| TRACING\_ENABLED                            | enabled                           | <Icon icon="square" />                        |                                                                                                                                                                                                                                                                                      | true          |
| TRACING\_SAMPLING\_RATE                     | sampling\_rate                    | <Icon icon="square-check" iconType="solid" /> | The sampling rate for the traces. The value must be between 0 and 1. If the value is 0, no traces will be sampled. If the value is 1, all traces will be sampled. For managed plans, the trace sampling rate will not exceed the rate imposed by the organization limit of the plan. | 1             |
| TRACING\_PARENT\_BASED\_SAMPLER             | parent\_based\_sampler            | <Icon icon="square-check" iconType="solid" /> | Enable the parent-based sampler. The parent-based sampler is used to sample the traces based on the parent trace.                                                                                                                                                                    | true          |
| TRACING\_BATCH\_TIMEOUT                     | batch\_timeout                    | <Icon icon="square" />                        | The maximum delay allowed before spans are exported.                                                                                                                                                                                                                                 | 10s           |
| TRACING\_EXPORT\_GRAPHQL\_VARIABLES         | export\_graphql\_variables        | <Icon icon="square" />                        | Export GraphQL variables as span attribute. Variables may contain sensitive data.                                                                                                                                                                                                    | false         |
| TRACING\_OPERATION\_CONTENT\_ATTRIBUTES     | operation\_content\_attributes    | <Icon icon="square" />                        | Enable the addition of GraphQL operation body content as trace attributes. When enabled, original operation content will be added to the trace span for parse and normalized operation content will be added to the trace span for normalize. The default value is false.            | false         |
|                                             | with\_new\_root                   | <Icon icon="square" />                        | Starts the root span always at the router.                                                                                                                                                                                                                                           | false         |
| TRACING\_SANITIZE\_UTF8\_ENABLED            | sanitize\_utf8.enabled            | <Icon icon="square" />                        | Enable sanitization of invalid UTF-8 sequences in span attribute values. Invalid bytes are replaced with the Unicode replacement character (U+FFFD). See [Sanitize UTF-8](/router/open-telemetry#sanitize-utf-8).                                                                    | false         |
| TRACING\_SANITIZE\_UTF8\_LOG\_SANITIZATIONS | sanitize\_utf8.log\_sanitizations | <Icon icon="square" />                        | When enabled, logs a warning for each span attribute that contains invalid UTF-8 and is sanitized.                                                                                                                                                                                   | false         |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

# See "https://cosmo-docs.wundergraph.com/router/metrics-and-monitoring" for more information
telemetry:
  # Common options
  service_name: "cosmo-router"
  # uses https://cosmo-otel.wundergraph.com for tracing and metrics

  # OpenTelemetry Tracing
  tracing:
    enabled: true
    sampling_rate: 1
    batch_timeout: "10s"
    export_graphql_variables: false
    operation_content_attributes: false
    with_new_root: false
    sanitize_utf8:
      enabled: false
      log_sanitizations: false
```

### Exporters

| Environment Variable | YAML     | Required               | Description       | Default Value |
| -------------------- | -------- | ---------------------- | ----------------- | ------------- |
|                      | diabled  | <Icon icon="square" /> | bool              |               |
|                      | exporter | <Icon icon="square" /> | one of: http,grpc |               |
|                      | endpoint | <Icon icon="square" /> |                   |               |
|                      | path     | <Icon icon="square" /> |                   |               |
|                      | headers  | <Icon icon="square" /> |                   |               |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

# See "https://cosmo-docs.wundergraph.com/router/metrics-and-monitoring" for more information
telemetry:
  tracing:
    enabled: true
    exporters:
      # If no exporters are defined, the default one is used
      - exporter: http # or grpc
        disabled: false
        endpoint: https://my-otel-collector.example.com
        # headers: {Authorization: Bearer <my-token>}
        batch_timeout: 10s
        export_timeout: 30s
```

### Propagation

| Environment Variable | YAML           | Required               | Description                      | Default Value |
| -------------------- | -------------- | ---------------------- | -------------------------------- | ------------- |
|                      | trace\_context | <Icon icon="square" /> |                                  | true          |
|                      | jaeger         | <Icon icon="square" /> |                                  |               |
|                      | b3             | <Icon icon="square" /> |                                  |               |
|                      | baggage        | <Icon icon="square" /> |                                  |               |
|                      | datadog        | <Icon icon="square" /> | Enable Datadog trace propagation | false         |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

# See "https://cosmo-docs.wundergraph.com/router/metrics-and-monitoring" for more information
telemetry:
  # OpenTelemetry Tracing
  tracing:
    propagation:
      # https://www.w3.org/TR/trace-context/
      trace_context: true
      # https://www.w3.org/TR/baggage/
      baggage: false
      # https://www.jaegertracing.io/ (compliant with opentracing)
      jaeger: false
      # https://github.com/openzipkin/b3-propagation (zipkin)
      b3: false
      # https://docs.datadoghq.com/tracing/trace_collection/trace_context_propagation/?tab=java#datadog-format
      datadog: false
```

### Attributes

| YAML                              | Required               | Description                             | Default Value |
| --------------------------------- | ---------------------- | --------------------------------------- | ------------- |
| attributes                        | <Icon icon="square" /> | The attributes to add for Tracing.      | \[]           |
| attributes.key                    | <Icon icon="square" /> | The key of the field.                   |               |
| attributes.value\_from            | <Icon icon="square" /> | Defines a source for the field value.   |               |
| attributes.value\_from.expression | <Icon icon="square" /> | The expression for the trace attribute. |               |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

# See "https://cosmo-docs.wundergraph.com/router/metrics-and-monitoring" for more information
telemetry:
  # OpenTelemetry Tracing
  tracing:
    attributes:
      - key: "x-new-attribute"
        value_from:
          expression: "request.url.method"
```

## Metrics

| Environment Variable                    | YAML                           | Required               | Description                                                                                       | Default Value |
| --------------------------------------- | ------------------------------ | ---------------------- | ------------------------------------------------------------------------------------------------- | ------------- |
| METRICS\_EXPERIMENT\_CARDINALITY\_LIMIT | experiment\_cardinality\_limit | <Icon icon="square" /> | Sets a hard limit on the number of Metric Points that can be collected during a collection cycle. | 2000          |

<Warning>
  The `experiment_cardinality_limit` option is experimental because it relies on experimental functionality in the OpenTelemetry SDK for Go. This feature helps prevent excessive memory usage by limiting the number of unique metric combinations (cardinality) that can be collected in a single collection cycle.

  See the specification for more information: [https://opentelemetry.io/docs/specs/otel/metrics/sdk/#cardinality-limits](https://opentelemetry.io/docs/specs/otel/metrics/sdk/#cardinality-limits)

  This option may change or be removed in future versions as the OpenTelemetry SDK stabilizes this functionality.
</Warning>

### OTLP

| Environment Variable                   | YAML                    | Required                                      | Description                                                                                                                                                                        | Default Value |
| -------------------------------------- | ----------------------- | --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| METRICS\_OTLP\_ENABLED                 | enabled                 | <Icon icon="square-check" iconType="solid" /> | Enables OTEL metrics instrumentation                                                                                                                                               | true          |
| METRICS\_OTLP\_ROUTER\_RUNTIME         | router\_runtime         | <Icon icon="square" />                        | Enable the collection of metrics for the router runtime.                                                                                                                           | true          |
| METRICS\_OTLP\_GRAPHQL\_CACHE          | graphql\_cache          | <Icon icon="square" />                        | Enable the collection of metrics for the GraphQL operation router caches.                                                                                                          | false         |
| METRICS\_OTLP\_EXCLUDE\_METRICS        | exclude\_metrics        | <Icon icon="square" />                        | The metrics to exclude from the OTEL metrics. Accepts a list of Go regular expressions. Use [https://regex101.com/](https://regex101.com/) to test your regular expressions.       | \[]           |
| METRICS\_OTLP\_EXCLUDE\_METRIC\_LABELS | exclude\_metric\_labels | <Icon icon="square" />                        | The metric labels to exclude from the OTEL metrics. Accepts a list of Go regular expressions. Use [https://regex101.com/](https://regex101.com/) to test your regular expressions. | \[]           |
| METRICS\_OTLP\_CONNECTION\_STATS       | connection\_stats       | <Icon icon="square" />                        | Enable connection metrics.                                                                                                                                                         | false         |
| METRICS\_OTLP\_NETWORK\_ENABLED        | network.enabled         | <Icon icon="square" />                        | Enable per-request subgraph HTTP phase metrics: DNS lookup, TCP connect, TLS handshake, and time-to-first-byte histograms.                                                         | false         |
| METRICS\_OTLP\_RESOLVER\_ENABLED       | resolver.enabled        | <Icon icon="square" />                        | Enable resolver metrics: resolver concurrency gauges and the resolver acquire duration histogram.                                                                                  | false         |
| METRICS\_OTLP\_CIRCUIT\_BREAKER        | circuit\_breaker        | <Icon icon="square" />                        | Ensure that circuit breaker metrics are enabled for OTEL.                                                                                                                          | false         |
| METRICS\_OTLP\_STREAM                  | streams                 | <Icon icon="square" />                        | Enable Cosmo Streams metrics.                                                                                                                                                      | false         |
| METRICS\_OTLP\_EXEMPLAR\_FILTER        | exemplar\_filter        | <Icon icon="square" />                        | Controls which measurements are eligible to record exemplars. One of: `always_off`, `trace_based`, `always_on`. See [Exemplars](/router/metrics-and-monitoring/exemplars).         | always\_off   |

### Metrics Log Exporter

Configured under `telemetry.metrics.otlp.log_exporter`. See [Metrics Log Exporter](/router/open-telemetry#metrics-log-exporter) for details.

| Environment Variable                           | YAML             | Required               | Description                                                                                                                        | Default Value |
| ---------------------------------------------- | ---------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| METRICS\_OTLP\_LOG\_EXPORTER\_ENABLED          | enabled          | <Icon icon="square" /> | Enable the metrics log exporter.                                                                                                   | false         |
| METRICS\_OTLP\_LOG\_EXPORTER\_EXCLUDE\_METRICS | exclude\_metrics | <Icon icon="square" /> | List of Go regex patterns. Metrics matching any pattern will not be logged. Cannot be used together with `include_metrics`.        | \[]           |
| METRICS\_OTLP\_LOG\_EXPORTER\_INCLUDE\_METRICS | include\_metrics | <Icon icon="square" /> | List of Go regex patterns. When set, only metrics matching at least one pattern are logged. Cannot be used with `exclude_metrics`. | \[]           |

### Attributes

| YAML                                   | Required               | Description                                                                                                                                                                                                      | Default Value                                                                                                         |
| -------------------------------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| attributes                             | <Icon icon="square" /> | The attributes to add to OTLP Metrics and Prometheus.                                                                                                                                                            | \[]                                                                                                                   |
| attributes.key                         | <Icon icon="square" /> | The key of the field.                                                                                                                                                                                            |                                                                                                                       |
| attributes.default                     | <Icon icon="square" /> | The default value of the field. If the value is not set, value\_from is used. If both value and value\_from are set, value\_from has precedence and in case of a missing value\_from, the default value is used. |                                                                                                                       |
| attributes.value\_from                 | <Icon icon="square" /> | Defines a source for the field value e.g. from a request header or request context. If both default and value\_from are set, value\_from has precedence.                                                         |                                                                                                                       |
| attributes.value\_from.request\_header | <Icon icon="square" /> | The name of the request header from which to extract the value. The value is only extracted when a request context is available otherwise the default value is used.                                             |                                                                                                                       |
| attributes.value\_from.context\_field  | <Icon icon="square" /> | The field name of the context from which to extract the value. The value is only extracted when a context is available otherwise the default value is used.                                                      | One of:\["operation\_service\_names", "graphql\_error\_codes", "graphql\_error\_service\_names", "operation\_sha256"] |

### Example YAML config:

```yaml config.yaml theme={"system"}
# See "https://cosmo-docs.wundergraph.com/router/metrics-and-monitoring" for more information
telemetry:
  metrics:
    experiment_cardinality_limit: 2000
    otlp:
      enabled: true
      router_runtime: true
      graphql_cache: true
      connection_stats: false
      # Per-request subgraph HTTP phase metrics (DNS, TCP connect, TLS handshake, time to first byte)
      network:
        enabled: false
      # Resolver concurrency gauges and resolver acquire duration histogram
      resolver:
        enabled: false
      exclude_metrics: []
      exclude_metric_labels: []
      streams: true
      # Record exemplars only for measurements taken within a sampled trace.
      # One of: always_off (default), trace_based, always_on
      exemplar_filter: always_off
      log_exporter:
        enabled: false
        # note that both exclude_metrics and include_metrics cannot be used together
        exclude_metrics: []
        include_metrics: []
    attributes:
      - key: "x-new-attribute"
        default: "foo"
        value_from:
          request_header: "X-Request-ID"

      - key: "error_codes"
        value_from:
          context_field: graphql_error_codes
```

### Prometheus

| Environment Variable                | YAML                    | Required                                      | Description                                                                                                                                                                | Default Value    |
| ----------------------------------- | ----------------------- | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
| PROMETHEUS\_ENABLED                 | enabled                 | <Icon icon="square-check" iconType="solid" /> | Enables prometheus metrics support                                                                                                                                         | true             |
| PROMETHEUS\_HTTP\_PATH              | path                    | <Icon icon="square" />                        | The HTTP path where metrics are exposed.                                                                                                                                   | "/metrics"       |
| PROMETHEUS\_LISTEN\_ADDR            | listen\_addr            | <Icon icon="square" />                        | The address to listen on for the prometheus metrics endpoint.                                                                                                              | "127.0.0.1:8088" |
| PROMETHEUS\_GRAPHQL\_CACHE          | graphql\_cache          | <Icon icon="square" />                        | Enable the collection of metrics for the GraphQL operation router caches.                                                                                                  | false            |
| PROMETHEUS\_CONNECTION\_STATS       | connection\_stats       | <Icon icon="square" />                        | Enable connection metrics.                                                                                                                                                 | false            |
| PROMETHEUS\_NETWORK\_ENABLED        | network.enabled         | <Icon icon="square" />                        | Enable per-request subgraph HTTP phase metrics: DNS lookup, TCP connect, TLS handshake, and time-to-first-byte histograms.                                                 | false            |
| PROMETHEUS\_RESOLVER\_ENABLED       | resolver.enabled        | <Icon icon="square" />                        | Enable resolver metrics: resolver concurrency gauges and the resolver acquire duration histogram.                                                                          | false            |
| PROMETHEUS\_EXCLUDE\_METRICS        | exclude\_metrics        | <Icon icon="square" />                        |                                                                                                                                                                            |                  |
| PROMETHEUS\_EXCLUDE\_METRIC\_LABELS | exclude\_metric\_labels | <Icon icon="square" />                        |                                                                                                                                                                            |                  |
| PROMETHEUS\_EXCLUDE\_SCOPE\_INFO    | exclude\_scope\_info    | <Icon icon="square" />                        | Exclude scope info from Prometheus metrics.                                                                                                                                | false            |
| PROMETHEUS\_CIRCUIT\_BREAKER        | circuit\_breaker        | <Icon icon="square" />                        | Enable the circuit breaker metrics for prometheus metric collection.                                                                                                       | false            |
| PROMETHEUS\_OTLP\_STREAM            | streams                 | <Icon icon="square" />                        | Enable Cosmo Streams metrics.                                                                                                                                              | false            |
| PROMETHEUS\_EXEMPLAR\_FILTER        | exemplar\_filter        | <Icon icon="square" />                        | Controls which measurements are eligible to record exemplars. One of: `always_off`, `trace_based`, `always_on`. See [Exemplars](/router/metrics-and-monitoring/exemplars). | always\_off      |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

# See "https://cosmo-docs.wundergraph.com/router/metrics-and-monitoring" for more information
telemetry:
  metrics:
    # Expose OpenTelemetry metrics for scraping
    prometheus:
      enabled: true
      path: "/metrics"
      listen_addr: "127.0.0.1:8088"
      graphql_cache: true
      connection_stats: false
      # Per-request subgraph HTTP phase metrics (DNS, TCP connect, TLS handshake, time to first byte)
      network:
        enabled: false
      # Resolver concurrency gauges and resolver acquire duration histogram
      resolver:
        enabled: false
      exclude_metrics: []
      exclude_metric_labels: []
      streams: true
      exclude_scope_info: false
      # Record exemplars only for measurements taken within a sampled trace.
      # One of: always_off (default), trace_based, always_on
      exemplar_filter: always_off
```

### Exporter

| YAML        | Required               | Description                                                                                                   | Default Value |
| ----------- | ---------------------- | ------------------------------------------------------------------------------------------------------------- | ------------- |
| disabled    | <Icon icon="square" /> |                                                                                                               |               |
| exporter    | <Icon icon="square" /> | one of: http,grpc                                                                                             |               |
| endpoint    | <Icon icon="square" /> |                                                                                                               |               |
| path        | <Icon icon="square" /> | The path to which the metrics are exported. This is ignored when using 'grpc' as exporter and can be omitted. |               |
| headers     | <Icon icon="square" /> |                                                                                                               |               |
| temporality | <Icon icon="square" /> | Temporality defines the window that an aggregation is calculated over. one of: delta, cumulative              |               |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

# See "https://cosmo-docs.wundergraph.com/router/metrics-and-monitoring" for more information
telemetry:
  # Common options
  service_name: "cosmo-router"
  # uses https://cosmo-otel.wundergraph.com for tracing and metrics

  # OpenTelemetry Metrics
  metrics:
    otlp:
      enabled: true
      # If no exporters are defined, the default one is used
      exporters:
        - exporter: http # or grpc
          disabled: false
          endpoint: https://my-otel-collector.example.com
          temporality: delta # or cumulative
          # headers: {Authorization: Bearer <my-token>}
      log_exporter:
        enabled: false
        # note that both exclude_metrics and include_metrics cannot be used together
        exclude_metrics: []
        include_metrics: []

    # Expose OpenTelemetry metrics for scraping
    prometheus:
      enabled: true
      path: "/metrics"
      listen_addr: "127.0.0.1:8088"
      exclude_metrics: []
      exclude_metric_labels: []
```

## GraphQL Metrics

| Environment Variable                  | YAML                | Required                                      | Description      | Default Value                                                                  |
| ------------------------------------- | ------------------- | --------------------------------------------- | ---------------- | ------------------------------------------------------------------------------ |
| GRAPHQL\_METRICS\_ENABLED             | enabled             | <Icon icon="square" />                        |                  | true                                                                           |
| GRAPHQL\_METRICS\_COLLECTOR\_ENDPOINT | collector\_endpoint | <Icon icon="square-check" iconType="solid" /> | Default endpoint | [https://cosmo-metrics.wundergraph.com](https://cosmo-metrics.wundergraph.com) |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

graphql_metrics:
  enabled: true
  collector_endpoint: "https://cosmo-metrics.wundergraph.com"
```

## CORS

| Environment Variable     | YAML               | Required               | Description                                                                                                                                  | Default Value                        |
| ------------------------ | ------------------ | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| CORS\_ENABLED            | enabled            | <Icon icon="square" /> | Set this to enable/disable the CORS middleware. It is enabled by default. When disabled, the rest of the properties for CORS have no effect. | true                                 |
| CORS\_ALLOW\_ORIGINS     | allow\_origins     | <Icon icon="square" /> | This is a list of origins which are allowed. You can provide origins with wildcards                                                          | \*                                   |
| CORS\_ALLOW\_METHODS     | allow\_methods     | <Icon icon="square" /> |                                                                                                                                              | HEAD,GET,POST                        |
| CORS\_ALLOW\_HEADERS     | allow\_headers     | <Icon icon="square" /> |                                                                                                                                              | Origin, Content-Length, Content-Type |
| CORS\_ALLOW\_CREDENTIALS | allow\_credentials | <Icon icon="square" /> |                                                                                                                                              | true                                 |
| CORS\_MAX\_AGE           | max\_age           | <Icon icon="square" /> |                                                                                                                                              | 5m                                   |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

cors:
  allow_origins: ["*"]
  allow_methods:
    - HEAD
    - GET
    - POST
  allow_headers:
    - Origin
    - Content-Length
    - Content-Type
  allow_credentials: true
  max_age: 5m
```

## Cache Control Policy

Configure your cache control policy. More information on this feature can be found here: [#cache-control-policy](/router/proxy-capabilities#cache-control-policy)

| Environment Variable            | YAML    | Required               | Description                                                                                                                 | Default Value |
| ------------------------------- | ------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------- |
| CACHE\_CONTROL\_POLICY\_ENABLED | enabled | <Icon icon="square" /> | Set this to enable/disable the strict cache control policy. It is false by default                                          | false         |
| CACHE\_CONTROL\_POLICY\_VALUE   | value   | <Icon icon="square" /> | The default value for the cache control policy. It will be applied to all requests, unless a subgraph has a more strict one |               |

### Example YAML Config:

```yaml config.yaml theme={"system"}
version: "1"

cache_control_policy:
  enabled: true
  value: "max-age=180, public"
  subgraphs:
    - name: "products"
      value: "max-age=60, public"
    - name: "pricing"
      value: "no-cache"
```

## Custom Modules

Configure your custom Modules. More information on this feature can be found here: [Custom Modules](/router/custom-modules)

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

modules:
  myModule:
    # Arbitrary values, unmarshalled by the module
    value: 1
```

## Router Plugins

The configuration for the router plugins. To learn more about the plugins, see the [plugins documentation](/router/gRPC/plugins).

| Environment Variable | YAML    | Required               | Description                                                                           | Default Value |
| -------------------- | ------- | ---------------------- | ------------------------------------------------------------------------------------- | ------------- |
| PLUGINS\_ENABLED     | enabled | <Icon icon="square" /> | Enable the router plugins. If the value is true, the router plugins are enabled.      | false         |
| PLUGINS\_PATH        | path    | <Icon icon="square" /> | The path to the plugins directory. The plugins directory is used to load the plugins. | plugins       |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

plugins:
  enabled: true
  path: "plugins"
```

## Headers

Configure Header propagation rules for all Subgraphs or individual Subgraphs by name.

### Cookie Whitelist

When `Cookie`is a propagated header, you may want to filter the keys that are forwarded to the subgraph from the client, you can do this via the `cookie_whitelist`option, which is a list of string cookie keys that will not be discarded. An empty value means allow all. If you'd like to block all cookies, disable the header propagation entirely.

<Info>
  The cookie whitelist can also affect custom modules that read request cookies,
  even if propagation is disabled for the `Cookie` header. This is because the
  whitelisting happens very early in the request lifecycle, before it reaches
  subgraphs or custom modules.
</Info>

**Example YAML config:**

```bash theme={"system"}
version: "1"

# Header manipulation
# See "https://cosmo-docs.wundergraph.com/router/proxy-capabilities" for more info
headers:
  cookie_whitelist:
   - "authorization"
   - "my-cookie-key"
  all:
    request:
      - op: "propagate"
        named: Cookie
```

### Global Header Rules

Apply to requests/responses to/from "all" Subgraphs. These will be applied globally in the graph

| Environment Variable | YAML     | Required               | Description                   | Default Value |
| -------------------- | -------- | ---------------------- | ----------------------------- | ------------- |
|                      | request  | <Icon icon="square" /> | List of Request Header Rules  |               |
|                      | response | <Icon icon="square" /> | List of Response Header Rules |               |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

# Header manipulation
# See "https://cosmo-docs.wundergraph.com/router/proxy-capabilities" for more info
headers:
  all: # Header rules for all origin requests.
    request:
      - op: "propagate"
        named: X-Test-Header
      - op: "propagate"
        matching: (?i)^x-deprecated-.*
      - op: "set"
        name: "X-API-Key"
        value: "my-secret-value"
    response:
      - op: "propagate"
        algorithm: "append"
        named: "X-Custom-Header"
```

#### Header Rule Example Using Template Expression:

This example sets the `X-User-ID` header based on the `sub` claim from the JWT token, if the user is authenticated.
Learn more about [template expressions](/router/configuration/template-expressions).

```yaml config.yaml theme={"system"}
version: "1"

headers:
  all:
    request:
      - op: "set"
        name: "X-User-ID"
        # Sets the header only if the user is authenticated
        expression: "request.auth.isAuthenticated ? request.auth.claims.sub : ''"
```

### Request Header Rule

Apply to requests to specific Subgraphs.

| Environment Variable | YAML                         | Required                                      | Description                                                                                                                                                                                         | Default Value |
| -------------------- | ---------------------------- | --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
|                      | op                           | <Icon icon="square-check" iconType="solid" /> | oneof=propagate, set                                                                                                                                                                                |               |
|                      | matching                     | <Icon icon="square" />                        | matching is the regex to match the header name against                                                                                                                                              |               |
|                      | named                        | <Icon icon="square" />                        | named is the exact header name to match                                                                                                                                                             |               |
|                      | rename                       | <Icon icon="square" />                        | renames the header's key to the provided value                                                                                                                                                      |               |
|                      | default                      | <Icon icon="square" />                        | default is the default value to set if the header is not present                                                                                                                                    |               |
|                      | name                         | <Icon icon="square" />                        | If `op` is `set`, `name` is the name of the desired header to set                                                                                                                                   |               |
|                      | value                        | <Icon icon="square" />                        | If `op` is `set`, `value` is the value of the desired header to set                                                                                                                                 |               |
|                      | expression                   | <Icon icon="square" />                        | If `op` is `set`, `expression` is the [expression](/router/configuration/template-expressions) to evaluate to get the value of the desired header to set                                            |               |
|                      | from\_file                   | <Icon icon="square" />                        | If `op` is `set`, sources the header value from a file's contents. The file is loaded into memory and refreshed on a polling interval, so request-time reads do not touch disk. Request rules only. |               |
|                      | from\_file.path              | <Icon icon="square-check" iconType="solid" /> | Absolute path to the file whose contents become the header value.                                                                                                                                   |               |
|                      | from\_file.refresh\_interval | <Icon icon="square-check" iconType="solid" /> | Determines how often the file is checked for changes and re-read into memory. The minimum value is `100ms`.                                                                                         | `1m`          |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

# Header manipulation
# See "https://cosmo-docs.wundergraph.com/router/proxy-capabilities" for more information
headers:
  subgraphs:
    product: # Header rules for the "product" Subgraph
      request:
        - op: "propagate"
          named: X-Test-Header
        - op: "set"
          name: "X-API-Key"
          value: "my-secret-value"
        # Read the value from a file. The file is loaded once at startup and
        # re-read every refresh_interval. Useful for mounted secrets that
        # rotate (e.g. Kubernetes Secrets, Vault Agent sidecars).
        - op: "set"
          name: "X-Service-Token"
          from_file:
            path: "/etc/secrets/service-token"
            refresh_interval: "1m"
```

<Note>
  `from_file` is request-only. It cannot be used in response header rules.
</Note>

### Response Header Rule

These rules can be applied to all responses, as well as just to specific subgraphs, and used to manipulate and propagate response headers from subgraphs to the client. By configuring the rule, users can define how headers should be handled when multiple subgraphs provide conflicting values for a specific header.

| Environment Variable | YAML      | Required                                      | Description                                                      | Default Value |
| -------------------- | --------- | --------------------------------------------- | ---------------------------------------------------------------- | ------------- |
|                      | op        | <Icon icon="square-check" iconType="solid" /> | oneof=propagate, set                                             |               |
|                      | algorithm | <Icon icon="square-check" iconType="solid" /> | oneof=first\_write, last\_write, append                          |               |
|                      | matching  | <Icon icon="square" />                        | matching is the regex to match the header name against. This     |               |
|                      | named     | <Icon icon="square" />                        | named is the exact header name to match                          |               |
|                      | default   | <Icon icon="square" />                        | default is the default value to set if the header is not present |               |
|                      | rename    | <Icon icon="square" />                        | renames the header's key to the provided value                   |               |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

# Header manipulation
# See "https://cosmo-docs.wundergraph.com/router/proxy-capabilities" for more information
headers:
  subgraphs:
    product: # Header rules for the "product" Subgraph
      response:
        - op: "propagate"
          algorithm: "append"
          named: "X-Test-Header"
        - op: "propagate"
          algorithm: "last_write"
          named: "X-Test2-Header"
        - op: "set"
          name: "X-User-Key"
          value: "my-user-value"
```

## Storage Providers

Storage providers allow you to configure different backends for persisted operations, router execution config and MCP operations.

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

storage_providers:
  s3:
    - id: "s3-provider"
      endpoint: "s3.amazonaws.com"
      access_key: "${AWS_ACCESS_KEY_ID}"
      secret_key: "${AWS_SECRET_ACCESS_KEY}"
      bucket: "my-bucket"
      region: "us-east-1"
      secure: true
  redis:
    - id: "redis-provider"
      urls:
        - "redis://localhost:6379"
      cluster_enabled: false
  file_system:
    - id: "fs-provider"
      path: "/path/to/files"
  cdn:
    - id: "cdn-provider"
      url: "https://cosmo-cdn.wundergraph.com"
```

### Storage Provider Types

Storage providers are configured as arrays, so environment variables use indexed notation: `STORAGE_PROVIDER_{TYPE}_{INDEX}_{FIELD}`. Indexes must start from `0` and be sequential. If an index is skipped, all indexes after the gap are ignored. See [Storage Providers](/router/storage-providers) for more details.

#### S3 Storage Provider

For storing operations and configs in S3-compatible storage.

| Environment Variable                     | YAML        | Required                                      | Description                                                 | Default Value |
| ---------------------------------------- | ----------- | --------------------------------------------- | ----------------------------------------------------------- | ------------- |
| STORAGE\_PROVIDER\_S3\_\{n}\_ID          | id          | <Icon icon="square-check" iconType="solid" /> | The ID of the provider to reference in other configurations |               |
| STORAGE\_PROVIDER\_S3\_\{n}\_ENDPOINT    | endpoint    | <Icon icon="square-check" iconType="solid" /> | The endpoint of the S3 service                              |               |
| STORAGE\_PROVIDER\_S3\_\{n}\_ACCESS\_KEY | access\_key | <Icon icon="square-check" iconType="solid" /> | The access key for the S3 service                           |               |
| STORAGE\_PROVIDER\_S3\_\{n}\_SECRET\_KEY | secret\_key | <Icon icon="square-check" iconType="solid" /> | The secret key for the S3 service                           |               |
| STORAGE\_PROVIDER\_S3\_\{n}\_BUCKET      | bucket      | <Icon icon="square-check" iconType="solid" /> | The bucket where objects will be stored                     |               |
| STORAGE\_PROVIDER\_S3\_\{n}\_REGION      | region      | <Icon icon="square" />                        | The region of the S3 bucket                                 |               |
| STORAGE\_PROVIDER\_S3\_\{n}\_SECURE      | secure      | <Icon icon="square" />                        | Whether to use HTTPS for S3 connections                     | false         |

#### CDN Storage Provider

For connecting to the Cosmo CDN.

| Environment Variable              | YAML | Required                                      | Description                                                 | Default Value                                                          |
| --------------------------------- | ---- | --------------------------------------------- | ----------------------------------------------------------- | ---------------------------------------------------------------------- |
| STORAGE\_PROVIDER\_CDN\_\{n}\_ID  | id   | <Icon icon="square-check" iconType="solid" /> | The ID of the provider to reference in other configurations |                                                                        |
| STORAGE\_PROVIDER\_CDN\_\{n}\_URL | url  | <Icon icon="square" />                        | The URL of the CDN                                          | [https://cosmo-cdn.wundergraph.com](https://cosmo-cdn.wundergraph.com) |

#### Redis Storage Provider

Used for distributed caching like automatic persisted queries.

| Environment Variable                             | YAML             | Required                                      | Description                                                                                                | Default Value |
| ------------------------------------------------ | ---------------- | --------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ------------- |
| STORAGE\_PROVIDER\_REDIS\_\{n}\_ID               | id               | <Icon icon="square-check" iconType="solid" /> | The ID of the provider to reference in other configurations                                                |               |
| STORAGE\_PROVIDER\_REDIS\_\{n}\_URLS             | urls             | <Icon icon="square-check" iconType="solid" /> | List of Redis URLs to connect to. If cluster\_enabled is true, these are the seeds to discover the cluster |               |
| STORAGE\_PROVIDER\_REDIS\_\{n}\_CLUSTER\_ENABLED | cluster\_enabled | <Icon icon="square" />                        | Whether to use the Redis Cluster client                                                                    | false         |

#### File System Storage Provider

This provider allows you to load files from the local file system.

| Environment Variable              | YAML | Required                                      | Description                                                   | Default Value |
| --------------------------------- | ---- | --------------------------------------------- | ------------------------------------------------------------- | ------------- |
| STORAGE\_PROVIDER\_FS\_\{n}\_ID   | id   | <Icon icon="square-check" iconType="solid" /> | The ID of the provider to reference in other configurations   |               |
| STORAGE\_PROVIDER\_FS\_\{n}\_PATH | path | <Icon icon="square-check" iconType="solid" /> | The path on the file system where files should be loaded from |               |

## Persisted Operations

The configuration for the persisted operations allows you to maintain a fixed set of GraphQL operations that can be queried against the router without exposing your entire graph to the public. This approach enhances security and performance.

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

persisted_operations:
  disabled: false
  log_unknown: false
  safelist:
    enabled: false
  cache:
    size: 100MB
  storage:
    provider_id: s3
    object_prefix: wundergraph
```

### Persisted Operations Configuration Options

These rules apply to requests being made from the Router to all Subgraphs.

| Environment Variable                            | YAML                                          | Required                                      | Description                                                                                                                                                                                                                                                                              | Default Value |
| ----------------------------------------------- | --------------------------------------------- | --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
|                                                 | persisted\_operations                         | <Icon icon="square" />                        | The configuration for the persisted operations.                                                                                                                                                                                                                                          |               |
| PERSISTED\_OPERATIONS\_DISABLED                 | persisted\_operations.disabled                | <Icon icon="square" />                        | Disable persisted operations. When set to true, the PQL manifest is also disabled.                                                                                                                                                                                                       | false         |
|                                                 | persisted\_operations.cache                   | <Icon icon="square" />                        | LRU cache for persisted operations.                                                                                                                                                                                                                                                      |               |
| PERSISTED\_OPERATIONS\_CACHE\_SIZE              | persisted\_operations.cache.size              | <Icon icon="square" />                        | The size of the cache in SI unit.                                                                                                                                                                                                                                                        | "100MB"       |
|                                                 | persisted\_operations.storage                 | <Icon icon="square" />                        | The storage provider for persisted operation. Only one provider can be active. When no provider is specified, the router will fallback to the Cosmo CDN provider to download the persisted operations.                                                                                   |               |
| PERSISTED\_OPERATIONS\_STORAGE\_PROVIDER\_ID    | persisted\_operations.storage.provider\_id    | <Icon icon="square-check" iconType="solid" /> | The ID of the storage provider. The ID must match the ID of the storage provider in the `storage_providers` section.                                                                                                                                                                     |               |
| PERSISTED\_OPERATIONS\_STORAGE\_OBJECT\_PREFIX  | persisted\_operations.storage.object\_prefix  | <Icon icon="square" />                        | The prefix of the object in the storage provider location. The prefix is put in front of the operation SHA256 hash. \$prefix/SHA256.json                                                                                                                                                 |               |
| PERSISTED\_OPERATIONS\_LOG\_UNKNOWN             | persisted\_operations.log\_unknown            | <Icon icon="square" />                        | Log operations (sent with the operation body) which haven't yet been persisted. If the value is true, all operations not yet persisted are logged to the router logs.                                                                                                                    | false         |
| PERSISTED\_OPERATIONS\_SAFELIST\_ENABLED        | persisted\_operations.safelist.enabled        | <Icon icon="square" />                        | Only allows persisted operations (sent with operation body). If the value is true, all operations not explicitly added to the safelist are blocked.                                                                                                                                      | false         |
| PERSISTED\_OPERATIONS\_MANIFEST\_ENABLED        | persisted\_operations.manifest.enabled        | <Icon icon="square" />                        | Enable the PQL manifest. When enabled, the router loads all persisted operations from a single manifest file and serves them from memory. Uses the `storage` config above when a provider is set, otherwise fetches from the Cosmo CDN. Only S3 and CDN storage providers are supported. | false         |
| PERSISTED\_OPERATIONS\_MANIFEST\_FILE\_NAME     | persisted\_operations.manifest.file\_name     | <Icon icon="square" />                        | The manifest file name. Only used when a custom storage provider is configured. The router resolves the full object path as `<object_prefix>/<file_name>`. Use a `.gz` or `.zst` extension (e.g. `manifest.json.gz`) to enable transparent decompression. Ignored in CDN mode.           | manifest.json |
| PERSISTED\_OPERATIONS\_MANIFEST\_POLL\_INTERVAL | persisted\_operations.manifest.poll\_interval | <Icon icon="square" />                        | The interval at which the router polls the Cosmo CDN for manifest updates (only when no storage provider is configured). Minimum 10s.                                                                                                                                                    | 10s           |
| PERSISTED\_OPERATIONS\_MANIFEST\_POLL\_JITTER   | persisted\_operations.manifest.poll\_jitter   | <Icon icon="square" />                        | Random jitter added to each poll interval to avoid thundering herd. Minimum 1s.                                                                                                                                                                                                          | 5s            |

## Automatic Persisted Queries

The configuration for automatic persisted queries allows you to enable automated caching of select GraphQL operations that can be queried against the router, using both POST and GET requests. This approach enhances performance.

It defaults to using a local cache (with the size defined in `cache.size`), but users can optionally use a Redis storage

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

automatic_persisted_queries:
  enabled: true
  cache:
    size: 10MB # This is only relevant for an in-memory cache that we maintain
    ttl: 900 # in seconds, set both for a local and a remote KV
  storage:
    provider_id: "my_redis"
    object_prefix: cosmo_apq
```

### Configuration Options

These rules apply to requests being made from the Router to all Subgraphs.

| Environment Variable | YAML                                                 | Required                                      | Description                                                                                                                                                                                                                                                        | Default Value |
| -------------------- | ---------------------------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- |
|                      | automatic\_persisted\_queries                        | <Icon icon="square" />                        | The configuration for the persisted operations.                                                                                                                                                                                                                    |               |
|                      | automatic\_persisted\_queries.enabled                | <Icon icon="square" />                        | Whether or not automatic persisted queries is enabled                                                                                                                                                                                                              | true          |
|                      | automatic\_persisted\_queries.cache                  | <Icon icon="square" />                        | LRU cache for persisted operations.                                                                                                                                                                                                                                |               |
|                      | automatic\_persisted\_queries.cache.size             | <Icon icon="square" />                        | The size of the cache in SI unit.                                                                                                                                                                                                                                  | "100MB"       |
|                      | automatic\_persisted\_queries.cache.ttl              | <Icon icon="square" />                        | The TTL of the cache, in seconds. Set to 0 to set no TTL                                                                                                                                                                                                           |               |
|                      | automatic\_persisted\_queries.storage                | <Icon icon="square" />                        | The external storage provider (redis) for automatic persisted operation. Only one provider can be active. When no provider is specified, the router will fallback to using a local in-memory cache (configured in the `automatic_persisted_queries.cache` options) |               |
|                      | automatic\_persisted\_queries.storage.provider\_id   | <Icon icon="square-check" iconType="solid" /> | The ID of the Redis storage provider. The ID must match the ID of the storage provider in the `storage_providers.redis` section.                                                                                                                                   |               |
|                      | automatic\_persisted\_queries.storage.object\_prefix | <Icon icon="square-check" iconType="solid" /> | The prefix of the object in the storage provider location. The prefix is put in front of the operation SHA256 hash. \$prefix/SHA256                                                                                                                                |               |

## Execution Config

The configuration for the execution setup contains instructions for the router to plan and execute your GraphQL operations. You can specify the storage provider from which the configuration should be fetched.

### Example YAML config:

The execution config source is exclusive. Configure exactly one of `storage`, `file`, or `manifest`. `fallback_storage` is the only field that may be combined with `storage` and is used to retry from a secondary location when the primary storage provider fails.

<CodeGroup>
  ```yaml Storage provider theme={"system"}
  version: "1"
  execution_config:
    storage:
      provider_id: s3
      object_path: "router.json"
  ```

  ```yaml Local file theme={"system"}
  version: "1"
  execution_config:
    file:
      path: "./__schemas/config.json"
      watch: true
      watch_interval: "1s"
  ```

  ```yaml Local manifest theme={"system"}
  version: "1"
  execution_config:
    manifest:
      path: "./__schemas/manifest"
      skip_missing_feature_flags: false
      ignored_feature_flags:
        - "experimental-checkout"
      watch: true
      watch_interval: "1s"
  ```

  ```yaml Fallback storage theme={"system"}
  version: "1"
  execution_config:
    storage:
      provider_id: s3
      object_path: "router.json"
    fallback_storage:
      enabled: true
      provider_id: minio
      object_path: "router.json"
  ```
</CodeGroup>

A manifest directory contains a `mapper.json` indexing the base graph and every feature flag by version, a `latest.json` with the base graph's execution config, and one `feature-flags/<name>.json` per feature flag. When `watch` is enabled, the router watches `mapper.json`. Whenever the file's mtime changes, the router reloads the assembled config without downtime.

When using a storage provider, the `object_path` field points to the file in your bucket that is updated after each schema deployment in your CI/CD pipeline:

```bash theme={"system"}
# Publish your subgraph
wgc subgraph publish my-subgraph --schema ./schema.graphqls
# Download the latest execution config after successful composition
wgc router fetch mygraph -o router.json
# Upload the execution config to your S3 storage
aws s3 cp router.json s3://cosmo/
```

The router will check for updates every 10 seconds (default) and hot-reload accordingly without impacting current user traffic.

You can configure a fallback storage for fetching the execution config in the event the router cannot reach the primary storage. You cannot use the same provider for both primary and fallback storage.

### Execution config options

| Environment Variable                                       | YAML                                             | Required                                      | Description                                                                                                                                                                                                                                  | Default Value |
| ---------------------------------------------------------- | ------------------------------------------------ | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
|                                                            | execution\_config                                | <Icon icon="square" />                        | The configuration for the execution config.                                                                                                                                                                                                  |               |
|                                                            | file                                             | <Icon icon="square" />                        | The configuration for the execution config file. The config file is used to load the execution config from the local file system. The file has precedence over the storage provider.                                                         |               |
| EXECUTION\_CONFIG\_FILE\_PATH                              | file.path                                        | <Icon icon="square" />                        | The path to the execution config file. The path is used to load the execution config from the local file system.                                                                                                                             |               |
| EXECUTION\_CONFIG\_FILE\_WATCH                             | file.watch                                       | <Icon icon="square" />                        | Enable the watch mode. The watch mode is used to watch the execution config file for changes. If the file changes, the router will reload the execution config without downtime.                                                             | true          |
| EXECUTION\_CONFIG\_FILE\_WATCH\_INTERVAL                   | file.watch\_interval                             | <Icon icon="square" />                        | The interval at which the file is checked for changes.                                                                                                                                                                                       | 1s            |
|                                                            | manifest                                         | <Icon icon="square" />                        | The configuration for loading the execution config from a local manifest directory. The directory contains `mapper.json`, `latest.json`, and one `feature-flags/<name>.json` per feature flag. Mutually exclusive with `file` and `storage`. |               |
| EXECUTION\_CONFIG\_MANIFEST\_PATH                          | manifest.path                                    | <Icon icon="square-check" iconType="solid" /> | The path to the manifest directory.                                                                                                                                                                                                          |               |
| EXECUTION\_CONFIG\_MANIFEST\_SKIP\_MISSING\_FEATURE\_FLAGS | manifest.skip\_missing\_feature\_flags           | <Icon icon="square" />                        | Skip feature flags listed in `mapper.json` whose execution config file cannot be loaded, instead of aborting the load.                                                                                                                       | false         |
| EXECUTION\_CONFIG\_MANIFEST\_IGNORED\_FEATURE\_FLAGS       | manifest.ignored\_feature\_flags                 | <Icon icon="square" />                        | Feature flag names to skip entirely when loading the manifest. Listed flags are not loaded even when referenced by `mapper.json`.                                                                                                            |               |
| EXECUTION\_CONFIG\_MANIFEST\_WATCH                         | manifest.watch                                   | <Icon icon="square" />                        | Enable the watch mode. When enabled, the router stats `mapper.json` for changes and reloads the assembled execution config without downtime.                                                                                                 | false         |
| EXECUTION\_CONFIG\_MANIFEST\_WATCH\_INTERVAL               | manifest.watch\_interval                         | <Icon icon="square" />                        | The interval at which `mapper.json` is checked for changes. Only applied when `manifest.watch` is enabled.                                                                                                                                   | 1s            |
|                                                            | execution\_config.storage                        | <Icon icon="square" />                        | The storage provider for the execution config. Only one provider can be active. When no provider is specified, the router will fallback to the Cosmo CDN provider to download the execution config.                                          |               |
| EXECUTION\_CONFIG\_STORAGE\_PROVIDER\_ID                   | execution\_config.storage.provider\_id           | <Icon icon="square-check" iconType="solid" /> | The ID of the storage provider. The ID must match the ID of the storage provider in the `storage_providers` section.                                                                                                                         |               |
| EXECUTION\_CONFIG\_STORAGE\_OBJECT\_PATH                   | execution\_config.storage.object\_path           | <Icon icon="square-check" iconType="solid" /> | The path to the execution config in the storage provider. The path is used to download the execution config from the S3 bucket.                                                                                                              |               |
| EXECUTION\_CONFIG\_FALLBACK\_STORAGE\_ENABLED              | execution\_config.fallback\_storage.enabled      | <Icon icon="square" />                        | Enable a fallback storage to fetch the execution config in case the above primary source fails.                                                                                                                                              | false         |
| EXECUTION\_CONFIG\_FALLBACK\_STORAGE\_PROVIDER\_ID         | execution\_config.fallback\_storage.provider\_id | <Icon icon="square" />                        | The ID of the storage provider. The ID must match the ID of the storage provider in the `storage_providers` section.                                                                                                                         |               |
| EXECUTION\_CONFIG\_FALLBACK\_STORAGE\_OBJECT\_PATH         | execution\_config.fallback\_storage.object\_path | <Icon icon="square" />                        | The path to the execution config in the storage provider. The path is used to download the execution config from the S3 bucket.                                                                                                              |               |

## Split Config Poller

The split-config polling strategy assembles the final router execution config by fetching the base graph and each feature flag config as separate files from the CDN. These rules govern its behavior when individual feature flag files are missing or should be excluded entirely. They are only applied when the router is enrolled in split-config loading; with a custom storage provider the router falls back to the regular polling strategy and these rules have no effect.

The base graph is always required. Skip and ignore rules apply to feature flags only. A missing or unfetchable base graph always aborts the poll cycle, regardless of these rules.

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

split_config_poller:
  skip_missing_feature_flags: true
  ignored_feature_flags:
    - "experimental-checkout"
    - "ab-test-foo"
```

### Split config poller options

| Environment Variable                                 | YAML                                                | Required               | Description                                                                                                                                                                      | Default Value |
| ---------------------------------------------------- | --------------------------------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| SPLIT\_CONFIG\_POLLER\_SKIP\_MISSING\_FEATURE\_FLAGS | split\_config\_poller.skip\_missing\_feature\_flags | <Icon icon="square" /> | Keep polling alive when a feature flag listed in the mapper cannot be fetched (responds with `file not found`). When false, a single missing feature flag aborts the poll cycle. | false         |
| SPLIT\_CONFIG\_POLLER\_IGNORED\_FEATURE\_FLAGS       | split\_config\_poller.ignored\_feature\_flags       | <Icon icon="square" /> | Feature flag names to skip entirely during polling. Listed flags are not fetched even when present in the mapper, and are absent from the assembled execution config.            | \[]           |

## Traffic Shaping

Configure rules for traffic shaping like maximum request body size, timeouts, retry behavior, etc. For more info, check this section in the docs: [Traffic shaping](/router/traffic-shaping)

### Example YAML config:

```yaml theme={"system"}
version: "1"

# Traffic configuration
# See "https://cosmo-docs.wundergraph.com/router/traffic-shaping" for more information
traffic_shaping:
  # Apply to all requests from clients to the router
  router:
    # Is the maximum size of the request body in MB, mib
    max_request_body_size: 5MB
    max_header_bytes: 1MiB
    decompression_enabled: true
    response_compression_min_size: 4KiB
  all: # Rules are applied to all subgraph requests.
    # Subgraphs transport options
    request_timeout: 60s
    dial_timeout: 30s
    tls_handshake_timeout: 0s
    response_header_timeout: 0s
    expect_continue_timeout: 0s
    keep_alive_idle_timeout: 90s
    keep_alive_probe_interval: 30s
    max_idle_conns: 1024
    max_conns_per_host: 100
    max_idle_conns_per_host: 20
    # Retry
    retry: # Rule is only applied to GraphQL operations of type "query"
      enabled: true
      algorithm: "backoff_jitter"
      max_attempts: 5
      interval: 3s
      max_duration: 10s
      condition: "IsRetryableStatusCode() || IsConnectionError() || IsTimeout()"
    # Circuit Breaker
    circuit_breaker:
      enabled: true
      request_threshold: 20
      error_threshold_percentage: 50
      sleep_window: 30s
      half_open_attempts: 5
      required_successful: 3
      rolling_duration: 60s
      num_buckets: 10
      execution_timeout: 60s
      max_concurrent_requests: -1

  subgraphs: # allows you to create subgraph specific traffic shaping rules
    products: # Will only affect this subgraph, and override the options in "all" for that subgraph
      request_timeout: 60s
      dial_timeout: 30s
      keep_alive_idle_timeout: 0s
      keep_alive_probe_interval:
      tls_handshake_timeout: 10s
      response_header_timeout: 0s
      expect_continue_timeout: 0s
      max_idle_conns: 1024
      max_conns_per_host: 100
      max_idle_conns_per_host: 20
      # You can configure circuit breakers per subgraph, which includes the above configurations
      circuit_breaker:
        enabled: false
```

### Subgraph Request Rules

These rules apply to requests being made from the Router to all Subgraphs.

| Environment Variable | YAML                         | Required                                      | Description                                                                         | Default Value |
| -------------------- | ---------------------------- | --------------------------------------------- | ----------------------------------------------------------------------------------- | ------------- |
|                      | retry                        | <Icon icon="square" />                        | [#traffic-shaping-jitter-retry](/router/configuration#traffic-shaping-jitter-retry) |               |
|                      | circuit\_breaker             | <Icon icon="square" />                        | [#circuit-breaker](/router/configuration#circuit-breaker)                           |               |
|                      | request\_timeout             | <Icon icon="square-check" iconType="solid" /> |                                                                                     | 60s           |
|                      | dial\_timeout                | <Icon icon="square" />                        |                                                                                     | 30s           |
|                      | response\_header\_timeout    | <Icon icon="square" />                        |                                                                                     | 0s            |
|                      | expect\_continue\_timeout    | <Icon icon="square" />                        |                                                                                     | 0s            |
|                      | tls\_handshake\_timeout      | <Icon icon="square" />                        |                                                                                     | 10s           |
|                      | keep\_alive\_idle\_timeout   | <Icon icon="square" />                        |                                                                                     | 90s           |
|                      | keep\_alive\_probe\_interval | <Icon icon="square" />                        |                                                                                     | 30s           |
|                      | max\_idle\_conns             | <Icon icon="square" />                        |                                                                                     | 1024          |
|                      | max\_conns\_per\_host        | <Icon icon="square" />                        |                                                                                     | 100           |
|                      | max\_idle\_conns\_per\_host  | <Icon icon="square" />                        |                                                                                     | 20            |

### Subgraph specific request rules

In addition to the general traffic shaping rules, we also allow users to set subgraph specific timeout options, overriding the default traffic rules defined in `all`(if present)

| Environment Variable | YAML                         | Required               | Description | Default Value |
| -------------------- | ---------------------------- | ---------------------- | ----------- | ------------- |
|                      | request\_timeout             | <Icon icon="square" /> |             | 60s           |
|                      | dial\_timeout                | <Icon icon="square" /> |             | 30s           |
|                      | response\_header\_timeout    | <Icon icon="square" /> |             | 0s            |
|                      | expect\_continue\_timeout    | <Icon icon="square" /> |             | 0s            |
|                      | keep\_alive\_idle\_timeout   | <Icon icon="square" /> |             | 90s           |
|                      | keep\_alive\_probe\_interval | <Icon icon="square" /> |             | 30s           |
|                      | max\_idle\_conns             | <Icon icon="square" /> |             | 1024          |
|                      | max\_conns\_per\_host        | <Icon icon="square" /> |             | 100           |
|                      | max\_idle\_conns\_per\_host  | <Icon icon="square" /> |             | 20            |

### Circuit Breaker

Configure circuit breaker either for all subgraphs, or per subgraph. More information on circuit breakers can be found [here](/router/traffic-shaping/circuit-breaker).

| Environment Variable | YAML                         | Required               | Description                                                                                                                                                                                                                                                                    | Default Value |
| -------------------- | ---------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- |
|                      | enabled                      | <Icon icon="square" /> | Enable the circuit breaker for the target (all subgraphs or a specific subgraph).                                                                                                                                                                                              | false         |
|                      | error\_threshold\_percentage | <Icon icon="square" /> | This represents the percentage of failed requests within the rolling window that will trigger the circuit to open. For example, with a 50% threshold and 100 total requests in the window, the circuit will open when 50 or more requests fail.                                | 50            |
|                      | request\_threshold           | <Icon icon="square" /> | Defines the minimum number of requests that must be received before the circuit breaker will evaluate error rates for potential state transitions.                                                                                                                             | 20            |
|                      | sleep\_window                | <Icon icon="square" /> | This setting determines how long the circuit will block all requests after transitioning to the open state. The sleep window serves a critical purpose: it gives the failing service time to recover without being overwhelmed by continued request attempts.                  | 5s            |
|                      | half\_open\_attempts         | <Icon icon="square" /> | Number of test requests allowed in the half-open state.                                                                                                                                                                                                                        | 1             |
|                      | required\_successful         | <Icon icon="square" /> | How many successful requests are needed to close the circuit from the half-open state. This setting works in conjunction with half\_open\_attempts to determine the recovery behavior.                                                                                         | 1             |
|                      | rolling\_duration            | <Icon icon="square" /> | The time window for collecting error and request statistics. Only data from within this window influences circuit breaker decisions, ensuring that the circuit responds to current conditions rather than being influenced by historical problems that may have been resolved. | 10s           |
|                      | num\_buckets                 | <Icon icon="square" /> | Number of buckets for statistics in the rolling window (higher = finer granularity).                                                                                                                                                                                           | 10            |
|                      | execution\_timeout           | <Icon icon="square" /> | The maximum time allocated before marking a request as failed due to timeout. This timeout is specifically for circuit breaker error tracking and operates independently of any actual request timeouts.                                                                       | 60s           |
|                      | max\_concurrent\_requests    | <Icon icon="square" /> | This controls the maximum number of concurrent requests that the circuit breaker will process simultaneously. When set to the default value of -1, there is no limit on concurrent requests.                                                                                   | -1            |

### Jitter Retry

| Environment Variable | YAML          | Required                                      | Description                                                                         | Default Value             |   |                     |   |               |
| -------------------- | ------------- | --------------------------------------------- | ----------------------------------------------------------------------------------- | ------------------------- | - | ------------------- | - | ------------- |
| RETRY\_ENABLED       | enabled       | <Icon icon="square" />                        |                                                                                     | true                      |   |                     |   |               |
| RETRY\_ALGORITHM     | algorithm     | <Icon icon="square" />                        | backoff\_jitter                                                                     | backoff\_jitter           |   |                     |   |               |
| RETRY\_EXPRESSION    | expression    | <Icon icon="square" />                        | The retry expression used to decide if a failed subgraph request should be retried. | \`IsRetryableStatusCode() |   | IsConnectionError() |   | IsTimeout()\` |
| RETRY\_MAX\_ATTEMPTS | max\_attempts | <Icon icon="square-check" iconType="solid" /> |                                                                                     |                           |   |                     |   |               |
| RETRY\_MAX\_DURATION | max\_duration | <Icon icon="square-check" iconType="solid" /> |                                                                                     |                           |   |                     |   |               |
| RETRY\_INTERVAL      | interval      | <Icon icon="square-check" iconType="solid" /> |                                                                                     |                           |   |                     |   |               |

### Client Request Request Rules

These rules apply to requests being made from clients to the Router.

| Environment Variable | YAML                             | Required               | Description                                                                                                                                                                                                                                  | Default Value |
| -------------------- | -------------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
|                      | max\_request\_body\_size         | <Icon icon="square" /> |                                                                                                                                                                                                                                              | 5mb           |
| MAX\_HEADER\_BYTES   | max\_header\_bytes               | <Icon icon="square" /> | Minimum Router version: [0.156.0](https://github.com/wundergraph/cosmo/compare/router@0.155.0...router@0.156.0) The maximum size of the request headers. Setting this to 0 uses the default value from the http standard lib, which is 1MiB. | 1mib          |
|                      | decompression\_enabled           | <Icon icon="square" /> | When enabled, the router will check incoming requests for a 'Content-Encoding' header and decompress the body accordingly Note: Currently only "gzip" is supported                                                                           | true          |
|                      | response\_compression\_min\_size | <Icon icon="square" /> | The minimum size of the response body in bytes to enable response compression. The size is specified as a string with a number and a unit, e.g. 10KB, 1MB, 1GB                                                                               | 4KiB          |
| 5mb                  |                                  |                        |                                                                                                                                                                                                                                              |               |

## WebSocket

Configure WebSocket handlers, protocols, and more.

### WebSocket Configuration

| Environment Variable | YAML                                 | Required                                      | Description                                                                                                                                  | Default Value |
| -------------------- | ------------------------------------ | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| WEBSOCKETS\_ENABLED  | enabled                              | <Icon icon="square-check" iconType="solid" /> |                                                                                                                                              | true          |
|                      | absinthe\_protocol                   | <Icon icon="square" />                        | [Absinthe Protocol Configuration](/router/configuration#absinthe-protocol-configuration)                                                     |               |
|                      | forward\_upgrade\_headers            | <Icon icon="square" />                        | Forward all useful Headers from the Upgrade Request, like User-Agent or Authorization in the extensions field when subscribing on a Subgraph |               |
|                      | forward\_upgrade\_query\_params      | <Icon icon="square" />                        | Forward all query parameters from the Upgrade Request in the extensions field when subscribing on a Subgraph                                 |               |
|                      | forward\_initial\_payload            | <Icon icon="square" />                        | Forward the initial payload from a client subscription in the extensions field when subscribing on a Subgraph                                | true          |
|                      | client\_info\_from\_initial\_payload | <Icon icon="square" />                        | [WebSocket Client Info Configuration](/router/configuration#websocket-client-info-configuration)                                             |               |

### Absinthe Protocol Configuration

Legacy WebSocket clients that use the Absinthe protocol might not be able to send a Subprotocol Header. For such clients, you can use the Absinthe Endpoint which automatically chooses the Subprotocol for them so that no Subprotocol Header needs to be set.

| Environment Variable                | YAML          | Required               | Description                               | Default Value    |
| ----------------------------------- | ------------- | ---------------------- | ----------------------------------------- | ---------------- |
| WEBSOCKETS\_ABSINTHE\_ENABLED       | enabled       | <Icon icon="square" /> |                                           | true             |
| WEBSOCKETS\_ABSINTHE\_HANDLER\_PATH | handler\_path | <Icon icon="square" /> | The path to mount the Absinthe handler on | /absinthe/socket |

### WebSocket Authentication

It's possible that Authentication for a WebSocket connection is not possible at the HTTP layer. In such a case, you can enable Authentication "from\_initial\_payload". This will extract a value from the "initial\_payload" field in the first WebSocket message which is responsible for negotiating the protocol between client and server.

In addition, it's possible to export the extracted value into a Request Header, which allows the Router to propagate it using [Header Propagation Rules](/router/configuration#global-header-rules) in subsequent Subgraph Requests.

### WebSocket Client Info Configuration

Configure how to extract client info from the initial WebSocket payload. This allows you to set client name and version information from the initial connection payload, which can then be forwarded to request headers if needed.

| Environment Variable                                                                     | YAML                                                  | Required               | Description                                                              | Default Value |
| ---------------------------------------------------------------------------------------- | ----------------------------------------------------- | ---------------------- | ------------------------------------------------------------------------ | ------------- |
| WEBSOCKETS\_CLIENT\_INFO\_FROM\_INITIAL\_PAYLOAD\_ENABLED                                | enabled                                               | <Icon icon="square" /> | Enable extracting client info from initial payload                       | true          |
| WEBSOCKETS\_CLIENT\_INFO\_FROM\_INITIAL\_PAYLOAD\_NAME\_FIELD                            | name\_field                                           | <Icon icon="square" /> | The field name in the initial payload to extract the client name from    |               |
| WEBSOCKETS\_CLIENT\_INFO\_FROM\_INITIAL\_PAYLOAD\_VERSION\_FIELD                         | version\_field                                        | <Icon icon="square" /> | The field name in the initial payload to extract the client version from |               |
| WEBSOCKETS\_CLIENT\_INFO\_FROM\_INITIAL\_PAYLOAD\_FORWARD\_TO\_REQUEST\_HEADERS\_ENABLED | forward\_to\_request\_headers.enabled                 | <Icon icon="square" /> | Enable forwarding extracted client info to request headers               | true          |
| WEBSOCKETS\_CLIENT\_INFO\_FROM\_INITIAL\_PAYLOAD\_NAME\_TARGET\_HEADER                   | forward\_to\_request\_headers.name\_target\_header    | <Icon icon="square" /> | The header name to forward the client name to                            |               |
| WEBSOCKETS\_CLIENT\_INFO\_FROM\_INITIAL\_PAYLOAD\_VERSION\_TARGET\_HEADER                | forward\_to\_request\_headers.version\_target\_header | <Icon icon="square" /> | The header name to forward the client version to                         |               |

### Example WebSocket YAML config:

```yaml config.yaml theme={"system"}
version: "1"

websocket:
  enabled: true
  absinthe_protocol:
    enabled: true
    handler_path: /absinthe/socket
  forward_initial_payload: true
  forward_upgrade_headers:
    enabled: true
    allow_list: # an empty list allows all headers
      - "Authorization" # forward only the Authorization Header
  forward_upgrade_query_params:
    enabled: true
    allow_list:
      - "Authorization"
  client_info_from_initial_payload:
    # enable extracting client info from initial payload
    enabled: true
    # the field name in the initial payload to extract the client name from
    name_field: "graphql-client-name"
    # the field name in the initial payload to extract the client version from
    version_field: "graphql-client-version"
    # enable forwarding extracted client info to request headers
    forward_to_request_headers:
      # enable forwarding extracted client info to request headers
      enabled: true
      # the header name to forward the client name to
      name_target_header: "GraphQL-Client-Name"
      # the header name to forward the client version to
      version_target_header: "GraphQL-Client-Version"
  authentication:
    # enable authentication from the initial payload
    from_initial_payload:
      enabled: false
      # which key to use one the initial payload to "extract" the Authorization value
      key: "authorization"
      export_token:
        export_token: false
        # to enable Subgraph authentication, we can export the value into a Header
        header_key: "Authorization"
```

## Authentication

Configure different authentication providers.

### New Authentication Config (Router Version ≥ 0.169.0)

### JWKS

The following configuration has two flavours

#### JWKS URL endpoint

This is useful when you want to connect to a JWKS endpoint

| YAML                            | Required                                      | Description                                                                                                                                                                                                                                                | Default Value     |
| ------------------------------- | --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
| url                             | <Icon icon="square-check" iconType="solid" /> | The URL of the JWKs. The JWKs are used to verify the JWT (JSON Web Token). The URL is specified as a string with the format 'scheme://host:port'.                                                                                                          |                   |
| refresh\_interval               | <Icon icon="square" />                        | The interval at which the JWKs are refreshed. The period is specified as a string with a number and a unit, e.g. 10ms, 1s, 1m, 1h. The supported units are 'ms', 's', 'm', 'h'.                                                                            | 1m                |
| allowed\_use                    | <Icon icon="square" />                        | The allowed value of the use parameter for the JWKs. If not specified, only keys with use set to 'sig' will be used. If your server provides no use, you can add an empty value to allow those keys.                                                       | \["sig"]          |
| algorithms                      | <Icon icon="square" />                        | The allowed algorithms for the keys that are retrieved from the JWKs. An empty list means that all algorithms are allowed. The following algorithms are supported "RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "PS256", "PS384", "PS512", "EdDSA" | \[] (all allowed) |
| refresh\_unknown\_kid.enabled   | <Icon icon="square" />                        | Enable automatic JWKS refresh when encountering a valid token with an unknown KID (Key ID). When enabled, the router will fetch updated keys to find the matching KID.                                                                                     | false             |
| refresh\_unknown\_kid.max\_wait | <Icon icon="square" />                        | Maximum time a refresh is allowed to wait. If the computed wait would exceed this value, the request fails immediately with 401 Unauthorized instead of waiting.                                                                                           | 2m                |
| refresh\_unknown\_kid.interval  | <Icon icon="square" />                        | Time between replenishing burst tokens. With burst=1, each subsequent request within the interval must wait for (interval × attempt number).                                                                                                               | 30s               |
| refresh\_unknown\_kid.burst     | <Icon icon="square" />                        | Maximum number of refreshes allowed without waiting. Prevents overloading the JWKS endpoint; beyond this, requests wait until the interval elapses or fail due to max\_wait.                                                                               | 2                 |

#### Secret

This is useful when you have a symmetric key that you cannot expose through a JWKS endpoint, you can use the secret based configuration

| YAML                 | Required                                      | Description                                                                                                                               | Default Value |
| -------------------- | --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| secret               | <Icon icon="square-check" iconType="solid" /> | The secret value, which will be used to construct the "k" parameter of the JWKS                                                           |               |
| header\_key\_id      | <Icon icon="square-check" iconType="solid" /> | The key id, this is required as the router use JWK Sets and is used to construct the "kid" attribute which helps identify the correct JWK |               |
| symmetric\_algorithm | <Icon icon="square-check" iconType="solid" /> | Specify which symmetric algorithm is used for signing, supported algorithms are "HS256", "HS384", "HS512"                                 |               |

#### Audience Validation

In addition to the above JWKS configuration flavours, you can define a list of audiences of which one is required (if specified) with either options.

| YAML      | Required               | Description                                                                            | Default Value |
| --------- | ---------------------- | -------------------------------------------------------------------------------------- | ------------- |
| audiences | <Icon icon="square" /> | The allowed list of audiences, of which at least one audience is required in the token | \[]           |

### JWT

| YAML                  | Required               | Description                                                                                                                                                                 | Default Value |
| --------------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| scope\_claim          | <Icon icon="square" /> | The JWT claim used to read scopes for authorization. Use this when your identity provider stores scopes in a claim other than `scope`. Only top level claims are supported. | scope         |
| header\_name          | <Icon icon="square" /> | The name of the header. The header is used to extract the token from the request. The default value is 'Authorization'.                                                     | Authorization |
| header\_value\_prefix | <Icon icon="square" /> | The prefix of the header value. The prefix is used to extract the token from the header value. The default value is 'Bearer'.                                               | Bearer        |

### Header Sources

| YAML            | Required                                      | Description                                                                                                                        | Default Value |
| --------------- | --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| type            | <Icon icon="square-check" iconType="solid" /> | The type of the source. The only currently supported type is 'header'.                                                             | header        |
| name            | <Icon icon="square-check" iconType="solid" /> | The name of the header. The header is used to extract the token from the request. The default value is 'Authorization'.            | Authorization |
| value\_prefixes | <Icon icon="square" />                        | The prefixes of the header value. The prefixes are used to extract the token from the header value. The default value is 'Bearer'. | Bearer        |

### Example YAML config V2:

```yaml theme={"system"}
authentication:
  jwt:
    jwks:
      - url: "https://example.com/.well-known/jwks.json"
        refresh_interval: 1m
        # Leaving algorithms empty will allow all supported algorithms from the config docs
        refresh_unknown_kid:
          enabled: true
          max_wait: 2m
          interval: 30s
          burst: 2
      - url: "https://example2.com/.well-known/jwks.json"
        refresh_interval: 2m
        # optional list of allowed algorithms per JWKS
        algorithms: ["RS256", "EdDSA", "HS512"]
        refresh_unknown_kid:
          enabled: false # These are defaults
          max_wait: 2m 
          interval: 30s
          burst: 2
    header_name: Authorization # This is the default value
    scope_claim: scope # This is the default value
    header_value_prefix: Bearer # This is the default value
    header_sources:
      - type: header
        name: X-Auth-Token
        value_prefixes: [Token, MyToken]
      - type: header
        name: X-Authorization
```

### Bypass Introspection Authentication

This is useful when you want to bypass authentication for introspection queries,
for example let certain tools introspect the schema without requiring authentication token.

<Warning>
  This feature is meant to be used in secure, internal environments. It is not recommended for use in a production environment.
  By default, introspection queries are not excluded from authentication.
  Also consider setting `introspection.secret` for a static secret dedicated to introspection queries.
</Warning>

| Environment Variable | YAML                  | Required               | Description                         | Default Value |
| -------------------- | --------------------- | ---------------------- | ----------------------------------- | ------------- |
|                      | ignore\_introspection | <Icon icon="square" /> | Bypass introspection authentication | false         |

### Old Authentication Config (Router Version \< 0.XXX.X)

### Provider

| Environment Variable | YAML | Required               | Description          | Default Value    |
| -------------------- | ---- | ---------------------- | -------------------- | ---------------- |
|                      | name | <Icon icon="square" /> | Name of the provider | My Auth Provider |
|                      | jwks | <Icon icon="square" /> | JWKS Provider        |                  |

### JWK Provider

| Environment Variable | YAML                    | Required                                      | Description | Default Value |
| -------------------- | ----------------------- | --------------------------------------------- | ----------- | ------------- |
|                      | url                     | <Icon icon="square" />                        |             |               |
|                      | header\_names           | <Icon icon="square" />                        |             |               |
|                      | header\_value\_prefixes | <Icon icon="square" />                        |             |               |
|                      | refresh\_interval       | <Icon icon="square-check" iconType="solid" /> |             | 1m            |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

# Authentication and Authorization
# See https://cosmo-docs.wundergraph.com/router/authentication-and-authorization for more information
authentication:
  providers:
    - name: My Auth Provider # Optional, used for error messages and diagnostics
      jwks: # JWKS provider configuration
        url: https://example.com/.well-known/jwks.json # URL to load the JWKS from
        header_name: Authorization # Optional
        header_value_prefix: Bearer # Optional
```

## Authorization

| Environment Variable                | YAML                                | Required               | Description                                                                                                                                                                                                                          | Default Value |
| ----------------------------------- | ----------------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- |
| REQUIRE\_AUTHENTICATION             | require\_authentication             | <Icon icon="square" /> | Set to true to disallow unauthenticated requests                                                                                                                                                                                     | false         |
| REJECT\_OPERATION\_IF\_UNAUTHORIZED | reject\_operation\_if\_unauthorized | <Icon icon="square" /> | If enabled, the Router will return 401 with no response data when the evaluation of field-based permissions ([@authenticated](/federation/directives/authenticated)or [@requiresScopes](/federation/directives/requiresscopes)fails) | false         |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

authorization:
  require_authentication: false
  reject_operation_if_unauthorized: false
```

## CDN

| Environment Variable | YAML        | Required                                      | Description                                                                                                         | Default Value                                                          |
| -------------------- | ----------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| CDN\_URL             | url         | <Icon icon="square-check" iconType="solid" /> | The URL of the CDN where the Router will fetch its Config. Not required when a static execution config is provided. | [https://cosmo-cdn.wundergraph.com](https://cosmo-cdn.wundergraph.com) |
| CDN\_CACHE\_SIZE     | cache\_size | <Icon icon="square" />                        | Cosmo Router caches responses from the CDN in memory, this defines the cache size.                                  | 100MB                                                                  |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

cdn:
  url: https://cosmo-cdn.wundergraph.com
  cache_size: 100MB
```

## Events

The Events section lets you define Event Sources for [Cosmo Streams / EDFS](/router/cosmo-streams).

We support NATS, Kafka and Redis as event bus provider.

```yaml config.yaml theme={"system"}
version: "1"

events:
  providers:
    nats:
      - id: default
        url: "nats://localhost:4222"
        authentication:
          token: "token" # or
          user_info:
            username: "username"
            password: "password"
        tls:
          ca_file: /path/to/ca.crt
          cert_file: /path/to/client.crt
          key_file: /path/to/client.key
    kafka:
      - id: my-kafka
        tls:
          enabled: true
        authentication:
          sasl_plain:
            password: "password"
            username: "username"
        brokers:
          - "localhost:9092"
    redis:
      - id: my-redis
        urls:
          - "localhost:9092"
```

### Provider

| Environment Variable | YAML      | Required                                      | Description                | Default Value |
| -------------------- | --------- | --------------------------------------------- | -------------------------- | ------------- |
|                      | providers | <Icon icon="square-check" iconType="solid" /> | one of: nats, kafka, redis |               |

### NATS Provider

| Environment Variable | YAML                                 | Required                                      | Description                                                                                                                  | Default Value |
| -------------------- | ------------------------------------ | --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------- |
|                      | id                                   | <Icon icon="square-check" iconType="solid" /> | The ID of the provider. This have to match with the ID specified in the subgraph schema.                                     |               |
|                      | url                                  | <Icon icon="square-check" iconType="solid" /> | NATS Connection string                                                                                                       |               |
|                      | authentication                       | <Icon icon="square" />                        | Authentication configuration for the NATS provider.                                                                          |               |
|                      | authentication.token                 | <Icon icon="square" />                        | Token based authentication.                                                                                                  |               |
|                      | authentication.user\_info            | <Icon icon="square" />                        | User-Info based authentication.                                                                                              |               |
|                      | authentication.user\_info.username   | <Icon icon="square" />                        | Username.                                                                                                                    |               |
|                      | authentication.user\_info.password   | <Icon icon="square" />                        | Password.                                                                                                                    |               |
|                      | tls                                  | <Icon icon="square" />                        | TLS configuration for the NATS provider.                                                                                     |               |
|                      | tls.insecure\_skip\_ca\_verification | <Icon icon="square" />                        | Skip server certificate verification. Not recommended for production.                                                        | false         |
|                      | tls.ca\_file                         | <Icon icon="square" />                        | Path to a custom CA certificate file (PEM) used to verify the server certificate. Defaults to the host's system trust store. |               |
|                      | tls.cert\_file                       | <Icon icon="square" />                        | Path to the client certificate file (PEM) for mTLS. Must be set together with `key_file`.                                    |               |
|                      | tls.key\_file                        | <Icon icon="square" />                        | Path to the client private key file (PEM) for mTLS. Must be set together with `cert_file`.                                   |               |

#### TLS

The NATS provider supports four TLS modes:

| Mode                 | Config                                             |
| -------------------- | -------------------------------------------------- |
| No TLS               | Omit the `tls` block                               |
| TLS with skip verify | `insecure_skip_ca_verification: true`              |
| TLS with custom CA   | `ca_file: /path/to/ca.crt`                         |
| Mutual TLS (mTLS)    | `cert_file` + `key_file` (plus optional `ca_file`) |

<CodeGroup>
  ```yaml Skip verify (dev/self-signed) theme={"system"}
  events:
    providers:
      nats:
        - id: my-nats
          url: "nats://localhost:4222"
          tls:
            insecure_skip_ca_verification: true
  ```

  ```yaml Custom CA (1-way TLS) theme={"system"}
  events:
    providers:
      nats:
        - id: my-nats
          url: "nats://localhost:4222"
          tls:
            ca_file: /path/to/ca.crt
  ```

  ```yaml Mutual TLS (mTLS) theme={"system"}
  events:
    providers:
      nats:
        - id: my-nats
          url: "nats://localhost:4222"
          tls:
            ca_file: /path/to/ca.crt
            cert_file: /path/to/client.crt
            key_file: /path/to/client.key
  ```
</CodeGroup>

<Warning>
  `insecure_skip_ca_verification: true` disables server certificate verification. Do not use in production.
</Warning>

### Kafka Provider

| Environment Variable | YAML                                 | Required                                      | Description                                                                                          | Default Value |
| -------------------- | ------------------------------------ | --------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ------------- |
|                      | id                                   | <Icon icon="square-check" iconType="solid" /> | The ID of the provider. This have to match with the ID specified in the subgraph schema.             | \[]           |
|                      | brokers                              | <Icon icon="square-check" iconType="solid" /> | A list of broker URLs.                                                                               |               |
|                      | authentication                       | <Icon icon="square" />                        | Authentication settings                                                                              |               |
|                      | authentication.sasl\_plain           | <Icon icon="square" />                        | SASL/Plain Authentication method                                                                     |               |
|                      | authentication.sasl\_plain.username  | <Icon icon="square" />                        | SASL/Plain Username                                                                                  |               |
|                      | authentication.sasl\_plain.password  | <Icon icon="square" />                        | SASL/Plain Password                                                                                  |               |
|                      | authentication.sasl\_scram           | <Icon icon="square" />                        | SASL/SCRAM Authentication method                                                                     |               |
|                      | authentication.sasl\_scram.username  | <Icon icon="square" />                        | SASL/SCRAM Username                                                                                  |               |
|                      | authentication.sasl\_scram.password  | <Icon icon="square" />                        | SASL/SCRAM Password                                                                                  |               |
|                      | authentication.sasl\_scram.mechanism | <Icon icon="square" />                        | SASL/SCRAM Mechanism, could be `SCRAM-SHA-256` of `SCRAM-SHA-512`                                    |               |
|                      | tls                                  | <Icon icon="square" />                        | TLS configuration for the Kafka provider. If enabled, it uses SystemCertPool for RootCAs by default. |               |
|                      | tls.enabled                          | <Icon icon="square" />                        | Enable the TLS.                                                                                      |               |

### Redis Provider

| Environment Variable | YAML | Required | Description                                                                              | Default Value |
| :------------------- | :--- | :------- | :--------------------------------------------------------------------------------------- | :------------ |
|                      | id   |          | The ID of the provider. This have to match with the ID specified in the subgraph schema. | \[]           |
|                      | urls |          | A list of redis instances URLS, e.g: `redis://localhost:6379/2`                          |               |

### Cosmo Streams handlers

Configuration for Cosmo Streams handlers. Learn more about [Custom Modules for Cosmo Streams](/router/cosmo-streams/custom-modules).

| Environment Variable | YAML                                                   | Required               | Description                                                                            | Default Value |
| :------------------- | :----------------------------------------------------- | :--------------------- | :------------------------------------------------------------------------------------- | :------------ |
|                      | handlers.on\_receive\_events.handler\_timeout          | <Icon icon="square" /> | The maximum time to wait for all OnReceiveEvents handlers to complete per event-batch. | 5s            |
|                      | handlers.on\_receive\_events.max\_concurrent\_handlers | <Icon icon="square" /> | The maximum number of concurrent OnReceiveEvents handlers per trigger.                 | 100           |

## Router Engine Configuration

Configure the GraphQL Execution Engine of the Router.

| Environment Variable                                                       | YAML                                                               | Required               | Description                                                                                                                                                                                                                                                                                                                                 | Default Value |
| -------------------------------------------------------------------------- | ------------------------------------------------------------------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| ENGINE\_ENABLE\_SINGLE\_FLIGHT                                             | enable\_single\_flight                                             | <Icon icon="square" /> | Deduplicate exactly the same in-flight origin request                                                                                                                                                                                                                                                                                       | true          |
| ENGINE\_ENABLE\_REQUEST\_TRACING                                           | enable\_request\_tracing                                           | <Icon icon="square" /> | Enable [Advanced Request Tracing (ART)](/router/advanced-request-tracing-art)This config is not correlated to OTEL tracing.                                                                                                                                                                                                                 | true          |
| ENGINE\_ENABLE\_EXECUTION\_PLAN\_CACHE\_RESPONSE\_HEADER                   | enable\_execution\_plan\_cache\_response\_header                   | <Icon icon="square" /> | **Deprecated**, use ["enable\_cache\_response\_headers"](/router/configuration#debug-configuration) instead. When enabled, the Router sets the response Header "X-WG-Execution-Plan-Cache" to "HIT" or "MISS"                                                                                                                               | false         |
| ENGINE\_MAX\_CONCURRENT\_RESOLVERS                                         | max\_concurrent\_resolvers                                         | <Icon icon="square" /> | Use this to limit the concurrency in the GraphQL Engine. A high number will lead to more memory usage. A number too low will slow down your Router.                                                                                                                                                                                         | 32            |
| ENGINE\_ENABLE\_NET\_POLL                                                  | enable\_net\_poll                                                  | <Icon icon="square" /> | Enables the more efficient poll implementation for the server-side WebSocket handler of the router. This is only available on Linux and MacOS. On Windows or when the host system is limited, the default synchronous implementation is used. Has no effect on the router's upstream connections to subgraphs.                              | true          |
| ENGINE\_WEBSOCKET\_SERVER\_READ\_TIMEOUT                                   | websocket\_server\_read\_timeout                                   | <Icon icon="square" /> | Read timeout on the server-side WebSocket handler (router accepting clients). Specified as a Go duration string, e.g. `10ms`, `1s`, `1m`.                                                                                                                                                                                                   | 5s            |
| ENGINE\_WEBSOCKET\_SERVER\_WRITE\_TIMEOUT                                  | websocket\_server\_write\_timeout                                  | <Icon icon="square" /> | Write timeout on the server-side WebSocket handler (router accepting clients).                                                                                                                                                                                                                                                              | 10s           |
| ENGINE\_WEBSOCKET\_SERVER\_POLL\_TIMEOUT                                   | websocket\_server\_poll\_timeout                                   | <Icon icon="square" /> | The timeout for the poll loop of the server-side WebSocket handler. The period is specified as a string with a number and a unit.                                                                                                                                                                                                           | 1s            |
| ENGINE\_WEBSOCKET\_SERVER\_CONN\_BUFFER\_SIZE                              | websocket\_server\_conn\_buffer\_size                              | <Icon icon="square" /> | The buffer size for the poll buffer of the server-side WebSocket handler. The buffer size determines how many connections can be handled in one loop.                                                                                                                                                                                       | 128           |
| ENGINE\_WEBSOCKET\_CLIENT\_WRITE\_TIMEOUT                                  | websocket\_client\_write\_timeout                                  | <Icon icon="square" /> | The timeout for the websocket write of the WebSocket client implementation.                                                                                                                                                                                                                                                                 | 10s           |
| ENGINE\_WEBSOCKET\_CLIENT\_PING\_INTERVAL                                  | websocket\_client\_ping\_interval                                  | <Icon icon="square" /> | The Websocket client ping interval to the subgraph. Defines how often the router will ping the subgraph to signal that the connection is still alive. Timeout needs to be coordinated with the subgraph. The timeout is specified as a string with a number and a unit, e.g. 10ms, 1s, 1m, 1h. The supported units are 'ms', 's', 'm', 'h'. | 15s           |
| ENGINE\_WEBSOCKET\_CLIENT\_PING\_TIMEOUT                                   | websocket\_client\_ping\_timeout                                   | <Icon icon="square" /> | The Websocket client ping timeout to the subgraph. Defines how long the router will wait for a ping response from the subgraph. The timeout is specified as a string with a number and a unit, e.g. 10ms, 1s, 1m, 1h. The supported units are 'ms', 's', 'm', 'h'.                                                                          | 30s           |
| ENGINE\_WEBSOCKET\_CLIENT\_ACK\_TIMEOUT                                    | websocket\_client\_ack\_timeout                                    | <Icon icon="square" /> | How long the router waits for a `connection_ack` from a subgraph after sending `connection_init`. Minimum `1s`.                                                                                                                                                                                                                             | 30s           |
| ENGINE\_WEBSOCKET\_CLIENT\_READ\_LIMIT                                     | websocket\_client\_read\_limit                                     | <Icon icon="square" /> | Maximum size of an incoming WebSocket message from a subgraph. Specified as a byte string, e.g. `512KB`, `1MB`. Minimum `1KB`.                                                                                                                                                                                                              | 1MB           |
| ENGINE\_EXECUTION\_PLAN\_CACHE\_SIZE                                       | execution\_plan\_cache\_size                                       | <Icon icon="square" /> | Define how many GraphQL Operations should be stored in the execution plan cache. A low number will lead to more frequent cache misses, which will lead to increased latency.                                                                                                                                                                | 1024          |
| ENGINE\_SLOW\_PLAN\_CACHE\_SIZE                                            | slow\_plan\_cache\_size                                            | <Icon icon="square" /> | The maximum number of entries in the slow plan cache. This cache protects slow-to-plan queries from being evicted by the main plan cache's LFU policy. Only used when `in_memory_fallback` is enabled. See [Slow Plan Cache](/concepts/cache-warmer#slow-plan-cache).                                                                       | 300           |
| ENGINE\_SLOW\_PLAN\_CACHE\_THRESHOLD                                       | slow\_plan\_cache\_threshold                                       | <Icon icon="square" /> | The minimum planning duration for a query to be promoted into the slow plan cache. Queries that take longer than this threshold to plan are considered expensive and protected from eviction. The period is specified as a string with a number and a unit, e.g. 10ms, 1s, 5s. The supported units are 'ms', 's', 'm', 'h'.                 | 100ms         |
| ENGINE\_MINIFY\_SUBGRAPH\_OPERATIONS                                       | minify\_subgraph\_operations                                       | <Icon icon="square" /> | Minify the subgraph operations. If the value is true, GraphQL Operations get minified after planning. This reduces the amount of GraphQL AST nodes the Subgraph has to parse, which ultimately saves CPU time and memory, resulting in faster response times.                                                                               | false         |
| ENGINE\_ENABLE\_PERSISTED\_OPERATIONS\_CACHE                               | enable\_persisted\_operations\_cache                               | <Icon icon="square" /> | Enable the persisted operations cache. The persisted operations cache is used to cache normalized persisted operations to improve performance.                                                                                                                                                                                              | true          |
| ENGINE\_ENABLE\_NORMALIZATION\_CACHE                                       | enable\_normalization\_cache                                       | <Icon icon="square" /> | Enable the normalization cache. The normalization cache is used to cache normalized operations to improve performance.                                                                                                                                                                                                                      | true          |
| ENGINE\_NORMALIZATION\_CACHE\_SIZE                                         | normalization\_cache\_size                                         | <Icon icon="square" /> | The size of the normalization cache.                                                                                                                                                                                                                                                                                                        | 1024          |
| ENGINE\_PARSEKIT\_POOL\_SIZE                                               | parsekit\_pool\_size                                               | <Icon icon="square" /> | The size of the ParseKit pool. The ParseKit pool provides re-usable Resources for parsing, normalizing, validating and planning GraphQL Operations. Setting the pool size to a value much higher than the number of CPU Threads available will not improve performance, but only increase memory usage.                                     | 8             |
| ENGINE\_RESOLVER\_MAX\_RECYCLABLE\_PARSER\_SIZE                            | resolver\_max\_recyclable\_parser\_size                            | <Icon icon="square" /> | Limits the size of the Parser that can be recycled back into the Pool. If set to 0, no limit is applied. This helps keep the Heap size more maintainable if you regularly perform large queries.                                                                                                                                            | 32768         |
| ENGINE\_ENABLE\_VALIDATION\_CACHE                                          | enable\_validation\_cache                                          | <Icon icon="square" /> | Enable the validation cache. The validation cache is used to cache results of validating GraphQL Operations.                                                                                                                                                                                                                                | true          |
| ENGINE\_VALIDATION\_CACHE\_SIZE                                            | validation\_cache\_size                                            | <Icon icon="square" /> | The size of the validation cache.                                                                                                                                                                                                                                                                                                           | 1024          |
| ENGINE\_DISABLE\_EXPOSING\_VARIABLES\_CONTENT\_ON\_VALIDATION\_ERROR       | disable\_exposing\_variables\_content\_on\_validation\_error       | <Icon icon="square" /> | Disables exposing the variables content in the error response. This is useful to avoid leaking sensitive information in the error response.                                                                                                                                                                                                 | false         |
| ENGINE\_ENABLE\_SUBGRAPH\_FETCH\_OPERATION\_NAME                           | enable\_subgraph\_fetch\_operation\_name                           | <Icon icon="square" /> | Enable appending the operation name to subgraph fetches. This will ensure that the operation name will be included in the corresponding subgraph requests using the following format: `$OperationName__$SubgraphName__$FetchID`.                                                                                                            | false         |
| ENGINE\_ENABLE\_REQUIRE\_FETCH\_REASONS                                    | enable\_require\_fetch\_reasons                                    | <Icon icon="square" /> | Enable the openfed\_\_requireFetchReasons directive, and forces the adding of the "fetch\_reasons" extension to upstream subgraph requests. This extension explains why each field was requested.                                                                                                                                           | false         |
| ENGINE\_VALIDATE\_REQUIRED\_EXTERNAL\_FIELDS                               | validate\_required\_external\_fields                               | <Icon icon="square" /> | Validate nullable external "@requires" dependencies. When a subgraph entity fetch returns a null value with an error for a field set specified in the "@requires" directive, any following fetch that depends on it should not receive such an entity.                                                                                      | false         |
| ENGINE\_SUBSCRIPTION\_FETCH\_TIMEOUT                                       | subscription\_fetch\_timeout                                       | <Icon icon="square" /> | The maximum time a subscription fetch can take before it is considered timed out.                                                                                                                                                                                                                                                           | 30s           |
| ENGINE\_ENABLE\_DEFER                                                      | enable\_defer                                                      | <Icon icon="square" /> | Enables support for the `@defer` directive, allowing clients to defer parts of a query so that the initial response is returned faster and deferred fields are streamed incrementally.                                                                                                                                                      | false         |
| ENGINE\_RELAX\_SUBGRAPH\_OPERATION\_FIELD\_SELECTION\_MERGING\_NULLABILITY | relax\_subgraph\_operation\_field\_selection\_merging\_nullability | <Icon icon="square" /> | Relaxes nullability validation for [field selection merging](/router/relaxed-field-selection-merging-nullability) across union member types.                                                                                                                                                                                                | false         |

<Warning>
  **Subject to change.** `enable_net_poll`, `websocket_server_poll_timeout`, and `websocket_server_conn_buffer_size` may be removed or changed in a future release without a standard deprecation cycle. Avoid depending on them.
</Warning>

<Note>
  If you're upgrading from a previous release and set `websocket_client_read_timeout`, `websocket_client_poll_timeout`, `websocket_client_conn_buffer_size`, `websocket_client_frame_timeout`, or `websocket_client_write_timeout`, see the [subscriptions overhaul migration guide](/router/subscriptions-migration). Several of these were removed and one (`websocket_client_write_timeout`) kept its name but changed scope.
</Note>

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

engine:
  enable_single_flight: true
  enable_request_tracing: true
  max_concurrent_resolvers: 32
  enable_websocket_epoll_kqueue: true
  epoll_kqueue_poll_timeout: "1s"
  epoll_kqueue_conn_buffer_size: 128
  # Server-side WebSocket handler (router accepting clients)
  websocket_server_read_timeout: "5s"
  websocket_server_write_timeout: "10s"
  websocket_server_poll_timeout: "1s"
  websocket_server_conn_buffer_size: 128
  # Upstream subscription client (router connecting to subgraphs)
  websocket_client_write_timeout: "10s"
  websocket_client_ping_interval: "15s"
  websocket_client_ping_timeout: "30s"
  websocket_client_ack_timeout: "30s"
  websocket_client_read_limit: "1MB"
  execution_plan_cache_size: 10000
  slow_plan_cache_size: 300
  slow_plan_cache_threshold: 100ms
  minify_subgraph_operations: true
  enable_persisted_operations_cache: true
  enable_normalization_cache: true
  normalization_cache_size: 1024
  parsekit_pool_size: 8
  enable_validation_cache: true
  validation_cache_size: 1024
  disable_exposing_variables_content_on_validation_error: false
  enable_subgraph_fetch_operation_name: true
  subscription_fetch_timeout: 30s
  relax_subgraph_operation_field_selection_merging_nullability: false
```

### Debug Configuration

| Environment Variable                                                  | YAML                                                   | Required               | Description                                                                                                                                                                                                                                                                                        | Default Value |
| --------------------------------------------------------------------- | ------------------------------------------------------ | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| ENGINE\_DEBUG\_PRINT\_OPERATION\_TRANSFORMATIONS                      | print\_operation\_transformations                      | <Icon icon="square" /> | Print the operation transformations.                                                                                                                                                                                                                                                               | false         |
| ENGINE\_DEBUG\_PRINT\_OPERATION\_ENABLE\_AST\_REFS                    | print\_operation\_enable\_ast\_refs                    | <Icon icon="square" /> | Print the operation enable AST refs.                                                                                                                                                                                                                                                               | false         |
| ENGINE\_DEBUG\_PRINT\_PLANNING\_PATHS                                 | print\_planning\_paths                                 | <Icon icon="square" /> | Print the planning paths.                                                                                                                                                                                                                                                                          | false         |
| ENGINE\_DEBUG\_PRINT\_QUERY\_PLANS                                    | print\_query\_plans                                    | <Icon icon="square" /> | Print the query plans.                                                                                                                                                                                                                                                                             | false         |
| ENGINE\_DEBUG\_PRINT\_NODE\_SUGGESTIONS                               | print\_node\_suggestions                               | <Icon icon="square" /> | Print the node suggestions.                                                                                                                                                                                                                                                                        | false         |
| ENGINE\_DEBUG\_CONFIGURATION\_VISITOR                                 | configuration\_visitor                                 | <Icon icon="square" /> | Print the configuration visitor.                                                                                                                                                                                                                                                                   | false         |
| ENGINE\_DEBUG\_PLANNING\_VISITOR                                      | planning\_visitor                                      | <Icon icon="square" /> | Print the planning visitor.                                                                                                                                                                                                                                                                        | false         |
| ENGINE\_DEBUG\_DATASOURCE\_VISITOR                                    | datasource\_visitor                                    | <Icon icon="square" /> | Print the datasource visitor.                                                                                                                                                                                                                                                                      | false         |
| ENGINE\_DEBUG\_REPORT\_WEBSOCKET\_CONNECTIONS                         | report\_websocket\_connections                         | <Icon icon="square" /> | Print the websocket connections.                                                                                                                                                                                                                                                                   | false         |
| ENGINE\_DEBUG\_REPORT\_MEMORY\_USAGE                                  | report\_memory\_usage                                  | <Icon icon="square" /> | Print the memory usage.                                                                                                                                                                                                                                                                            | false         |
| ENGINE\_DEBUG\_ENABLE\_RESOLVER\_DEBUGGING                            | enable\_resolver\_debugging                            | <Icon icon="square" /> | Enable verbose debug logging for the Resolver.                                                                                                                                                                                                                                                     | false         |
| ENGINE\_DEBUG\_ENABLE\_CACHE\_RESPONSE\_HEADERS                       | enable\_cache\_response\_headers                       | <Icon icon="square" /> | Enable hit/miss response headers for the normalization caches ("X-WG-Normalization-Cache", "X-WG-Variables-Normalization-Cache", "X-WG-Variables-Remapping-Cache"), the persisted operations cache ("X-WG-Persisted-Operation-Cache"), and the execution plan cache ("X-WG-Execution-Plan-Cache"). | false         |
| ENGINE\_DEBUG\_ENABLE\_PERSISTED\_OPERATIONS\_CACHE\_RESPONSE\_HEADER | enable\_persisted\_operations\_cache\_response\_header | <Icon icon="square" /> | **Deprecated**, use "enable\_cache\_response\_headers" instead. Enable the persisted operations cache response header. The persisted operations cache response header is used to cache the persisted operations in the client.                                                                     | false         |
| ENGINE\_DEBUG\_ENABLE\_NORMALIZATION\_CACHE\_RESPONSE\_HEADER         | enable\_normalization\_cache\_response\_header         | <Icon icon="square" /> | **Deprecated**, use "enable\_cache\_response\_headers" instead. Enable the normalization cache response header. The normalization cache response header is used to cache the normalized operations in the client.                                                                                  | false         |
| ENGINE\_DEBUG\_ALWAYS\_INCLUDE\_QUERY\_PLAN                           | always\_include\_query\_plan                           | <Icon icon="square" /> | Always include the query plan in the response.                                                                                                                                                                                                                                                     | false         |
| ENGINE\_DEBUG\_ALWAYS\_SKIP\_LOADER                                   | always\_skip\_loader                                   | <Icon icon="square" /> | Always skip the loader. This will return no data but only render response extensions, e.g. to expose the query plan.                                                                                                                                                                               | false         |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

engine:
  debug:
    print_operation_transformations: false
    print_operation_enable_ast_refs: false
    print_planning_paths: false
    print_query_plans: false
    print_node_suggestions: false
    configuration_visitor: false
    planning_visitor: false
    datasource_visitor: false
    report_websocket_connections: false
    report_memory_usage: false
    enable_resolver_debugging: false
    enable_persisted_operations_cache_response_header: false
    enable_normalization_cache_response_header: false
    always_include_query_plan: false
    always_skip_loader: false
```

## Rate Limiting

Configures a rate limiter on the outgoing subgraphs requests. When enabled, a rate of 10 req/s with a burst of 10 requests is configured.

<Info>
  The rate limiter requires Redis version 3.2 or newer since it relies on
  [replicate\_commands](https://redis.io/commands/eval#replicating-commands-instead-of-scripts)
  feature. ElastiCache for Redis only works in non-clustered mode. You can
  enable a failover instance to achieve high availability.
</Info>

### Key Suffix Expression

As you can see in the config table below, you can define an expression to generate the a rate limiting key suffix. The evaluation of the expression must return a string, which will be appended to the key prefix.

Using a key suffix expression, you're able to dynamically choose a rate limiting key, e.g. based on the user authentication, a header, or a combination. Here's an example expression that uses the `sub` claim if available, and a Header as the fallback.

```bash theme={"system"}
request.auth.claims.sub ?? request.header.Get('X-Forwarded-For')
```

For mor information on how to use the expression language, please refer to the [Template Expressions](/router/configuration/template-expressions) section.

### General Rate Limiting Configuration

| Environment Variable                                                                     | YAML                    | Required                                      | Description                                                                                                                                                                                                                                                                                                      | Default Value |
| ---------------------------------------------------------------------------------------- | ----------------------- | --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| RATE\_LIMIT\_ENABLED                                                                     | enabled                 | <Icon icon="square" />                        | Enable / Disable rate limiting globally                                                                                                                                                                                                                                                                          | false         |
| RATE\_LIMIT\_STRATEGY                                                                    | strategy                | <Icon icon="square-check" iconType="solid" /> | The rate limit strategy to use                                                                                                                                                                                                                                                                                   | simple        |
|                                                                                          | simple\_strategy        | <Icon icon="square" />                        | \[                                                                                                                                                                                                                                                                                                               |               |
| Rate Limiting Simple Strategy]\(/router/configuration#rate-limiting-simple-strategy)     | simple                  |                                               |                                                                                                                                                                                                                                                                                                                  |               |
|                                                                                          | storage                 | <Icon icon="square" />                        | [Rate Limiting Redis Storage](/router/configuration#rate-limiting-redis-storage)                                                                                                                                                                                                                                 |               |
| RATE\_LIMIT\_KEY\_SUFFIX\_EXPRESSION                                                     | key\_suffix\_expression | <Icon icon="square" />                        | The expression to define a key suffix for the rate limit, e.g. by using request headers, claims, or a combination of both with a fallback strategy. The expression is specified as a string and needs to evaluate to a string. Please see [https://expr-lang.org/](https://expr-lang.org/) for more information. |               |
|                                                                                          | error\_extension\_code  | <Icon icon="square" />                        |                                                                                                                                                                                                                                                                                                                  |               |
| [Rate Limit Error Extension Code](/router/configuration#rate-limit-error-extension-code) |                         |                                               |                                                                                                                                                                                                                                                                                                                  |               |

### Rate Limiting Redis Storage

| Environment Variable                 | YAML             | Required                                      | Description                                         | Default Value              |
| ------------------------------------ | ---------------- | --------------------------------------------- | --------------------------------------------------- | -------------------------- |
| RATE\_LIMIT\_REDIS\_URLS             | urls             | <Icon icon="square-check" iconType="solid" /> | List of the connection URL(s).                      | \[redis\://localhost:6379] |
| RATE\_LIMIT\_REDIS\_CLUSTER\_ENABLED | cluster\_enabled | <Icon icon="square" />                        | If the Redis instance is a Redis cluster            | false                      |
| RATE\_LIMIT\_REDIS\_KEY\_PREFIX      | key\_prefix      | <Icon icon="square" />                        | This prefix is used to namespace the ratelimit keys | cosmo\_rate\_limit         |

### Rate Limiting Simple Strategy

| Environment Variable                                        | YAML                                   | Required                                      | Description                                                                                                                                                                     | Default Value |
| ----------------------------------------------------------- | -------------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| RATE\_LIMIT\_SIMPLE\_RATE                                   | rate                                   | <Icon icon="square-check" iconType="solid" /> | Allowed request rate (number)                                                                                                                                                   | 10            |
| RATE\_LIMIT\_SIMPLE\_BURST                                  | burst                                  | <Icon icon="square-check" iconType="solid" /> | Allowed burst rate (number) - max rate per one request                                                                                                                          | 10            |
| RATE\_LIMIT\_SIMPLE\_PERIOD                                 | period                                 | <Icon icon="square-check" iconType="solid" /> | The rate limiting period, e.g. "10s", "1m", etc...                                                                                                                              | 1s            |
| RATE\_LIMIT\_SIMPLE\_REJECT\_EXCEEDING\_REQUESTS            | reject\_exceeding\_requests            | <Icon icon="square" />                        | Reject the complete request if a sub-request exceeds the rate limit. If set to false, partial responses are possible.                                                           | false         |
| RATE\_LIMIT\_SIMPLE\_HIDE\_STATS\_FROM\_RESPONSE\_EXTENSION | hide\_stats\_from\_response\_extension | <Icon icon="square" />                        | Hide the rate limit stats from the response extension. If the value is true, the rate limit stats are not included in the response extension.                                   | false         |
|                                                             | overrides                              | <Icon icon="square" />                        | List of per-key rate limit overrides. The first matching override wins; unmatched keys use the global defaults. See [example below](#rate-limiting-example-yaml-configuration). |               |
|                                                             | overrides.matching                     | <Icon icon="square-check" iconType="solid" /> | Go regex pattern matched against the suffix portion of the rate-limit key (the result of `key_suffix_expression`), not the full prefixed Redis key.                             |               |
|                                                             | overrides.rate                         | <Icon icon="square-check" iconType="solid" /> | Allowed request rate for matching keys.                                                                                                                                         |               |
|                                                             | overrides.burst                        | <Icon icon="square-check" iconType="solid" /> | Allowed burst rate for matching keys.                                                                                                                                           |               |
|                                                             | overrides.period                       | <Icon icon="square-check" iconType="solid" /> | Rate limiting period for matching keys, e.g. "10s", "1m".                                                                                                                       |               |

### Rate Limit Error Extension Code

| Environment Variable                         | YAML    | Required               | Description                                                                                                                                                                                | Default Value         |
| -------------------------------------------- | ------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------- |
| RATE\_LIMIT\_ERROR\_EXTENSION\_CODE\_ENABLED | enabled | <Icon icon="square" /> | If enabled, a code will be added to the extensions.code field of error objects related to rate limiting. This allows clients to easily identify if an error happened due to rate limiting. | true                  |
| RATE\_LIMIT\_ERROR\_EXTENSION\_CODE          | code    | <Icon icon="square" /> | The code to add to the extensions.code field of error objects related to rate limiting.                                                                                                    | RATE\_LIMIT\_EXCEEDED |

### Rate Limiting Example YAML configuration

```yaml config.yaml theme={"system"}
rate_limit:
    enabled: true
    strategy: "simple"
    simple_strategy:
        rate: 10
        burst: 10
        period: 1s
        reject_exceeding_requests: false
        reject_status_code: 200
        hide_stats_from_response_extension: false
        overrides:
            - matching: "^premium-.*"
              rate: 100
              burst: 200
              period: 1s
    storage:
        cluster_enabled: false
        urls:
         - "redis://localhost:6379"
        key_prefix: "cosmo_rate_limit"
    debug: false
    key_suffix_expression: "request.header.Get('X-Api-Key')"
    error_extension_code:
        enabled: true
        code: "RATE_LIMIT_EXCEEDED"
```

## Subgraph Data Propagation

Controls what subgraphs can propagate back to the client. Errors and the response `extensions` object are governed by separate but related policies.

### Subgraph Error Propagation

The configuration for the subgraph error propagation. Errors can be exposed to the client in a "wrapped" form to hide Subgraph internals, or it's possible to "pass-through" Subgraph errors directly to the client.

| Environment Variable                                        | YAML                          | Required               | Description                                                                                                                                                                                                                                      | Default Value              |
| ----------------------------------------------------------- | ----------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------- |
| SUBGRAPH\_ERROR\_PROPAGATION\_ENABLED                       | enabled                       | <Icon icon="square" /> | Enable error propagation. If the value is true (default: false), Subgraph errors will be propagated to the client.                                                                                                                               | false                      |
| SUBGRAPH\_ERROR\_PROPAGATION\_MODE                          | mode                          | <Icon icon="square" /> | The mode of error propagation. The supported modes are 'wrapped' (default) and 'pass-through'. The 'wrapped' mode wraps the error in a custom error object to hide internals. The 'pass-through' mode returns the error as is from the Subgraph. | wrapped                    |
| SUBGRAPH\_ERROR\_PROPAGATION\_REWRITE\_PATHS                | rewrite\_paths                | <Icon icon="square" /> | Rewrite the paths of the Subgraph errors. If the value is true (default), the paths of the Subgraph errors will be rewritten to match the Schema of the Federated Graph.                                                                         | true                       |
| SUBGRAPH\_ERROR\_PROPAGATION\_OMIT\_LOCATIONS               | omit\_locations               | <Icon icon="square" /> | Omit the location field of Subgraph errors. If the value is true, the location field of Subgraph errors will be omitted.                                                                                                                         | true                       |
| SUBGRAPH\_ERROR\_PROPAGATION\_OMIT\_EXTENSIONS              | omit\_extensions              | <Icon icon="square" /> | Omit the extensions field of Subgraph errors. If the value is true, the extensions field of Subgraph errors will be omitted.                                                                                                                     | false                      |
| SUBGRAPH\_ERROR\_PROPAGATION\_STATUS\_CODES                 | propagate\_status\_codes      | <Icon icon="square" /> | Propagate Subgraph status codes. If the value is true, Subgraph Response status codes will be propagated to the client in the errors.extensions.code field.                                                                                      | false                      |
| SUBGRAPH\_ERROR\_PROPAGATION\_ALLOWED\_FIELDS               | allowed\_fields               | <Icon icon="square" /> | In passthrough mode, by default only message and path is propagated. You can specify additional fields here.                                                                                                                                     |                            |
| SUBGRAPH\_ERROR\_PROPAGATION\_DEFAULT\_EXTENSION\_CODE      | default\_extension\_code      | <Icon icon="square" /> | The default extension code. The default extension code is used to specify the default code for the Subgraph errors when the code is not present.                                                                                                 | DOWNSTREAM\_SERVICE\_ERROR |
| SUBGRAPH\_ERROR\_PROPAGATION\_ATTACH\_SERVICE\_NAME         | attach\_service\_name         | <Icon icon="square" /> | Attach the service name to each Subgraph error. If the value is true, the service name will be attached to the Subgraph errors.                                                                                                                  | true                       |
| SUBGRAPH\_ERROR\_PROPAGATION\_ALLOWED\_EXTENSION\_FIELDS    | allowed\_extension\_fields    | <Icon icon="square" /> | The allowed extension fields. The allowed extension fields are used to specify which fields of the Subgraph errors are allowed to be propagated to the client.                                                                                   | \["code"]                  |
| SUBGRAPH\_ERROR\_PROPAGATION\_ALLOW\_ALL\_EXTENSION\_FIELDS | allow\_all\_extension\_fields | <Icon icon="square" /> | Allow all extension fields from Subgraph errors to be propagated to the client. If the value is true (default: false), all extension fields from Subgraph errors will be propagated, overriding the allowed\_extension\_fields configuration.    | false                      |

#### Example YAML configuration:

```yaml theme={"system"}
version: "1"

subgraph_error_propagation:
  enabled: true
  propagate_status_codes: false
  mode: "wrapped"
  rewrite_paths: true
  omit_locations: true
  omit_extensions: false # If true, overrides allowed_extension_fields and allow_all_extension_fields
  default_extension_code: DOWNSTREAM_SERVICE_ERROR
  attach_service_name: true
  allow_all_extension_fields: false # If true, overrides allowed_extension_fields
  allowed_extension_fields:
    - "code"
```

See [Subgraph Error Propagation](/router/subgraph-data-propagation/subgraph-error-propagation) for more detailed information.

### Subgraph Extension Propagation

The router forwards subgraph response `extensions` to the client. An allow list restricts which extension fields are propagated, and an algorithm selects a winner when multiple subgraphs return the same field.

| Environment Variable                                         | YAML                       | Required               | Description                                                                                                                                                                    | Default Value |
| ------------------------------------------------------------ | -------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- |
| SUBGRAPH\_EXTENSION\_PROPAGATION\_ENABLED                    | enabled                    | <Icon icon="square" /> | Enable forwarding of subgraph response extensions to the client.                                                                                                               | false         |
| SUBGRAPH\_EXTENSION\_PROPAGATION\_ALLOWED\_EXTENSION\_FIELDS | allowed\_extension\_fields | <Icon icon="square" /> | Extension fields that are allowed to be propagated from subgraphs to the client. Any field not in this list is dropped. If empty, all extension fields are forwarded.          | \[]           |
| SUBGRAPH\_EXTENSION\_PROPAGATION\_ALGORITHM                  | algorithm                  | <Icon icon="square" /> | Conflict resolution when multiple subgraphs return the same extension field. `first_write` keeps the value from the first subgraph that wrote it; `last_write` keeps the last. | first\_write  |

#### Example YAML configuration:

```yaml theme={"system"}
version: "1"

subgraph_extension_propagation:
  enabled: true
  allowed_extension_fields:
    - rateLimit
    - auth
  algorithm: last_write
```

See [Subgraph Extension Propagation](/router/subgraph-data-propagation/subgraph-extension-propagation) for more detailed information.

## Security

The configuration for the security. The security is used to configure the security settings for the Router.

| Environment Variable                                   | YAML                                        | Required               | Description                                                                                                                        | Default Value |
| ------------------------------------------------------ | ------------------------------------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| SECURITY\_BLOCK\_MUTATIONS                             | block\_mutations                            | <Icon icon="square" /> | Block mutation Operations.                                                                                                         |               |
| SECURITY\_BLOCK\_MUTATIONS\_ENABLED                    | block\_mutations.enabled                    | <Icon icon="square" /> | If the value is true, the mutations are blocked.                                                                                   | false         |
| SECURITY\_BLOCK\_MUTATIONS\_CONDITION                  | block\_mutations.condition                  | <Icon icon="square" /> | The [expression](/router/configuration/template-expressions#authentication-object) to evaluate if the operation should be blocked. |               |
| SECURITY\_BLOCK\_SUBSCRIPTIONS                         | block\_subscriptions                        | <Icon icon="square" /> | Block subscription Operations.                                                                                                     |               |
|                                                        | block\_subscriptions.enabled                | <Icon icon="square" /> | If the value is true, the subscriptions are blocked.                                                                               | false         |
|                                                        | block\_subscriptions.condition              | <Icon icon="square" /> | The [expression](/router/configuration/template-expressions) to evaluate if the operation should be blocked.                       |               |
| SECURITY\_BLOCK\_NON\_PERSISTED\_OPERATIONS            | block\_non\_persisted\_operations           | <Icon icon="square" /> | Block non-persisted Operations.                                                                                                    |               |
| SECURITY\_BLOCK\_NON\_PERSISTED\_OPERATIONS\_ENABLED   | block\_non\_persisted\_operations.enabled   | <Icon icon="square" /> | If the value is true, the non-persisted operations are blocked.                                                                    | false         |
| SECURITY\_BLOCK\_NON\_PERSISTED\_OPERATIONS\_CONDITION | block\_non\_persisted\_operations.condition | <Icon icon="square" /> | The [expression](/router/configuration/template-expressions) to evaluate if the operation should be blocked.                       |               |
| SECURITY\_BLOCK\_PERSISTED\_OPERATIONS                 | block\_persisted\_operations                | <Icon icon="square" /> | Block persisted Operations.                                                                                                        |               |
| SECURITY\_BLOCK\_PERSISTED\_OPERATIONS\_ENABLED        | block\_persisted\_operations.enabled        | <Icon icon="square" /> | If the value is true, the persisted operations are blocked.                                                                        | false         |
| SECURITY\_BLOCK\_PERSISTED\_OPERATIONS\_CONDITION      | block\_persisted\_operations.condition      | <Icon icon="square" /> | The [expression](/router/configuration/template-expressions) to evaluate if the operation should be blocked.                       |               |
|                                                        | complexity\_calculation\_cache              | <Icon icon="square" /> | Complexity Cache configuration                                                                                                     |               |
|                                                        | complexity\_limits                          | <Icon icon="square" /> | Complexity limits configuration                                                                                                    |               |
|                                                        | complexity\_limits.mode                     | <Icon icon="square" /> | `measure` calculates complexity without rejecting; `enforce` rejects operations exceeding limits.                                  | enforce       |
|                                                        | parser\_limits.approximate\_depth\_limit    | <Icon icon="square" /> | The approximate cumulative depth limit of a query, including fragments. Set to 0 to disable.                                       | 200           |
|                                                        | parser\_limits.total\_fields\_limit         | <Icon icon="square" /> | The total number of fields the parser will allow. Set to 0 to disable.                                                             | 3500          |
| SECURITY\_OPERATION\_NAME\_LENGTH\_LIMIT               | operation\_name\_length\_limit              | <Icon icon="square" /> | The maximum allowed length for the operation name. Set to 0 to disable.                                                            | 512           |

### Example YAML Configuration

```yaml theme={"system"}
version: "1"

security:
  block_mutations:
    enabled: false
    condition: "request.header.Get('x-block-mutation') == 'yes'"
  block_subscriptions:
    enabled: false
  block_non_persisted_operations:
    enabled: false
  block_persisted_operations:
    enabled: false
  complexity_calculation_cache: # This is for a local in-memory cache, to persist the calculation results
    enabled: true
    size: 1024
  complexity_limits:
    mode: enforce # 'measure' calculates complexity without rejecting; 'enforce' rejects operations exceeding limits
    depth: # the equivalent of `security.depth_limit` previously
      enabled: true
      limit: 7
      ignore_persisted_operations: true
    total_fields:
      enabled: true
      limit: 128
      ignore_persisted_operations: true
    root_fields:
      enabled: true
      limit: 3
      ignore_persisted_operations: true
    root_field_aliases:
      enabled: false
      limit: 3
      ignore_persisted_operations: true
  parser_limits:
    approximate_depth_limit: 300
    total_fields_limit: 700
  operation_name_length_limit: 1024
```

<Warning>
  Query Depth is now deprecated. We recommend using the
  `security.complexity_calculation_cache` and `security.complexity_limits`
  configurations instead, which provide that functionality.
</Warning>

### Cost Control

The configuration for [Cost Control](/router/security/cost-control) based on `@cost` and `@listSize` directives.
Calculates estimated and actual costs for GraphQL operations. It can reject expensive operations.

| Environment Variable                           | YAML                  | Required               | Description                                                                                                   | Default Value |
| ---------------------------------------------- | --------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------- | ------------- |
| SECURITY\_COST\_CONTROL\_ENABLED               | enabled               | <Icon icon="square" /> | Enable Cost Control. When true, the router calculates costs for every operation.                              | false         |
| SECURITY\_COST\_CONTROL\_MODE                  | mode                  | <Icon icon="square" /> | `measure` calculates costs without rejecting; `enforce` rejects operations exceeding the limit.               | measure       |
| SECURITY\_COST\_CONTROL\_MAX\_ESTIMATED\_LIMIT | max\_estimated\_limit | <Icon icon="square" /> | Maximum allowed estimated cost. Operations exceeding this are rejected in enforce mode. 0 means no limit.     | 0             |
| SECURITY\_COST\_CONTROL\_ESTIMATED\_LIST\_SIZE | estimated\_list\_size | <Icon icon="square" /> | Default assumed size for list fields when no `@listSize` directive is present. Must be positive when enabled. | 0             |
| SECURITY\_COST\_CONTROL\_EXPOSE\_HEADERS       | expose\_headers       | <Icon icon="square" /> | Add `X-WG-Cost-Estimated` and `X-WG-Cost-Actual` response headers.                                            | false         |

#### Example YAML Configuration

```yaml theme={"system"}
security:
  cost_control:
    enabled: true
    mode: enforce
    estimated_list_size: 10
    max_estimated_limit: 1000
    expose_headers: true
```

### Complexity Calculation Cache

The configuration for the in-memory complexity cache, to help speed up the calculation process in the event of a recurring query

| Environment Variable                 | YAML    | Required               | Description                      | Default Value |
| ------------------------------------ | ------- | ---------------------- | -------------------------------- | ------------- |
| SECURITY\_COMPLEXITY\_CACHE\_ENABLED | enabled | <Icon icon="square" /> | Enable the complexity cache      | false         |
| SECURITY\_COMPLEXITY\_CACHE\_SIZE    | size    | <Icon icon="square" /> | The size of the complexity cache | 1024          |

### Complexity Limits

The configuration for adding a complexity limits for queries. We currently expose 4 limits:

* **Query Depth** - How many nested levels you can have in a query. This limit prevents infinite querying, and also limits the size of the data returned.
* **Total Fields in Query**
* **Root Fields in Query**
* **Root Field Aliases in Query**

A limit is not applied when its value is 0 or `enabled` is not true.

The `mode` field controls enforcement versus measurement:

* `measure`: calculates complexity and reports it via telemetry but does not reject requests.
* `enforce` (default): rejects requests that exceed limits.

| Environment Variable | YAML                          | Required               | Description                                                                                                                                                                            | Default Value |
| -------------------- | ----------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
|                      | mode                          | <Icon icon="square" /> | `measure` calculates complexity without rejecting; `enforce` rejects operations exceeding limits.                                                                                      | enforce       |
|                      | enabled                       | <Icon icon="square" /> | Enable the specific limit. If the value is true (default: false), and a valid limit value is set, the limit will be applied.                                                           | false         |
|                      | limit                         | <Icon icon="square" /> | The limit amount for query. If the limit is 0, this limit is not applied.                                                                                                              | 0             |
|                      | ignore\_persisted\_operations | <Icon icon="square" /> | Disable the limit for persisted operations. Since persisted operations are stored intentionally, users may want to disable the limit to consciously allow nested persisted operations. | false         |

## File Upload

The configuration for file upload. Configure whether it should be enabled along with file size and number of files.

| Environment Variable          | YAML            | Required               | Description                                                                                                                                                                 | Default Value |
| ----------------------------- | --------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| FILE\_UPLOAD\_ENABLED         | enabled         | <Icon icon="square" /> | Whether the feature is enabled or not                                                                                                                                       | true          |
| FILE\_UPLOAD\_MAX\_FILE\_SIZE | max\_file\_size | <Icon icon="square" /> | The maximum size of a file that can be uploaded. The size is specified as a string with a number and a unit, e.g. 10KB, 1MB, 1GB. The supported units are 'KB', 'MB', 'GB'. | 50MB          |
| FILE\_UPLOAD\_MAX\_FILES      | max\_files      | <Icon icon="square" /> | The maximum number of files that can be uploaded per request.                                                                                                               | 2             |

### Example YAML Configuration

```yaml theme={"system"}
version: "1"

file_upload:
  enabled: true
  max_file_size: 1GB
  max_files: 2
```

## Client Header

The configuration for custom names for client name and client version headers.

| Environment Variable | YAML    | Required               | Description                                   | Default Value |
| -------------------- | ------- | ---------------------- | --------------------------------------------- | ------------- |
|                      | name    | <Icon icon="square" /> | The custom name of the client name header.    |               |
|                      | version | <Icon icon="square" /> | The custom name of the client version header. |               |

### Example YAML Configuration

```yaml theme={"system"}
version: "1"

client_header:
  name: "Client-Name"
  version: "Client-Version"
```

By default, we support `Graphql-Client-Name` , `Graphql-Client-Version`, `ApolloGraphql-Client-Name`, `ApolloGraphql-Client-Version`.

The custom names are given more precedence.

## Apollo Compatibility Flags

This configuration is used to enable full compatibility with Apollo Federation, Apollo Gateway and Apollo Router, you can enable certain compatibility flags, allowing you to use Cosmo Router as a drop-in replacement for Apollo.

### Apollo Compatibility Value Completion

Invalid \_\_typename values will be returned in extensions.valueCompletion instead of errors.

### Apollo Compatibility Truncate Floats

Truncate floats like 1.0 to 1, 2.0 to 2, etc.. Values like 1.1 or 2.2 will not be truncated.

### Apollo Compatibility Suppress Fetch Errors

Suppresses fetch errors. When enabled, only the 'data' object is returned, suppressing errors. If disabled, fetch errors are included in the 'errors' array.

### Apollo Compatibility Replace Undefined Op Field Errors (Deprecated)

<Warning>
  This flag is deprecated. Use `use_graphql_validation_failed_status` instead.
</Warning>

Produces the same error message as Apollo when an invalid operation field is included in an operation selection set. **Extension code**: "GRAPHQL\_VALIDATION\_FAILED" Status code: 400

### Apollo Compatibility Use GraphQL Validation Failed Status

Produces the same error message and status as Apollo when GraphQL validation fails. **Extension code**: "GRAPHQL\_VALIDATION\_FAILED" Status code: 400

### Apollo Compatibility Replace Invalid Var Errors

Produces the same error message as Apollo when an invalid variable is supplied. **Extension code**: "BAD\_USER\_INPUT"

### Apollo Compatibility Replace Validation Error Status

Produces the same error status as Apollo when validation fails. **Error status**: 400 Bad Request **Minimum router version**: [0.175.0](https://github.com/wundergraph/cosmo/compare/router@0.174.3...router@0.175.0)

| Environment Variable                                                     | YAML                                                       | Required               | Description                                                                                                                                                                   | Default Value |
| ------------------------------------------------------------------------ | ---------------------------------------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| APOLLO\_COMPATIBILITY\_ENABLE\_ALL                                       | apollo\_compatibility\_flags: enable\_all: \<bool>         | <Icon icon="square" /> | Enables all the options of Apollo Compatibility.                                                                                                                              | false         |
| APOLLO\_COMPATIBILITY\_VALUE\_COMPLETION\_ENABLED                        | value\_completion: enabled: \<bool>                        | <Icon icon="square" /> | Enables value completion.                                                                                                                                                     | false         |
| APOLLO\_COMPATIBILITY\_TRUNCATE\_FLOATS\_ENABLED                         | truncate\_floats: enabled: \<bool>                         | <Icon icon="square" /> | Enables truncate floats.                                                                                                                                                      | false         |
| APOLLO\_COMPATIBILITY\_SUPPRESS\_FETCH\_ERRORS\_ENABLED                  | suppress\_fetch\_errors: enabled: \<bool>                  | <Icon icon="square" /> | Enables suppress fetch errors.                                                                                                                                                | false         |
| APOLLO\_COMPATIBILITY\_REPLACE\_UNDEFINED\_OP\_FIELD\_ERRORS\_ENABLED    | replace\_undefined\_op\_field\_errors: enabled: \<bool>    | <Icon icon="square" /> | **Deprecated**. Replaces undefined operation field errors. Use use\_graphql\_validation\_failed\_status instead.                                                              | false         |
| APOLLO\_COMPATIBILITY\_REPLACE\_INVALID\_VAR\_ERRORS\_ENABLED            | replace\_invalid\_var\_errors: enabled: \<bool>            | <Icon icon="square" /> | Replaces invalid variable errors.                                                                                                                                             | false         |
| APOLLO\_COMPATIBILITY\_REPLACE\_VALIDATION\_ERROR\_STATUS\_ENABLED       | replace\_validation\_error\_status: enabled: \<bool>       | <Icon icon="square" /> | Replaces validation error status with 400.                                                                                                                                    | false         |
| APOLLO\_COMPATIBILITY\_SUBSCRIPTION\_MULTIPART\_PRINT\_BOUNDARY\_ENABLED | subscription\_multipart\_print\_boundary: enabled: \<bool> | <Icon icon="square" /> | Prints the multipart boundary right after the message in multipart subscriptions. Without this flag, the Apollo client wouldn't parse a message until the next one is pushed. | false         |
| APOLLO\_COMPATIBILITY\_USE\_GRAPHQL\_VALIDATION\_FAILED\_STATUS\_ENABLED | use\_graphql\_validation\_failed\_status: enabled: \<bool> | <Icon icon="square" /> | Uses GraphQL validation failed status code and error format.                                                                                                                  | false         |

### Example YAML Configuration

```yaml theme={"system"}
version: "1"

apollo_compatibility_flags:
  enable_all: false
  value_completion:
    enabled: true
  truncate_floats:
    enabled: false
  suppress_fetch_errors:
    enabled: true
  replace_undefined_op_field_errors:
    enabled: true # Deprecated, use use_graphql_validation_failed_status instead
  replace_invalid_var_errors:
    enabled: true
  replace_validation_error_status:
    enabled: false
  subscription_multipart_print_boundary:
    enabled: false
  use_graphql_validation_failed_status:
    enabled: true
```

## Apollo Router Compatibility Flags

<Info>
  Apollo Router Compatibility Flags *can* be enabled alongside Apollo
  Compatibility Flags, but some will override their counterpart's functionality.
  This means you can safely use `enable_all: true` alongside these flags.
</Info>

### Apollo Router Compatibility Replace Invalid Var Errors

Produces the same error messages as Apollo Router when an invalid variable is supplied.

Extension code: "VALIDATION\_INVALID\_TYPE\_VARIABLE"

| Environment Variable                                                  | YAML                          | Required               | Description                       | Default Value |
| --------------------------------------------------------------------- | ----------------------------- | ---------------------- | --------------------------------- | ------------- |
| APOLLO\_ROUTER\_COMPATIBILITY\_REPLACE\_INVALID\_VAR\_ERRORS\_ENABLED | replace\_invalid\_var\_errors | <Icon icon="square" /> | Replaces invalid variable errors. | false         |

### Example YAML Configuration

```yaml theme={"system"}
version: "1"

apollo_router_compatibility_flags:
  replace_invalid_var_errors:
    enabled: true
```

## Cache warmer

| Environment Variable                | YAML                 | Required               | Description                                                                                                                                                                                                                                                                                            | Default Value |
| ----------------------------------- | -------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- |
| CACHE\_WARMUP\_ENABLED              | enabled              | <Icon icon="square" /> | Enable the cache warmer.                                                                                                                                                                                                                                                                               | false         |
| CACHE\_WARMUP\_ITEMS\_PER\_SECOND   | items\_per\_second   | <Icon icon="square" /> | Maximum number of cache warmup items processed per second across all workers. Acts as an upper bound: actual throughput can be lower if processing is slow or there are too few items. Set to `0` for unlimited. Higher numbers decrease warmup time but increase system load.                         | 50            |
| CACHE\_WARMUP\_ITEM\_DELAY          | item\_delay          | <Icon icon="square" /> | A fixed delay applied after each cache warmup item is processed, per worker. Use to further smooth load during warmup. It applies in addition to `items_per_second`. The period is specified as a string with a number and a unit, e.g. 10ms, 1s, 1m, 1h. The supported units are 'ms', 's', 'm', 'h'. | 0s            |
| CACHE\_WARMUP\_TIMEOUT              | timeout              | <Icon icon="square" /> | The timeout for warming up the cache. This can be used to limit the amount of time cache warming will block deploying a new config. The period is specified as a string with a number and a unit, e.g. 10ms, 1s, 1m, 1h. The supported units are 'ms', 's', 'm', 'h'.                                  | 30s           |
| CACHE\_WARMUP\_WORKERS              | workers              | <Icon icon="square" /> | The number of workers for the cache warmup to run in parallel. Higher numbers decrease the time to warm up the cache but increase the load on the system.                                                                                                                                              | 8             |
|                                     | source               | <Icon icon="square" /> | The source of the cache warmup items. Only one can be specified. If empty, the cache warmup source is the Cosmo CDN and it requires a graph to be set.                                                                                                                                                 |               |
| CACHE\_WARMUP\_IN\_MEMORY\_FALLBACK | in\_memory\_fallback | <Icon icon="square" /> | Enable in-memory switchover that persists the plan cache across router restarts. When enabled, the router will use queries from the previous instance's plan cache to warm up the new cache on restart. Can be used as a fallback or as the primary source for cache warming.                          | true          |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

cache_warmup:
  enabled: true
  workers: 8
  items_per_second: 50
  item_delay: 0s
  timeout: 30s
  in_memory_fallback: true
```

### Source

The source of the cache warmup items. Only one can be specified. If empty, the cache warmup source is the Cosmo CDN and it requires a graph to be set.

| Environment Variable | YAML            | Required               | Description                                                  | Default Value |
| -------------------- | --------------- | ---------------------- | ------------------------------------------------------------ | ------------- |
|                      | filesystem.path | <Icon icon="square" /> | The path to the directory containing the cache warmup items. |               |
|                      | cdn.enabled     | <Icon icon="square" /> | Whether the CDN is the source for warming the cache.         | true          |

### Example YAML config:

```yaml config.yaml theme={"system"}
version: "1"

cache_warmup:
  enabled: true
  workers: 8
  items_per_second: 50
  item_delay: 0s
  timeout: 30s
  in_memory_fallback: true
  source:
    cdn:
      enabled: true
    filesystem:
      path: "./cache-warmer/operations"
```
