stack: the gateway sets no X-Forwarded-For or X-Real-IP, so Edge Functions cannot see the client IP
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 72/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- typescript
- 領域
- backend
調査の方向性
packages/stack/src/HttpProxy.ts、特に upstreamHeadersFor とアクセスログでの request.socket.remoteAddress の使用箇所を読みます。報告されたネイティブスタックコマンドと hello 関数で再現し、レガシースタックの動作と同様に、関数がクライアントアドレスを含む両方の転送ヘッダーを受け取ることを確認します。
索引モデルが issue の本文から書いたものです。
説明
Affected area
Local development
Supabase CLI version
2.121.0
Operating system
macOS 27.0.1 (Apple silicon)
Installation method
pnpm
Command
SUPABASE_EXPERIMENTAL_STACK=1 supabase start --runtime native
for i in 1 2 3 4 5; do curl -s -w ' %{time_total}s\n' http://127.0.0.1:54321/functions/v1/hello; done
Actual output
{"requests":1,"workerStartedAt":"2026-10-22T04:47:49.507Z","xForwardedFor":null,"xRealIp":null} 1.111719s
{"requests":1,"workerStartedAt":"2026-10-22T04:47:49.553Z","xForwardedFor":null,"xRealIp":null} 0.023354s
{"requests":1,"workerStartedAt":"2026-10-22T04:47:49.586Z","xForwardedFor":null,"xRealIp":null} 0.018719s
# same project on the legacy stack (SUPABASE_EXPERIMENTAL_STACK=0 supabase start)
{"requests":1,"workerStartedAt":"2026-10-22T04:48:40.137Z","xForwardedFor":"192.168.171.1","xRealIp":"192.168.171.1"} 0.056585s
{"requests":2,"workerStartedAt":"2026-10-22T04:48:40.137Z","xForwardedFor":"192.168.171.1","xRealIp":"192.168.171.1"} 0.004061s
{"requests":3,"workerStartedAt":"2026-10-22T04:48:40.137Z","xForwardedFor":"192.168.171.1","xRealIp":"192.168.171.1"} 0.003451s
On the experimental stack the function gets neither X-Forwarded-For nor X-Real-IP. On the legacy stack Kong sets both to the client address.
Expected behavior
The experimental stack's gateway adds the client address as X-Forwarded-For and X-Real-IP, like Kong does on the legacy stack, so functions see who is calling them.
Steps to reproduce
mkdir repro && cd repro && supabase init- Create
supabase/functions/hello/index.ts:let requests = 0; const workerStartedAt = new Date().toISOString(); Deno.serve((req) => Response.json({ requests: ++requests, workerStartedAt, xForwardedFor: req.headers.get("x-forwarded-for"), xRealIp: req.headers.get("x-real-ip"), }) ); - Add to
supabase/config.toml:[functions.hello] verify_jwt = false SUPABASE_EXPERIMENTAL_STACK=1 supabase start --runtime native, then call the function as above. Both header fields arenull.- Stop it, start the legacy stack with
SUPABASE_EXPERIMENTAL_STACK=0 supabase start(I passed-xfor everything except the database, Kong and the edge runtime) and make the same call. Both fields hold the client address.
(The requests counter is for #7274 and doesn't matter here.)
Crash report ID
No response
Docker and service versions
Docker: Client 29.8.2, Server 29.8.2 (linux/arm64)
supabase/postgres 17.11.0.004
supabase/gotrue v2.197.0
postgrest/postgrest v16.4
supabase/realtime v2.143.4
supabase/storage-api v1.82.1
supabase/edge-runtime v1.77.4
supabase/studio 2026.10.12-sha-3699278
supabase/postgres-meta v0.100.0
supabase/logflare 1.53.0
supabase/supavisor 2.9.13
Additional context
In the v2.121.0 tag (97531eb590ccd2c5cf215287ae03e877180810b4), packages/stack/src/HttpProxy.ts builds the upstream headers in upstreamHeadersFor (lines 132-148). It copies the client's headers, drops hop-by-hop ones and rewrites host and the API key, but adds no forwarding headers. The client address is already there: the access log reads request.socket.remoteAddress (line 156). develop and next have no forwarding headers in that file either.
Our functions rate-limit by client IP, taken from the first X-Forwarded-For hop, and answer 400 when there is none. So on the native runtime every one of those functions fails locally, while the same project works on the legacy stack. Sending X-Forwarded-For from the client gets past it, because the gateway passes client headers through, but that means changing every caller just for local development.
I investigated this with help from an AI coding assistant (Claude Code), which also drafted this text. The results above come from real runs.
- 主要言語
- TypeScript
- スター
- 2.4k
- フォーク
- 537
- 平均マージ
- 19時間 40分
- マージ済み PR(30日)
- 403
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
supabase/cli のほかの issue
-
config push: changing auth.oauth_server.authorization_url_path fails with 400 (enabled and path must be sent together)対応中かも @itz-puneet が 6 日前に担当しました。 オープン🐛 Bug supabase/cli
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
supabase/cli#7087 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
db schema declarative sync: no way to fail (non-zero exit) when the generated migration is destructive再び着手できるかも このイシューのプルリクエストはマージされずにクローズされました。 オープン✨ Feature supabase/cli
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
メンテナーはふだん 1 日以内に返信
-
📘 Docs supabase/cli
難易度 1/5 1時間未満 初心者へのやさしさ 88/100
supabase/cli#6974 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
🐛 Bug supabase/cli
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
メンテナーはふだん 1 日以内に返信
-
🐛 Bug supabase/cli
難易度 3/5 1〜2日 初心者へのやさしさ 56/100
メンテナーはふだん 1 日以内に返信
似ている issue
-
clawsweeper:fix-shape-clear clawsweeper:queueable-fix clawsweeper:source-repro impact:ux-friction issue-rating: 🦞 diamond lobster no-stale P3
難易度 2/5 1〜3時間 初心者へのやさしさ 73/100
openclaw/openclaw#182077 · コメント 1 件 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信
-
aikido high security
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
dequelabs/axe-linter-action#161 ·
-
[Feature Request] Update the DimCode agent icon to the 45:32 brand mark対応中かも @eric8810 が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
lyswhut/lx-music-desktop#3026 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
abhigyanpatwari/GitNexus#3704 ·
メンテナーはふだん 1 日以内に返信