fix(console): use private inference IP handoff (#56427)

This commit is contained in:
Dax 2026-10-17 11:44:25 -04:00 • committed by GitHub
parent a801306ddf
commit 8b2aaaf55f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 78 additions and 4 deletions

View file

@ -64,7 +64,12 @@ new sst.cloudflare.x.SolidStart("Console", {
if (migrationDomain)
args.bindings = $resolve(args.bindings).apply((bindings) => [
...(bindings ?? []),
{ type: "service", name: "INFERENCE", service: `opencode-inference-${$app.stage}` },
{
type: "service",
name: "INFERENCE",
service: `opencode-inference-${$app.stage}`,
entrypoint: "LegacyIngress",
},
])
},
},

View file

@ -0,0 +1,20 @@
// Only direct Cloudflare requests can supply visitor-IP evidence to the private inference binding.
// Worker subrequests can derive CF-Connecting-IP from script-controlled X-Real-IP.
export function inferenceHeaders(request: Request & { readonly cf?: unknown }) {
const ip =
request.cf !== undefined && !["cf-worker", "cf-ew-via", "x-real-ip"].some((name) => request.headers.has(name))
? request.headers.get("cf-connecting-ip")
: null
const headers = new Headers(request.headers)
for (const name of [
"x-real-ip",
"x-forwarded-for",
"forwarded",
"cf-connecting-ip",
"cf-connecting-ipv6",
"x-zen-ip",
])
headers.delete(name)
if (ip) headers.set("x-real-ip", ip)
return headers
}

View file

@ -1,4 +1,5 @@
import { Resource } from "@opencode/console-resource"
import { inferenceHeaders } from "./inference-ip"
const paths: Record<string, string | undefined> = {
"POST /zen/v1/chat/completions": "/openai/v1/chat/completions",
@ -36,14 +37,12 @@ export async function proxyInference(request: Request) {
destination.search = url.search
destination.hash = ""
const forwarded = new Request(destination, request)
const forwarded = new Request(destination, new Request(request, { headers: inferenceHeaders(request) }))
for (const name of ["host", "content-length"]) forwarded.headers.delete(name)
// Keyless requests must reach new inference without credentials; `public` is not an API key there.
const anonymous = !key || key === "public"
if (anonymous) for (const name of ["authorization", "x-api-key", "x-goog-api-key"]) forwarded.headers.delete(name)
if (!anonymous) forwarded.headers.set("authorization", `Bearer ${key}`)
const ip = request.headers.get("cf-connecting-ip")
if (ip) forwarded.headers.set("x-real-ip", ip)
const requestID = request.headers.get("x-opencode-request-id") ?? request.headers.get("x-opencode-request")
if (requestID) forwarded.headers.set("x-opencode-request-id", requestID)

View file

@ -0,0 +1,50 @@
import { expect, test } from "bun:test"
import { inferenceHeaders } from "../src/lib/inference-ip"
test.each(["203.0.113.10", "2001:db8::10"])("forwards only the direct edge address: %s", (ip) => {
const request = Object.assign(
new Request("https://opencode.ai/zen/v1/models", {
headers: {
"cf-connecting-ip": ip,
"cf-connecting-ipv6": "2001:db8::bad",
"x-forwarded-for": "198.51.100.1",
forwarded: "for=198.51.100.1",
"x-zen-ip": "198.51.100.1",
authorization: "Bearer test-only",
},
}),
{ cf: { colo: "TEST" } },
)
expect([...inferenceHeaders(request)]).toEqual([
["authorization", "Bearer test-only"],
["x-real-ip", ip],
])
})
test.each(["cf-worker", "cf-ew-via", "x-real-ip"])("rejects relay evidence: %s", (name) => {
const request = Object.assign(
new Request("https://opencode.ai/zen/v1/models", {
headers: { "cf-connecting-ip": "203.0.113.10", [name]: "spoofed" },
}),
{ cf: { colo: "TEST" } },
)
expect(inferenceHeaders(request).has("x-real-ip")).toBe(false)
expect(inferenceHeaders(request).has("cf-connecting-ip")).toBe(false)
})
test("missing runtime metadata cannot turn headers into trusted evidence", () => {
const request = new Request("http://origin/zen/v1/models", {
headers: { "cf-connecting-ip": "203.0.113.10" },
})
expect([...inferenceHeaders(request)]).toEqual([])
})
test("missing edge IP strips claims rather than retaining a fallback", () => {
const request = Object.assign(
new Request("https://opencode.ai/zen/v1/models", {
headers: { "x-forwarded-for": "198.51.100.1", "cf-connecting-ipv6": "2001:db8::1" },
}),
{ cf: { colo: "TEST" } },
)
expect([...inferenceHeaders(request)]).toEqual([])
})