Files
universe/k8s/lux-ns/exchange-gw-config.yaml
zeekayandHanzo AI 7a04dc7642 the gateway stops authoring a header its backend already wrote
KrakenD sets Access-Control-Allow-Origin from security/cors AND passes the
backend's response through verbatim, because output_encoding is "no-op".
exchange-api (Express) already sets that header, so every response through the
gateway carried it twice — and a browser refuses a response whose ACAO "contains
multiple values". lux.exchange rendered empty pages with no failed request to
show for it; the token list fell to 698 characters from 2219.

The headers are what identified it, after Cloudflare and replica drift were both
wrongly suspected:

  api-exchange.lux.network -> (no x-krakend)   -> 1 ACAO
  exchange.lux.cloud       -> x-krakend 2.12.1 -> 2 ACAO

A transparent proxy does not get to author headers the thing it is proxying has
already authored. CORS belongs to whoever writes the response. security/cors is
gone; the backend's complete set (origin, methods, headers) passes through
untouched, and gw.lux.exchange now returns exactly one.

This ConfigMap was live-only — exchange-gw.yaml named it and never carried its
contents, so the five routes the gateway serves existed in exactly one place,
the cluster. Declared here now.

exchange.lux.cloud points at exchange-api directly, matching testnet, devnet and
api-exchange.lux.network. With the gateway fixed either path works; the short one
is the one the other three already use.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-28 12:39:00 -07:00

133 lines
3.6 KiB
YAML

# The exchange gateway's routing table — the five endpoints lux.exchange calls,
# each proxied to exchange-api:4000.
#
# It was live-only until now: deploy/lux-ns/exchange-gw.yaml names this
# ConfigMap but never carried its contents, so the routes the gateway serves
# existed in exactly one place, the cluster.
#
# NO security/cors HERE, deliberately. output_encoding is "no-op", which makes
# this a transparent proxy: the backend's response passes through byte for byte,
# INCLUDING the Access-Control-Allow-Origin that exchange-api (Express) already
# sets. Adding KrakenD's own CORS on top produced the header twice, and a browser
# refuses a response whose ACAO "contains multiple values" — every page rendered
# empty with no failed request to show for it. A transparent proxy does not get
# to author headers the thing it is proxying has already authored. CORS belongs
# to whoever writes the response, which here is exchange-api.
apiVersion: v1
kind: ConfigMap
metadata:
name: exchange-gw-config
namespace: lux-ns
data:
gateway.json: |
{
"$schema": "https://www.krakend.io/schema/v3.json",
"version": 3,
"name": "Lux Exchange Gateway",
"port": 8080,
"timeout": "30s",
"output_encoding": "no-op",
"extra_config": {
"router": {
"return_error_msg": true
},
"qos/ratelimit/router": {
"max_rate": 5000,
"client_max_rate": 200,
"strategy": "ip"
}
},
"endpoints": [
{
"endpoint": "/v1/graphql",
"method": "POST",
"output_encoding": "no-op",
"input_headers": [
"*"
],
"backend": [
{
"url_pattern": "/v1/graphql",
"encoding": "no-op",
"method": "POST",
"host": [
"http://exchange-api:4000"
]
}
]
},
{
"endpoint": "/v1/quote",
"method": "POST",
"output_encoding": "no-op",
"input_headers": [
"*"
],
"backend": [
{
"url_pattern": "/v1/quote",
"encoding": "no-op",
"method": "POST",
"host": [
"http://exchange-api:4000"
]
}
]
},
{
"endpoint": "/v1/swap",
"method": "POST",
"output_encoding": "no-op",
"input_headers": [
"*"
],
"backend": [
{
"url_pattern": "/v1/swap",
"encoding": "no-op",
"method": "POST",
"host": [
"http://exchange-api:4000"
]
}
]
},
{
"endpoint": "/v1/check_approval",
"method": "POST",
"output_encoding": "no-op",
"input_headers": [
"*"
],
"backend": [
{
"url_pattern": "/v1/check_approval",
"encoding": "no-op",
"method": "POST",
"host": [
"http://exchange-api:4000"
]
}
]
},
{
"endpoint": "/v1/swappable_tokens",
"method": "GET",
"output_encoding": "no-op",
"input_headers": [
"*"
],
"backend": [
{
"url_pattern": "/v1/swappable_tokens",
"encoding": "no-op",
"method": "GET",
"host": [
"http://exchange-api:4000"
]
}
]
}
]
}