@teamscala/service-boot 0.23.320 → 0.23.321
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -19,14 +19,20 @@ import { BootFatalError } from "@teamscala/os/errors/boot-error";
|
|
|
19
19
|
import type { MountRegistry } from "@teamscala/os/runtime-contracts/mount-context";
|
|
20
20
|
import type { Context, Hono } from "hono";
|
|
21
21
|
import { getConnInfo } from "hono/bun";
|
|
22
|
+
import { CALLER_HEADERS } from "@teamscala/os/contracts/mcp";
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
// From CALLER_HEADERS, never a literal: this name is one end of a contract the
|
|
25
|
+
// gateway's caller-resolution reads, and a literal stores it twice. The
|
|
26
|
+
// 2026-08-02 outage was that exact drift on a sibling header (reader on
|
|
27
|
+
// `x-user-id`, writer on `x-caller-user-id`), and it took every tool on the
|
|
28
|
+
// cloud MCP down once the branch masking it was closed.
|
|
29
|
+
const REMOTE_PORT_HEADER = CALLER_HEADERS.REMOTE_PORT;
|
|
24
30
|
// Verified socket-peer address (unforgeable transport origin). Sanitized
|
|
25
31
|
// (client-supplied value deleted) then set from getConnInfo so handlers that
|
|
26
32
|
// receive only a Request (e.g. mcp-tool-runtime/mount.ts) can gate on the
|
|
27
33
|
// genuine transport origin per no-client-controlled-trust-signals — an external
|
|
28
34
|
// attacker cannot make their TCP connection appear on the server's loopback.
|
|
29
|
-
const REMOTE_ADDR_HEADER =
|
|
35
|
+
const REMOTE_ADDR_HEADER = CALLER_HEADERS.REMOTE_ADDRESS;
|
|
30
36
|
|
|
31
37
|
export function registerApiRoutes(
|
|
32
38
|
app: Hono,
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
* identity — a clone can never upgrade).
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
+
import { CALLER_HEADERS } from "@teamscala/os/contracts/mcp";
|
|
29
30
|
import { resolveSocketPeer } from "@teamscala/proc-walker/socket-peer";
|
|
30
31
|
|
|
31
32
|
const LOOPBACK = new Set(["127.0.0.1", "::1", "::ffff:127.0.0.1"]);
|
|
@@ -53,15 +54,15 @@ export function stampTransportIdentity(
|
|
|
53
54
|
const port = peer?.port;
|
|
54
55
|
const address = peer?.address ?? null;
|
|
55
56
|
const needsPort =
|
|
56
|
-
typeof port === "number" && port > 0 && !req.headers.has(
|
|
57
|
+
typeof port === "number" && port > 0 && !req.headers.has(CALLER_HEADERS.REMOTE_PORT);
|
|
57
58
|
// Nothing to stamp when there is no peer address and no port to add.
|
|
58
59
|
if (!needsPort && address === null) return req;
|
|
59
60
|
|
|
60
61
|
const headers = new Headers(req.headers);
|
|
61
|
-
if (needsPort) headers.set(
|
|
62
|
+
if (needsPort) headers.set(CALLER_HEADERS.REMOTE_PORT, String(port));
|
|
62
63
|
if (address) {
|
|
63
|
-
headers.delete(
|
|
64
|
-
headers.set(
|
|
64
|
+
headers.delete(CALLER_HEADERS.REMOTE_ADDRESS);
|
|
65
|
+
headers.set(CALLER_HEADERS.REMOTE_ADDRESS, String(address));
|
|
65
66
|
}
|
|
66
67
|
// Local-caller attribution: loopback peer + no forwarding header => a
|
|
67
68
|
// direct local fetch whose owning process we can name via /proc.
|
|
@@ -75,9 +76,9 @@ export function stampTransportIdentity(
|
|
|
75
76
|
) {
|
|
76
77
|
const owner = resolveSocketPeer(port);
|
|
77
78
|
if (owner) {
|
|
78
|
-
headers.set(
|
|
79
|
+
headers.set(CALLER_HEADERS.LOCAL_COMM, owner.comm);
|
|
79
80
|
const cmd = owner.cmdline.join(" ").trim();
|
|
80
|
-
if (cmd) headers.set(
|
|
81
|
+
if (cmd) headers.set(CALLER_HEADERS.LOCAL_CMD, cmd.slice(0, 160));
|
|
81
82
|
}
|
|
82
83
|
}
|
|
83
84
|
return new Request(req.url, {
|