# yaml-language-server: $schema=../config.schema.json

version: "1"

# General router options
graph:
  token: "mytoken"

log_level: "info"
listen_addr: "localhost:3002"
controlplane_url: "https://cosmo-cp.wundergraph.com"
playground_enabled: true
playground_path: "/"
playground:
  enabled: false
  path: "/my-playground"
  concurrency_limit: 1500
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_registration: true
graphql_path: /graphql
dev_mode: false
instance_id: ""
graphql_metrics:
  enabled: true
  collector_endpoint: "https://cosmo-metrics.wundergraph.com"
localhost_fallback_inside_docker: true

# Cross-Origin Resource Sharing (CORS)
cors:
  allow_origins: ["*"]
  allow_methods:
    - HEAD
    - GET
    - POST
  allow_headers:
    - Origin
    - Content-Length
    - Content-Type
  allow_credentials: true
  max_age: 5m

access_logs:
  enabled: true
  router:
    fields:
      - key: "hello"
        value_from:
          context_field: "operation_name"
      - key: "request_information"
        value_from:
          expression: "request.error ?? 'success'"
  subgraphs:
    enabled: true
    fields:
      - key: "response_field"
        value_from:
          response_header: "X-Response-Field"

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

# Config for custom modules
# See "https://cosmo-docs.wundergraph.com/router/metrics-and-monitoring" for more information
telemetry:
  # Common options
  service_name: "cosmo-router"

  # If no exporter is specified it uses https://cosmo-otel.wundergraph.com for tracing and metrics

  # OpenTelemetry Tracing
  tracing:
    enabled: true
    sampling_rate: 1
    export_graphql_variables: true
    with_new_root: false
    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
      datadog: 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
        path: "/v1/traces"
        headers: {}

  # OpenTelemetry Metrics
  metrics:
    otlp:
      enabled: true
      router_runtime: true
      graphql_cache: true
      engine_stats:
        subscriptions: true
      exclude_metric_labels: []
      exclude_metrics: []
      # If no exporters are defined, the default one is used
      exporters:
        - exporter: http # or grpc
          disabled: false
          headers: {}
          path: "/v1/metrics"
          endpoint: https://my-otel-collector.example.com
          # headers: {Authorization: Bearer <my-token>}

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

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

# Config for custom modules
# See "https://cosmo-docs.wundergraph.com/router/custom-modules" for more information
modules:
  myModule:
    # Arbitrary values, unmarshalled by the module
    value: 1

cluster:
  name: "my-cluster"

# 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: 4MiB
    decompression_enabled: false
  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
    # 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:
    products: # Will only affect this subgraph
      request_timeout: 120s

# Header manipulation
# See "https://cosmo-docs.wundergraph.com/router/proxy-capabilities" for more information
headers:
  all: # Header rules for all subgraph requests.
    request:
      - op: "propagate" # Forward a client header
        named: X-Test-Header # Exact match (Use the canonical version)

      - op: "propagate"
        matching: (?i)^X-Custom-.* # Regex match (Case insensitive)

      - op: "propagate"
        named: "X-User-Id"
        default: "123" # Set the value when the header was not set
      - op: "set"
        name: "X-API-Key"
        value: "some-secret"
      - op: "set"
        name: "x-operation-name"
        value_from:
          context_field: "operation_name"
    response:
      - op: "propagate"
        algorithm: "append"
        named: "X-Custom-Header"
  subgraphs:
    specific-subgraph: # Will only affect this subgraph
      request:
        - op: "propagate"
          named: Subgraph-Secret
          default: "some-secret"
      response:
        - op: "set"
          name: "X-Subgraph-Key"
          value: "some-subgraph-secret"
  cookie_whitelist:
    - "cookie1"
    - "cookie2"

# Authentication and Authorization
# See https://cosmo-docs.wundergraph.com/router/authentication-and-authorization for more information
authentication:
  jwt:
    jwks:
      - url: "https://example.com/.well-known/jwks.json"
        refresh_interval: 1m
        algorithms: ["RS256"]
      - url: "https://example.com/.well-known/jwks2.json"
        refresh_interval: 2m
        algorithms: ["RS256", "HS256"]
      - url: "https://example.com/.well-known/jwks3.json"
    header_name: Authorization
    header_value_prefix: Bearer
    header_sources:
      - type: header
        name: X-Authorization
        value_prefixes: [Bearer, Token]
      - type: header
        name: authz

authorization:
  require_authentication: false # Set to true to disable requests without authentication

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

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

engine:
  enable_single_flight: true
  enable_request_tracing: true
  enable_execution_plan_cache_response_header: false
  max_concurrent_resolvers: 32
  enable_net_poll: true
  enable_subgraph_fetch_operation_name: true
  websocket_client_poll_timeout: "1s"
  websocket_client_conn_buffer_size: 128
  websocket_client_read_timeout: "5s"
  execution_plan_cache_size: 1024
  resolver_max_recyclable_parser_size: 4096
  debug:
    report_websocket_connections: false
    report_memory_usage: false

rate_limit:
  enabled: true
  strategy: "simple"
  storage:
    cluster_enabled: true
    urls:
      - "test@localhost:8000"
      - "test2@localhost:8001"
    key_prefix: "cosmo_rate_limit"
  simple_strategy:
    rate: 60
    burst: 60
    period: "60s"
    reject_exceeding_requests: true

override_routing_url:
  subgraphs:
    some-subgraph: http://router:3002/graphql

overrides:
  subgraphs:
    some-subgraph:
      routing_url: http://router:3002/graphql
      subscription_url: http://router:3002/graphql/ws
      subscription_protocol: ws
      subscription_websocket_subprotocol: graphql-ws

websocket:
  enabled: true
  absinthe_protocol:
    enabled: true
    handler_path: /absinthe/socket
  forward_initial_payload: true
  forward_upgrade_headers:
    enabled: true
    allow_list:
      - "Authorization"
  forward_upgrade_query_params:
    enabled: true
    allow_list:
      - "Authorization"
  authentication:
    from_initial_payload:
      enabled: true
      key: "Authorization"
      export_token:
        enabled: true
        header_key: "Authorization"

storage_providers:
  s3:
    - id: "s3"
      endpoint: "localhost:10000"
      bucket: "cosmo"
      access_key: "Pj6opX3288YukriGCzIr"
      secret_key: "WNMg9X4fzMva18henO6XLX4qRHEArwYdT7Yt84w9"
      region: "us-east-1"
      secure: false
  redis:
    - id: "my_redis"
      cluster_enabled: false
      urls:
        - "test@localhost:8000"
        - "test2@localhost:8001"

security:
  complexity_calculation_cache:
    enabled: true
    size: 1024
  complexity_limits:
    depth:
      enabled: true
      limit: 5
      ignore_persisted_operations: true
    total_fields:
      enabled: true
      limit: 7
      ignore_persisted_operations: true
    root_fields:
      enabled: true
      limit: 3
      ignore_persisted_operations: true
    root_field_aliases:
      enabled: true
      limit: 4
      ignore_persisted_operations: true
persisted_operations:
  safelist:
    enabled: true
  log_unknown: true
  cache:
    size: 100MB
  storage:
    provider_id: s3
    object_prefix: "5ef73d80-cae4-4d0e-98a7-1e9fa922c1a4/92c25b45-a75b-4954-b8f6-6592a9b203eb/operations/foo"

automatic_persisted_queries:
  enabled: true
  cache:
    size: 100MB
    ttl: 900
  storage:
    provider_id: redis
    object_prefix: "cosmo_apq"

execution_config:
  storage:
    provider_id: s3
    object_path: "5ef73d80-cae4-4d0e-98a7-1e9fa922c1a4/92c25b45-a75b-4954-b8f6-6592a9b203eb/routerconfigs/latest.json"

router_config_path: "latest.json"

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