The router provides three different ways of customization:

  1. Configure the router runtime: You can specify a config.yaml for convenience or pass 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.

  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 wgc router compose to build the file locally for development or wgc router fetch to download the latest production version.

  3. Customize the router programatically through Go 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.

Recommendation Create a config file and use environment variable expansion to avoid storing secrets on the file system.

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.

version: '1'

graph:
    token: "${GRAPH_API_TOKEN}"

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.

Expand Environment Variables

You can expand environment variables in the file like this:

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 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 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.yamlfile. This line informs your IDE, to download the correct JSON schema file to validate the config file.

# 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-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 .

Environment Variables

Many configuration options can be set as environment variables. For a complete list of options, please look at the Router config tables.

Router

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

Intervals, timeouts, and delays are specified in Go duration syntax e.g 1s, 5m or 1h.

Sizes can be specified in 2MB, 1mib.

Environment VariableYAMLRequiredDescriptionDefault Value
LISTEN_ADDRlisten_addrThe server listener address.localhost:3002
CONTROLPLANE_URLcontrolplane_urlThe controlplane url. Not required when a static execution config is provided.https://cosmo-cp.wundergraph.com
PLAYGROUND_ENABLEDplayground_enabledEnables the GraphQL playground on ($LISTEN_ADDR/)true
PLAYGROUND_PATHplayground_pathThe path where the playground is served”/“
INTROSPECTION_ENABLEDintrospection_enabledEnables the GraphQL introspectiontrue
QUERY_PLANS_ENABLEDquery_plans_enabledThe Router can return Query plans as part of the response, which might be useful to understand the execution.true
LOG_LEVELlog_levelThe log level to use.info
JSON_LOGjson_logRender the log output in JSON format (true) or human readable (false)true
SHUTDOWN_DELAYshutdown_delayMaximum time in seconds the server has to shutdown gracefully. Should be higher than GRACE_PERIOD60s
GRACE_PERIODgrace_periodMaximum time in seconds the server has between schema updates to gracefully clean up all resources. Should be smaller than SHUTDOWN_DELAY30s
POLL_INTERVALpoll_intervalThe interval of how often the router should check for new schema updates10s
POLL_JITTERpoll_jitterThe maximum delay added to the poll interval to mitigate thundering herd issues in router fleets scenarios.5s
HEALTH_CHECK_PATHhealth_check_pathHealth check path. Returns 200 when the router is alive/health
READINESS_CHECK_PATHreadiness_check_pathReadiness check path. Return 200 when the router is ready to accept traffic, otherwise 503/health/ready
LIVENESS_CHECK_PATHliveness_check_pathLiveness check path. Return 200 when the router is alive/health/live
GRAPHQL_PATHgraphql_pathThe path where the GraphQL Handler is served/graphql
PLAYGROUND_PATHplayground_pathThe path where the playground is served/
LOCALHOST_FALLBACK_INSIDE_DOCKERlocalhost_fallback_inside_dockerEnable fallback for requests that fail to connect to localhost while running in Dockertrue
DEV_MODEdev_modeEnables pretty log output and allows to use Advanced Request Tracing (ART) without further security protection.false
INSTANCE_IDinstance_idIf 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.

Example configuration:

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: ""

Access Logs

For a detailed example, please refer to the Access Logs section.

Environment VariableYAMLRequiredDescriptionDefault Value
access_logsEnable 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_ENABLEDaccess_logs.enabledEnable 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.bufferThe buffer is used to buffer the logs before writing them to the output.
ACCESS_LOGS_BUFFER_ENABLEDaccess_logs.buffer.enabledEnable the buffer.false
ACCESS_LOGS_BUFFER_SIZEaccess_logs.buffer.sizeThe size of the buffer. The default value is 256KB.
ACCESS_LOGS_FLUSH_INTERVALaccess_logs.buffer.flush_intervalThe 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.outputThe log destination. The supported destinations are stdout and file. Only one option can be enabled. The default destination is stdout.
ACCESS_LOGS_OUTPUT_STDOUT_ENABLEDaccess_logs.output.stdout.enabledtrue
ACCESS_LOGS_OUTPUT_FILE_ENABLEDaccess_logs.output.file.enabledfalse
ACCESS_LOGS_FILE_OUTPUT_PATHaccess_logs.output.file.pathThe path to the log file. The path is used to specify the path to the log file.
access_logs.routerThe configuration for access logs for the router.
access_logs.router.fieldsThe fields to add to the access logs for router. The fields are added to the logs as key-value pairs.[]
access_logs.router.fields.keyThe key of the field to add to the logs.
access_logs.router.fields.defaultThe 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_fromDefines 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_headerThe 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_fieldThe 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.subgraphsThe subgraph access logs configuration
access_logs.subgraphs.enabledEnable the subgraphs access logs.false
access_logs.subgraphs.fieldsThe 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.keyThe key of the field to add to the logs.
access_logs.subgraphs.fields.defaultThe 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_fromDefines 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_headerThe 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_headerThe 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_fieldThe 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”, “operation_parsing_time”, “operation_validation_time”, “operation_planning_time”, “operation_normalization_time” ]

Example YAML config:

version: "1"

access_logs:
  enabled: true
  buffer:
    enabled: false
    size: 256KB
    flush_interval: 10s
  output:
    file:
      enabled: true
      path: "access.log"
  router:
    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 VariableYAMLRequiredDescriptionDefault Value
GRAPH_API_TOKENtokenThe token permits the router to communicate with the controlplane and export telemetry. Created with wgc router token create. (Can be empty when providing a static router configuration through ROUTER_CONFIG_PATHbut will disable the default telemetry stack)

Example YAML config:

version: "1"

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

TLS

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

Server TLS

Environment VariableYAMLRequiredDescriptionDefault Value
TLS_SERVER_ENABLEDenabledEnables server TLS support.false
TLS_SERVER_CERT_FILEcert_fileThe path to the server certificate file.
TLS_SERVER_KEY_FILEkey_fileThe path to the server private key file.

Example YAML config:

version: "1"

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

Client Authentication

Environment VariableYAMLRequiredDescriptionDefault Value
TLS_CLIENT_AUTH_CERT_FILEcert_fileEnables client authentication support. The file to the certificate file used to authenthicate clients.” “
TLS_CLIENT_AUTH_REQUIREDrequiredEnforces a valid client certificate to establish a connection.false

Example YAML config:

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

Compliance

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

IP Anonymization

Environment VariableYAMLRequiredDescriptionDefault Value
SECURITY_ANONYMIZE_IP_ENABLEDenabledEnables IP anonymization in traces and logs.true
SECURITY_ANONYMIZE_IP_METHODmethodThe metod to anonymize IP addresses. Can be “hash” or “redact”.“redact”

Example YAML config:

version: "1"

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

Cluster

Environment VariableYAMLRequiredDescriptionDefault Value
CLUSTER_NAMEnameThe logical name of the router cluster. The name is used for analytic purpose.

Example YAML config:

version: "1"

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

Telemetry

Environment VariableYAMLRequiredDescriptionDefault Value
TELEMETRY_SERVICE_NAMEservice_nameThe name of the service.cosmo-router
resource_attributesThe resource attributes to add to OTEL metrics and traces. The resource attributes identify the entity producing the traces and metrics.
resource_attributes.keyThe key of the attribute.
resource_attributes.valueThe value of the attribute.
attributesThe 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.keyThe key of the attribute.
attributes.defaultThe value of the attribute.
attributes.value_fromDefines 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_headerThe 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:

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 VariableYAMLRequiredDescriptionDefault Value
TRACING_ENABLEDenabledtrue
TRACING_SAMPLING_RATEsampling_rateThe 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_SAMPLERparent_based_samplerEnable the parent-based sampler. The parent-based sampler is used to sample the traces based on the parent trace.true
TRACING_BATCH_TIMEOUTbatch_timeoutThe maximum delay allowed before spans are exported.10s
TRACING_EXPORT_GRAPHQL_VARIABLESexport_graphql_variablesExport GraphQL variables as span attribute. Variables may contain sensitive data.false
with_new_rootStarts the root span always at the router.false

Example YAML config:

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
    with_new_root: false

Exporters

Environment VariableYAMLRequiredDescriptionDefault Value
diabledbool
exporterone of: http,grpc
endpoint
path
headers

Example YAML config:

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 VariableYAMLRequiredDescriptionDefault Value
trace_contexttrue
jaeger
b3
baggage
datadogEnable Datadog trace propagationfalse

Example YAML config:

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

Metrics

OTLP

Environment VariableYAMLRequiredDescriptionDefault Value
METRICS_OTLP_ENABLEDenabledEnables OTEL metrics instrumentationtrue
METRICS_OTLP_ROUTER_RUNTIMErouter_runtimeEnable the collection of metrics for the router runtime.true
METRICS_OTLP_GRAPHQL_CACHEgraphql_cacheEnable the collection of metrics for the GraphQL operation router caches.false
METRICS_OTLP_EXCLUDE_METRICSexclude_metricsThe metrics to exclude from the OTEL metrics. Accepts a list of Go regular expressions. Use https://regex101.com/ to test your regular expressions.[]
METRICS_OTLP_EXCLUDE_METRIC_LABELSexclude_metric_labelsThe metric labels to exclude from the OTEL metrics. Accepts a list of Go regular expressions. Use https://regex101.com/ to test your regular expressions.[]

Attributes

YAMLRequiredDescriptionDefault Value
attributesThe attributes to add to OTLP Metrics and Prometheus.[]
attributes.keyThe key of the field.
attributes.defaultThe 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_fromDefines 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_headerThe 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_fieldThe 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:

# See "https://cosmo-docs.wundergraph.com/router/metrics-and-monitoring" for more information
telemetry:
  metrics:
    otlp:
      enabled: true
      router_runtime: true
      graphql_cache: true
      exclude_metrics: []
      exclude_metric_labels: []
    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 VariableYAMLRequiredDescriptionDefault Value
PROMETHEUS_ENABLEDenabledEnables prometheus metrics supporttrue
PROMETHEUS_HTTP_PATHpathThe HTTP path where metrics are exposed.”/metrics”
PROMETHEUS_LISTEN_ADDRlisten_addrThe address to listen on for the prometheus metrics endpoint.”127.0.0.1:8088”
PROMETHEUS_GRAPHQL_CACHEgraphql_cacheEnable the collection of metrics for the GraphQL operation router caches.false
PROMETHEUS_EXCLUDE_METRICSexclude_metrics
PROMETHEUS_EXCLUDE_METRIC_LABELSexclude_metric_labels
PROMETHEUS_EXCLUDE_SCOPE_INFOexclude_scope_infoExclude scope info from Prometheus metrics.false

Example YAML config:

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
      exclude_metrics: []
      exclude_metric_labels: []
      exclude_scope_info: false

Exporter

YAMLRequiredDescriptionDefault Value
disabled
exporterone of: http,grpc
endpoint
pathThe path to which the metrics are exported. This is ignored when using ‘grpc’ as exporter and can be omitted.
headers
temporalityTemporality defines the window that an aggregation is calculated over.
one of: delta, cumulative

Example YAML config:

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>}

    # 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 VariableYAMLRequiredDescriptionDefault Value
GRAPHQL_METRICS_ENABLEDenabledtrue
GRAPHQL_METRICS_COLLECTOR_ENDPOINTcollector_endpointDefault endpointhttps://cosmo-metrics.wundergraph.com

Example YAML config:

version: "1"

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

CORS

Environment VariableYAMLRequiredDescriptionDefault Value
CORS_ENABLEDenabledSet 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_ORIGINSallow_originsThis is a list of origins which are allowed. You can provide origins with wildcards*
CORS_ALLOW_METHODSallow_methodsHEAD,GET,POST
CORS_ALLOW_HEADERSallow_headersOrigin, Content-Length, Content-Type
CORS_ALLOW_CREDENTIALSallow_credentialstrue
CORS_MAX_AGEmax_age5m

Example YAML config:

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

Environment VariableYAMLRequiredDescriptionDefault Value
CACHE_CONTROL_POLICY_ENABLEDenabledSet this to enable/disable the strict cache control policy. It is false by defaultfalse
CACHE_CONTROL_POLICY_VALUEvalueThe 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:

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

Example YAML config:

version: "1"

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

Headers

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

When Cookieis 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_whitelistoption, 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.

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.

Example YAML config:

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 VariableYAMLRequiredDescriptionDefault Value
requestList of Request Header Rules
responseList of Response Header Rules

Example YAML config:

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"

Request Header Rule

Apply to requests to specific Subgraphs.

Environment VariableYAMLRequiredDescriptionDefault Value
oponeof=propagate, set
matchingmatching is the regex to match the header name against
namednamed is the exact header name to match
renamerenames the header’s key to the provided value
defaultdefault is the default value to set if the header is not present
nameIf op is set, name is the name of the desired header to set
valueIf op is set, value is the value of the desired header to set

Example YAML config:

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"

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 VariableYAMLRequiredDescriptionDefault Value
oponeof=propagate, set
algorithmoneof=first_write, last_write, append
matchingmatching is the regex to match the header name against. This
namednamed is the exact header name to match
defaultdefault is the default value to set if the header is not present
renamerenames the header’s key to the provided value

Example YAML config:

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

The configuration for the storage providers. Storage providers can be used to store the persisted operations and the execution config.

Example YAML config:

version: "1"

storage_providers:
  cdn:
    - url: https://cosmo-cdn.wundergraph.com
      id: cdn
  s3:
    - id: "s3"
      endpoint: "localhost:10000"
      bucket: "cosmo"
      access_key: "key"
      secret_key: "secret"
      region: us-east-1
      secure: false
  redis:
    - id: "my-redis"
      cluster_enabled: false
      urls:
        - "redis://localhost:6379"

Users can supply a list of URLs for their redis storage provider.

  • If cluster_enabled: false , then we will use the first URL for the connection URL.

  • If cluster_enabled: true , then we will use all of the URLs for the Redis Cluster connection.

URLs can be supplied with redis configuration options embedded, such as: redis://myUser:myPass@localhost:6379?ssl=true&db=1@connectTimeout=2

Prior to router@v0.169.0, the redis configuration looks like:

  redis:
    - id: "my_redis"
      url: "redis://localhost:6379"

Storage Provider Yaml Options

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

Environment VariableYAMLRequiredDescriptionDefault Value
cdnCDN storage provider.
cdn.idUnique ID of the provider. It is used as reference in persisted_operations and execution_config sections.
cdn.urlURL of the storage provider.https://cosmo-cdn.wundergraph.com
redisRedis storage provider.
STORAGE_PROVIDER_REDIS_IDredis.idUnique ID of the provider. It is used as reference in persisted_operations and execution_config sections.
STORAGE_PROVIDER_REDIS_CLUSTER_ENABLEDredis.cluster_enabledIf the Redis instance is a Redis cluster
STORAGE_PROVIDER_REDIS_URLSredis.urlsList of Redis urls, containing port and auth information if necessary. Must contain at least one element
s3S3 storage provider.
s3.idUnique ID of the privider. It is used as reference in persisted_operations and execution_config sections.
s3.endpointThe endpoint of the S3 bucket. The endpoint is used to specify the endpoint of the S3 bucket.
s3.bucketThe name of the S3 bucket. The S3 bucket is used to store the execution config.
s3.access_keyThe access key of the S3 bucket. The access key ID is used to authenticate with the S3 bucket.
s3.secret_keyThe secret key of the S3 bucket. The secret access key is used to authenticate with the S3 bucket.
s3.regionThe region of the S3 bucket. The region is used to specify the region of the S3 bucket
s3.secureEnables https in the provided endpoint. Must be set to false when accessing http endpointstrue

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:

version: "1"

persisted_operations:
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 VariableYAMLRequiredDescriptionDefault Value
persisted_operationsThe configuration for the persisted operations.
persisted_operations.cacheLRU cache for persisted operations.
PERSISTED_OPERATIONS_CACHE_SIZEpersisted_operations.cache.sizeThe size of the cache in SI unit.”100MB”
persisted_operations.storageThe 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_IDpersisted_operations.storage.provider_idThe ID of the storage provider. The ID must match the ID of the storage provider in the storage_providers section.
PERSISTED_OPERATIONS_STORAGE_OBJECT_PREFIXpersisted_operations.storage.object_prefixThe 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_UNKNOWNpersisted_operations.log_unknownLog 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_ENABLEDpersisted_operations.safelist.enabledOnly allows persisted operations (sent with operation body). If the value is true, all operations not explicitly added to the safelist are blocked.false

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:

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 VariableYAMLRequiredDescriptionDefault Value
automatic_persisted_queriesThe configuration for the persisted operations.
automatic_persisted_queries.enabledWhether or not automatic persisted queries is enabledtrue
automatic_persisted_queries.cacheLRU cache for persisted operations.
automatic_persisted_queries.cache.sizeThe size of the cache in SI unit.”100MB”
automatic_persisted_queries.cache.ttlThe TTL of the cache, in seconds. Set to 0 to set no TTL
automatic_persisted_queries.storageThe 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_idThe 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_prefixThe 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:

version: "1"

execution_config:
storage:
  provider_id: s3
  object_path: /prod

Subgraph Request Rules

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

Environment VariableYAMLRequiredDescriptionDefault Value
execution_configThe configuration for the execution config.
fileThe 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_PATHfile.pathThe path to the execution config file. The path is used to load the execution config from the local file system.
EXECUTION_CONFIG_FILE_WATCHfile.watchEnable 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.storageThe 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_IDexecution_config.storage.provider_idThe ID of the storage provider. The ID must match the ID of the storage provider in the storage_providers section.
EXECUTION_CONFIG_STORAGE_OBJECT_PATHexecution_config.storage.object_pathThe 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_ENABLEDexecution_config.fallback_storage.enabledEnable a fallback storage to fetch the execution config in case the above primary source fails.false
EXECUTION_CONFIG_FALLBACK_STORAGE_PROVIDER_IDexecution_config.fallback_storage.provider_idThe 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_PATHexecution_config.fallback_storage.object_pathThe path to the execution config in the storage provider. The path is used to download the execution config from the S3 bucket.

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

Example YAML config:

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
  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: 0s
    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
  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

Subgraph Request Rules

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

Environment VariableYAMLRequiredDescriptionDefault Value
retry#traffic-shaping-jitter-retry
request_timeout60s
dial_timeout30s
response_header_timeout0s
expect_continue_timeout0s
tls_handshake_timeout10s
keep_alive_idle_timeout0s
keep_alive_probe_interval30s
max_idle_conns1024
max_conns_per_host100
max_idle_conns_per_host20

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 VariableYAMLRequiredDescriptionDefault Value
request_timeout60s
dial_timeout30s
response_header_timeout0s
expect_continue_timeout0s
keep_alive_idle_timeout0s
keep_alive_probe_interval30s
max_idle_conns1024
max_conns_per_host100
max_idle_conns_per_host20

Jitter Retry

Environment VariableYAMLRequiredDescriptionDefault Value
RETRY_ENABLEDenabledtrue
algorithmbackoff_jitterbackoff_jitter
max_attempts
max_duration
interval

Client Request Request Rules

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

Environment VariableYAMLRequiredDescriptionDefault Value
max_request_body_size5mb
MAX_HEADER_BYTESmax_header_bytesMinimum Router version: 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_enabledWhen enabled, the router will check incoming requests for a ‘Content-Encoding’ header and decompress the body accordingly
Note: Currently only “gzip” is supported
true
5mb

WebSocket

Configure WebSocket handlers, protocols, and more.

WebSocket Configuration

Environment VariableYAMLRequiredDescriptionDefault Value
WEBSOCKETS_ENABLEDenabledtrue
absinthe_protocolAbsinthe Protocol Configuration
forward_upgrade_headersForward all useful Headers from the Upgrade Request, like User-Agent or Authorization in the extensions field when subscribing on a Subgraph
forward_upgrade_query_paramsForward all query parameters from the Upgrade Request in the extensions field when subscribing on a Subgraph
forward_initial_payloadForward the initial payload from a client subscription in the extensions field when subscribing on a Subgraphtrue

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 VariableYAMLRequiredDescriptionDefault Value
WEBSOCKETS_ABSINTHE_ENABLEDenabledtrue
WEBSOCKETS_ABSINTHE_HANDLER_PATHhandler_pathThe 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 in subsequent Subgraph Requests.

Example WebSocket YAML config:

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"
  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

YAMLRequiredDescriptionDefault Value
urlThe 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_intervalThe 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
algorithmsThe 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 “HS256”, “HS384”, “HS512”, “RS256”, “RS384”, “RS512”, “ES256”, “ES384”, “ES512”, “PS256”, “PS384”, “PS512”, “EdDSA”[] (all allowed)
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’.

JWT

YAMLRequiredDescriptionDefault Value
header_nameThe name of the header. The header is used to extract the token from the request. The default value is ‘Authorization’.Authorization
header_value_prefixThe 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

YAMLRequiredDescriptionDefault Value
typeThe type of the source. The only currently supported type is ‘header’.header
nameThe name of the header. The header is used to extract the token from the request. The default value is ‘Authorization’.Authorization
value_prefixesThe 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:

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
      - url: "https://example2.com/.well-known/jwks.json"
        refresh_interval: 2m
        # optional list of allowed algorithms per JWKS
        algorithms: ["RS256", "EdDSA", "HS512"]
    header_name: Authorization # 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

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

Provider

Environment VariableYAMLRequiredDescriptionDefault Value
nameName of the providerMy Auth Provider
jwksJWKS Provider

JWK Provider

Environment VariableYAMLRequiredDescriptionDefault Value
url
header_names
header_value_prefixes
refresh_interval1m

Example YAML config:

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 VariableYAMLRequiredDescriptionDefault Value
REQUIRE_AUTHENTICATIONrequire_authenticationSet to true to disallow unauthenticated requestsfalse
REJECT_OPERATION_IF_UNAUTHORIZEDreject_operation_if_unauthorizedIf enabled, the Router will return 401 with no response data when the evaluation of field-based permissions (@authenticatedor @requiresScopesfails)false

Example YAML config:

version: "1"

authorization:
  require_authentication: false
  reject_operation_if_unauthorized: false

CDN

Environment VariableYAMLRequiredDescriptionDefault Value
CDN_URLurlThe 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
CDN_CACHE_SIZEcache_sizeCosmo Router caches responses from the CDN in memory, this defines the cache size.100MB

Example YAML config:

version: "1"

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

Events

The Events section lets you define Event Sources for Event-Driven Federated Subscriptions (EDFS).

We support NATS and Kafka as event bus provider.

version: "1"

events:
  providers:
    nats:
      - id: default
        url: "nats://localhost:4222"
        authentication:
          token: "token" # or
          user_info:
            username: "username"
            password: "password"
    kafka:
      - id: my-kafka
        tls:
          enabled: true
        authentication:
          sasl_plain:
            password: "password"
            username: "username"
        brokers:
          - "localhost:9092"

Provider

Environment VariableYAMLRequiredDescriptionDefault Value
providersone of: nats, kafka

NATS Provider

Environment VariableYAMLRequiredDescriptionDefault Value
idThe ID of the provider. This have to match with the ID specified in the subgraph schema.
urlNATS Connection string
authenticationAuthentication configuration for the NATS provider.
authentication.tokenToken based authentication.
authentication.user_infoUser-Info based authentication.
authentication.user_info.usernameUsername.
authentication.user_info.passwordPassword.

Kafka Provider

Environment VariableYAMLRequiredDescriptionDefault Value
idThe ID of the provider. This have to match with the ID specified in the subgraph schema.[]
brokersA list of broker URLs.
authenticationAuthentication settings
authentication.sasl_plainSASL/Plain Authentication method
authentication.sasl_plain.usernameSASL/Plain Username
authentication.sasl_plain.passwordSASL/Plain Password
tlsTLS configuration for the Kafka provider. If enabled, it uses SystemCertPool for RootCAs by default.
tls.enabledEnable the TLS.

Nats Provider

Router Engine Configuration

Configure the GraphQL Execution Engine of the Router.

Environment VariableYAMLRequiredDescriptionDefault Value
ENGINE_ENABLE_SINGLE_FLIGHTenable_single_flightDeduplicate exactly the same in-flight origin requesttrue
ENGINE_ENABLE_REQUEST_TRACINGenable_request_tracingEnable Advanced Request Tracing (ART)This config is not correlated to OTEL tracing.true
ENGINE_ENABLE_EXECUTION_PLAN_CACHE_RESPONSE_HEADERenable_execution_plan_cache_response_headerUsually only required for testing. When enabled, the Router sets the response Header “X-WG-Execution-Plan-Cache” to “HIT” or “MISS”false
ENGINE_MAX_CONCURRENT_RESOLVERSmax_concurrent_resolversUse 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_POLLenable_net_pollEnables the more efficient poll implementation for all WebSocket implementations (client, server) 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.true
ENGINE_WEBSOCKET_CLIENT_POLL_TIMEOUTwebsocket_client_poll_timeoutThe timeout for the poll loop of the WebSocket client implementation. The period is specified as a string with a number and a unit1s
ENGINE_WEBSOCKET_CLIENT_CONN_BUFFER_SIZEwebsocket_client_conn_buffer_sizeThe buffer size for the poll buffer of the WebSocket client implementation. The buffer size determines how many connections can be handled in one loop.128
ENGINE_WEBSOCKET_CLIENT_READ_TIMEOUTwebsocket_client_read_timeoutThe timeout for the websocket read of the WebSocket client implementation.5s
ENGINE_EXECUTION_PLAN_CACHE_SIZEexecution_plan_cache_sizeDefine 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_MINIFY_SUBGRAPH_OPERATIONSminify_subgraph_operationsMinify 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_CACHEenable_persisted_operations_cacheEnable the persisted operations cache. The persisted operations cache is used to cache normalized persisted operations to improve performance.true
ENGINE_ENABLE_NORMALIZATION_CACHEenable_normalization_cacheEnable the normalization cache. The normalization cache is used to cache normalized operations to improve performance.true
ENGINE_NORMALIZATION_CACHE_SIZEnormalization_cache_sizeThe size of the normalization cache.1024
ENGINE_PARSEKIT_POOL_SIZEparsekit_pool_sizeThe 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_SIZEresolver_max_recyclable_parser_sizeLimits 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_CACHEenable_validation_cacheEnable the validation cache. The validation cache is used to cache results of validating GraphQL Operations.true
ENGINE_VALIDATION_CACHE_SIZEvalidation_cache_sizeThe size of the validation cache.1024
ENGINE_ENABLE_SUBGRAPH_FETCH_OPERATION_NAMEenable_subgraph_fetch_operation_nameEnable 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__operationName\_\_subgraphName__$sequenceID.true
ENGINE_SUBSCRIPTION_FETCH_TIMEOUTsubscription_fetch_timeoutThe maximum time a subscription fetch can take before it is considered timed out.30s

Example YAML config:

version: "1"

engine:
  enable_single_flight: true
  enable_request_tracing: true
  enable_execution_plan_cache_response_header: false
  max_concurrent_resolvers: 32
  enable_websocket_epoll_kqueue: true
  epoll_kqueue_poll_timeout: "1s"
  epoll_kqueue_conn_buffer_size: 128
  websocket_client_read_timeout: "1s"
  execution_plan_cache_size: 10000
  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
  enable_subgraph_fetch_operation_name: true
  subscription_fetch_timeout: 30s

Debug Configuration

Environment VariableYAMLRequiredDescriptionDefault Value
ENGINE_DEBUG_PRINT_OPERATION_TRANSFORMATIONSprint_operation_transformationsPrint the operation transformations.false
ENGINE_DEBUG_PRINT_OPERATION_ENABLE_AST_REFSprint_operation_enable_ast_refsPrint the operation enable AST refs.false
ENGINE_DEBUG_PRINT_PLANNING_PATHSprint_planning_pathsPrint the planning paths.false
ENGINE_DEBUG_PRINT_QUERY_PLANSprint_query_plansPrint the query plans.false
ENGINE_DEBUG_PRINT_NODE_SUGGESTIONSprint_node_suggestionsPrint the node suggestions.false
ENGINE_DEBUG_CONFIGURATION_VISITORconfiguration_visitorPrint the configuration visitor.false
ENGINE_DEBUG_PLANNING_VISITORplanning_visitorPrint the planning visitor.false
ENGINE_DEBUG_DATASOURCE_VISITORdatasource_visitorPrint the datasource visitor.false
ENGINE_DEBUG_REPORT_WEBSOCKET_CONNECTIONSreport_websocket_connectionsPrint the websocket connections.false
ENGINE_DEBUG_REPORT_MEMORY_USAGEreport_memory_usagePrint the memory usage.false
ENGINE_DEBUG_ENABLE_RESOLVER_DEBUGGINGenable_resolver_debuggingEnable verbose debug logging for the Resolver.false
ENGINE_DEBUG_ENABLE_PERSISTED_OPERATIONS_CACHE_RESPONSE_HEADERenable_persisted_operations_cache_response_headerEnable 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_HEADERenable_normalization_cache_response_headerEnable 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_PLANalways_include_query_planAlways include the query plan in the response.false
ENGINE_DEBUG_ALWAYS_SKIP_LOADERalways_skip_loaderAlways skip the loader. This will return no data but only render response extensions, e.g. to expose the query plan.false

Example YAML config:

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.

The rate limiter requires Redis version 3.2 or newer since it relies on replicate_commands feature. ElastiCache for Redis only works in non-clustered mode. You can enable a failover instance to achieve high availability.

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.

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 Expressionssection.

General Rate Limiting Configuration

Environment VariableYAMLRequiredDescriptionDefault Value
RATE_LIMIT_ENABLEDenabledEnable / Disable rate limiting globallyfalse
RATE_LIMIT_STRATEGYstrategyThe rate limit strategy to usesimple
simple_strategy[
Rate Limiting Simple Strategy](/router/configuration#rate-limiting-simple-strategy)simple
storageRate Limiting Redis Storage
RATE_LIMIT_KEY_SUFFIX_EXPRESSIONkey_suffix_expressionThe 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/ for more information.
error_extension_code
Rate Limit Error Extension Code

Rate Limiting Redis Storage

Environment VariableYAMLRequiredDescriptionDefault Value
RATE_LIMIT_REDIS_URLSurlsList of the connection URL(s).[redis://localhost:6379]
RATE_LIMIT_REDIS_CLUSTER_ENABLEDcluster_enabledIf the Redis instance is a Redis clusterfalse
RATE_LIMIT_REDIS_KEY_PREFIXkey_prefixThis prefix is used to namespace the ratelimit keyscosmo_rate_limit

Rate Limiting Simple Strategy

Environment VariableYAMLRequiredDescriptionDefault Value
RATE_LIMIT_SIMPLE_RATErateAllowed request rate (number)10
RATE_LIMIT_SIMPLE_BURSTburstAllowed burst rate (number) - max rate per one request10
RATE_LIMIT_SIMPLE_PERIODperiodThe rate limiting period, e.g. ”10s”, “1m”, etc…1s
RATE_LIMIT_SIMPLE_REJECT_EXCEEDING_REQUESTSreject_exceeding_requestsReject 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_EXTENSIONhide_stats_from_response_extensionHide 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

Rate Limit Error Extension Code

Environment VariableYAMLRequiredDescriptionDefault Value
RATE_LIMIT_ERROR_EXTENSION_CODE_ENABLEDenabledIf 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_CODEcodeThe code to add to the extensions.code field of error objects related to rate limiting.RATE_LIMIT_EXCEEDED

Rate Limiting Example YAML configuration

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
    storage:
        cluster_enabled: false
        urls:
         - "redis://localhost:6379"
        key_prefix: "cosmo_rate_limit"
    debug: false
    key_suffix_expression: ""
    error_extension_code:
        enabled: true
        code: "RATE_LIMIT_EXCEEDED"

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 VariableYAMLRequiredDescriptionDefault Value
SUBGRAPH_ERROR_PROPAGATION_ENABLEDenabledEnable error propagation. If the value is true (default: false), Subgraph errors will be propagated to the client.false
SUBGRAPH_ERROR_PROPAGATION_MODEmodeThe 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_PATHSrewrite_pathsRewrite 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_LOCATIONSomit_locationsOmit the location field of Subgraph errors. If the value is true, the location field of Subgraph errors will be omitted. This is useful because the locations of a Subgraph error is internal to the Subgraph and not relevant to the client.true
SUBGRAPH_ERROR_PROPAGATION_OMIT_EXTENSIONSomit_extensionsOmit the extensions field of Subgraph errors. If the value is true, the extensions field of Subgraph errors will be omitted. This is useful in case you want to avoid leaking internal information to the client. Some users of GraphQL leverage the errors.extensions.code field to implement error handling logic in the client, in which case you might want to set this to false.false
SUBGRAPH_ERROR_PROPAGATION_STATUS_CODESpropagate_status_codesPropagate 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_FIELDSallowed_fieldsIn passthrough mode, by default only message and path is propagated. You can specify additional fields here.
SUBGRAPH_ERROR_PROPAGATION_DEFAULT_EXTENSION_CODEdefault_extension_codeThe 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_NAMEattach_service_nameAttach 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_FIELDSallowed_extension_fieldsThe 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”]

Example YAML configuration:

version: "1"

subgraph_error_propagation:
    enabled: true
    propagate_status_codes: false
    mode: "wrapped"
    rewrite_paths: true
    omit_locations: true
    omit_extensions: false
    default_extension_code: DOWNSTREAM_SERVICE_ERROR
    attach_service_name: true
    allowed_extension_fields:
      - "code"

Security

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

Environment VariableYAMLRequiredDescriptionDefault Value
SECURITY_BLOCK_MUTATIONSblock_mutationsBlock mutation Operations.
SECURITY_BLOCK_MUTATIONS_ENABLEDblock_mutations.enabledIf the value is true, the mutations are blocked.false
SECURITY_BLOCK_MUTATIONS_CONDITIONblock_mutations.conditionThe expression to evaluate if the operation should be blocked.
SECURITY_BLOCK_SUBSCRIPTIONSblock_subscriptionsBlock subscription Operations.
block_subscriptions.enabledIf the value is true, the subscriptions are blocked.false
block_subscriptions.conditionThe expression to evaluate if the operation should be blocked.
SECURITY_BLOCK_NON_PERSISTED_OPERATIONSblock_non_persisted_operationsBlock non-persisted Operations.
SECURITY_BLOCK_NON_PERSISTED_OPERATIONS_ENABLEDblock_non_persisted_operations.enabledIf the value is true, the non-persisted operations are blocked.false
SECURITY_BLOCK_NON_PERSISTED_OPERATIONS_CONDITIONblock_non_persisted_operations.conditionThe expression to evaluate if the operation should be blocked.
complexity_calculation_cacheComplexity Cache configuration
complexity_limitsComplexity limits configuration

Example YAML Configuration

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
    complexity_calculation_cache: # This is for a local in-memory cache, to persist the calculation results
      enabled: true
      size: 1024
    complexity_limits:
        depth: # the equivalent of `security.depth_limit` prevoiusly
          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

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

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 VariableYAMLRequiredDescriptionDefault Value
SECURITY_COMPLEXITY_CACHE_ENABLEDenabledEnable the complexity cachefalse
SECURITY_COMPLEXITY_CACHE_SIZEsizeThe size of the complexity cache1024

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

For all of the limits, if the limit is 0, or enabled isn’t true, the limit isn’t applied. All of them have the same configuration fields:

Environment VariableYAMLRequiredDescriptionDefault Value
enabledEnable the specific limit. If the value is true (default: false), and a valid limit value is set, the limit will be appliedfalse
limitThe limit amount for query. If the limit is 0, this limit isn’t applied0
ignore_persisted_operationsDisable the limit for persisted operations. Since persisted operations are stored intentionally, users may want to disable the limit to consciously allow nested persisted operationsfalse

File Upload

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

Environment VariableYAMLRequiredDescriptionDefault Value
FILE_UPLOAD_ENABLEDenabledWhether the feature is enabled or nottrue
FILE_UPLOAD_MAX_FILE_SIZEmax_file_sizeThe 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_FILESmax_filesThe maximum number of files that can be uploaded per request.2

Example YAML Configuration

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 VariableYAMLRequiredDescriptionDefault Value
nameThe custom name of the client name header.
versionThe custom name of the client version header.

Example YAML Configuration

version: "1"

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

By default, we support Graphql-Client-Name , Graphql-Client-Version, Apollo-Graphql-Client-Name, Apollo-Graphql-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

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 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

Environment VariableYAMLRequiredDescriptionDefault Value
APOLLO_COMPATIBILITY_ENABLE_ALLapollo_compatibility_flags: enable_all: <bool>Enables all the options of Apollo Compatibility.false
APOLLO_COMPATIBILITY_VALUE_COMPLETION_ENABLEDvalue_completion: enabled: <bool>Enables value completion.false
APOLLO_COMPATIBILITY_TRUNCATE_FLOATS_ENABLEDtruncate_floats: enabled: <bool>Enables truncate floats.false
APOLLO_COMPATIBILITY_SUPPRESS_FETCH_ERRORS_ENABLEDsuppress_fetch_errors: enabled: <bool>Enables suppress fetch errors.false
APOLLO_COMPATIBILITY_REPLACE_UNDEFINED_OP_FIELD_ERRORS_ENABLEDreplace_undefined_op_field_errors: enabled: <bool>Replaces undefined operation field errors.false
APOLLO_COMPATIBILITY_REPLACE_INVALID_VAR_ERRORS_ENABLEDreplace_invalid_var_errors: enabled: <bool>Replaces invalid variable errors.false
APOLLO_COMPATIBILITY_REPLACE_VALIDATION_ERROR_STATUS_ENABLEDreplace_validation_error_status_enabled: <bool>Replaces validation error status with 400.false
APOLLO_COMPATIBILITY_SUBSCRIPTION_MULTIPART_PRINT_BOUNDARY_ENABLEDsubscription_multipart_print_boundary: enabled: <bool>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

Example YAML Configuration

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
    replace_invalid_var_errors:
        enabled: true
    replace_validation_error_status:
        enabled: false

Apollo Router Compatibility Flags

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.

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 VariableYAMLRequiredDescriptionDefault Value
APOLLO_ROUTER_COMPATIBILITY_REPLACE_INVALID_VAR_ERRORS_ENABLEDreplace_invalid_var_errorsReplaces invalid variable errors.false

Example YAML Configuration

version: "1"

apollo_router_compatibility_flags:
    replace_invalid_var_errors:
        enabled: true

Cache warmer

Environment VariableYAMLRequiredDescriptionDefault Value
enabledEnable the cache warmer.false
workersThe 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
items_per_secondThe number of cache warmup items to process per second. Higher numbers decrease the time to warm up the cache but increase the load on the system.50
timeoutThe 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
sourceThe 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.

Example YAML config:

version: "1"

cache_warmup:
  enabled: true
  workers: 8
  items_per_second: 50
  timeout: 30s

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 VariableYAMLRequiredDescriptionDefault Value
pathThe path to the directory containing the cache warmup items.

Example YAML config:

version: "1"

cache_warmup:
  enabled: true
  workers: 8
  items_per_second: 50
  timeout: 30s
  source:
    path: "./cache-warmer/operations"