@calltelemetry/ct-lab-mcp 0.8.40 → 0.8.42

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.
@@ -0,0 +1,49 @@
1
+ export type HostReadOperation = {
2
+ readonly kind: "host_status";
3
+ } | {
4
+ readonly kind: "service_status";
5
+ readonly service: "bifrost" | "tailscaled" | "ct-agent";
6
+ } | {
7
+ readonly kind: "tailnet_status";
8
+ };
9
+ /** Internal selection evidence, NOT a live identity check or permission grant. */
10
+ export interface ResolvedHostBinding {
11
+ readonly scope: "inventory_binding_not_live_identity_or_authorization";
12
+ readonly assetId: string;
13
+ readonly machineId: string;
14
+ readonly tailnetHostname: string;
15
+ readonly remoteUser: string;
16
+ /** Canonical OpenSSH SHA256: + 43 unpadded base64 chars; contracts.ts owns validation. */
17
+ readonly sshHostKeySha256: string;
18
+ readonly capabilityClass: "lab-admin" | "worker";
19
+ /** Digest reported by the canonical reader; not independently attested here. */
20
+ readonly inventorySha256: string;
21
+ }
22
+ /** Canonical binding field validators shared by the inventory and process boundaries. */
23
+ export declare function isHostMachineId(value: unknown): value is string;
24
+ export declare function isHostCatalogDigest(value: unknown): value is string;
25
+ export declare function isHostRemoteUser(value: unknown): value is string;
26
+ export declare function isHostCapabilityClass(value: unknown): value is ResolvedHostBinding["capabilityClass"];
27
+ export declare function isHostTailnet(value: unknown): value is string;
28
+ export declare function isHostTailnetHostname(value: unknown): value is string;
29
+ /** Revalidate and copy at an asynchronous trust boundary without inventing a second schema. */
30
+ export declare function snapshotHostBinding(value: unknown): Readonly<ResolvedHostBinding>;
31
+ export type HostTransportCode = "HOST_OPERATION_INVALID" | "HOST_BINDING_INVALID" | "HOST_ENROLLMENT_MISSING" | "HOST_HOSTKEY_INVALID" | "HOST_PROCESS_FAILED" | "HOST_TIMEOUT" | "HOST_CANCELLED" | "HOST_OUTPUT_INVALID" | "HOST_IDENTITY_MISMATCH" | "HOST_CLEANUP_UNCONFIRMED" | "HOST_UNAUTHENTICATED" | "HOST_FORBIDDEN" | "HOST_POLICY_UNAVAILABLE";
32
+ export declare class HostTransportError extends Error {
33
+ readonly code: HostTransportCode;
34
+ constructor(code: HostTransportCode);
35
+ }
36
+ export declare function failHost(code: HostTransportCode): never;
37
+ export declare function exactRecord(value: unknown, keys: readonly string[]): value is Record<string, unknown>;
38
+ export declare function literal(value: unknown, pattern: RegExp): value is string;
39
+ export declare function isHostAssetId(value: unknown): value is string;
40
+ /** Canonical OpenSSH SHA-256: `SHA256:` + 43 unpadded base64 characters. */
41
+ export declare function isHostKeyFingerprint(value: unknown): value is string;
42
+ /** Validate the SSH wire encoding as well as the text; never accept arbitrary bytes as a key. */
43
+ export declare function publicHostKeyFingerprint(value: unknown): string;
44
+ export declare function readHostOperation(input: unknown): Readonly<HostReadOperation>;
45
+ export declare function hostOperationId(op: HostReadOperation): string;
46
+ /** Abort is propagated without exposing arbitrary AbortSignal.reason/provider errors. */
47
+ export declare function checkHostAbort(signal: AbortSignal): void;
48
+ export declare function hostWait<T>(work: Promise<T>, signal: AbortSignal): Promise<T>;
49
+ //# sourceMappingURL=contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../../src/host/contracts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,137 @@
1
+ import { createHash } from "node:crypto";
2
+ /** Canonical binding field validators shared by the inventory and process boundaries. */
3
+ export function isHostMachineId(value) {
4
+ return literal(value, /^(?!0{32}$)[a-f0-9]{32}$/);
5
+ }
6
+ export function isHostCatalogDigest(value) {
7
+ return literal(value, /^[a-f0-9]{64}$/);
8
+ }
9
+ export function isHostRemoteUser(value) {
10
+ return literal(value, /^[a-z_][a-z0-9_-]{0,31}$/);
11
+ }
12
+ export function isHostCapabilityClass(value) {
13
+ return value === "worker" || value === "lab-admin";
14
+ }
15
+ export function isHostTailnet(value) {
16
+ return literal(value, /^tail[a-z0-9]{1,59}\.ts\.net$/);
17
+ }
18
+ export function isHostTailnetHostname(value) {
19
+ if (typeof value !== "string")
20
+ return false;
21
+ const dot = value.indexOf(".");
22
+ return dot > 0 && literal(value.slice(0, dot), /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/)
23
+ && isHostTailnet(value.slice(dot + 1));
24
+ }
25
+ /** Revalidate and copy at an asynchronous trust boundary without inventing a second schema. */
26
+ export function snapshotHostBinding(value) {
27
+ if (!exactRecord(value, ["scope", "assetId", "machineId", "tailnetHostname", "remoteUser",
28
+ "sshHostKeySha256", "capabilityClass", "inventorySha256"])
29
+ || value.scope !== "inventory_binding_not_live_identity_or_authorization" || !isHostAssetId(value.assetId)
30
+ || !isHostMachineId(value.machineId) || !isHostTailnetHostname(value.tailnetHostname)
31
+ || !isHostRemoteUser(value.remoteUser) || !isHostKeyFingerprint(value.sshHostKeySha256)
32
+ || !isHostCatalogDigest(value.inventorySha256) || !isHostCapabilityClass(value.capabilityClass))
33
+ failHost("HOST_BINDING_INVALID");
34
+ return Object.freeze({ scope: value.scope, assetId: value.assetId, machineId: value.machineId,
35
+ tailnetHostname: value.tailnetHostname, remoteUser: value.remoteUser, sshHostKeySha256: value.sshHostKeySha256,
36
+ capabilityClass: value.capabilityClass, inventorySha256: value.inventorySha256 });
37
+ }
38
+ export class HostTransportError extends Error {
39
+ code;
40
+ constructor(code) {
41
+ super(code);
42
+ this.code = code;
43
+ this.name = "HostTransportError";
44
+ }
45
+ }
46
+ export function failHost(code) { throw new HostTransportError(code); }
47
+ export function exactRecord(value, keys) {
48
+ return value !== null && typeof value === "object" && !Array.isArray(value)
49
+ && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null)
50
+ && Reflect.ownKeys(value).length === keys.length
51
+ && keys.every(key => Object.hasOwn(value, key) && "value" in Object.getOwnPropertyDescriptor(value, key));
52
+ }
53
+ export function literal(value, pattern) {
54
+ return typeof value === "string" && !/[\r\n\u2028\u2029]/.test(value) && pattern.test(value);
55
+ }
56
+ export function isHostAssetId(value) {
57
+ return literal(value, /^[a-z][a-z0-9_-]{0,127}$/);
58
+ }
59
+ /** Canonical OpenSSH SHA-256: `SHA256:` + 43 unpadded base64 characters. */
60
+ export function isHostKeyFingerprint(value) {
61
+ if (!literal(value, /^SHA256:[A-Za-z0-9+/]{43}$/))
62
+ return false;
63
+ const bytes = Buffer.from(value.slice(7), "base64");
64
+ return bytes.length === 32 && bytes.toString("base64").replace(/=+$/, "") === value.slice(7);
65
+ }
66
+ /** Validate the SSH wire encoding as well as the text; never accept arbitrary bytes as a key. */
67
+ export function publicHostKeyFingerprint(value) {
68
+ if (!literal(value, /^(ssh-ed25519|ecdsa-sha2-nistp256) [A-Za-z0-9+/]+={0,2}$/)
69
+ || value.length > 1024)
70
+ failHost("HOST_HOSTKEY_INVALID");
71
+ const [algorithm, encoded] = value.split(" ");
72
+ const bytes = Buffer.from(encoded, "base64");
73
+ if (bytes.toString("base64") !== encoded)
74
+ failHost("HOST_HOSTKEY_INVALID");
75
+ let offset = 0;
76
+ const field = () => {
77
+ if (offset + 4 > bytes.length)
78
+ failHost("HOST_HOSTKEY_INVALID");
79
+ const size = bytes.readUInt32BE(offset);
80
+ offset += 4;
81
+ if (size > bytes.length - offset)
82
+ failHost("HOST_HOSTKEY_INVALID");
83
+ const result = bytes.subarray(offset, offset + size);
84
+ offset += size;
85
+ return result;
86
+ };
87
+ if (!field().equals(Buffer.from(algorithm)))
88
+ failHost("HOST_HOSTKEY_INVALID");
89
+ if (algorithm === "ssh-ed25519") {
90
+ if (field().length !== 32)
91
+ failHost("HOST_HOSTKEY_INVALID");
92
+ }
93
+ else {
94
+ if (!field().equals(Buffer.from("nistp256")))
95
+ failHost("HOST_HOSTKEY_INVALID");
96
+ const point = field();
97
+ if (point.length !== 65 || point[0] !== 4)
98
+ failHost("HOST_HOSTKEY_INVALID");
99
+ }
100
+ if (offset !== bytes.length)
101
+ failHost("HOST_HOSTKEY_INVALID");
102
+ return "SHA256:" + createHash("sha256").update(bytes).digest("base64").replace(/=+$/, "");
103
+ }
104
+ export function readHostOperation(input) {
105
+ if (exactRecord(input, ["kind"]) && (input.kind === "host_status" || input.kind === "tailnet_status"))
106
+ return Object.freeze({ kind: input.kind });
107
+ if (exactRecord(input, ["kind", "service"]) && input.kind === "service_status"
108
+ && (input.service === "bifrost" || input.service === "tailscaled" || input.service === "ct-agent"))
109
+ return Object.freeze({ kind: input.kind, service: input.service });
110
+ failHost("HOST_OPERATION_INVALID");
111
+ }
112
+ export function hostOperationId(op) {
113
+ return op.kind === "service_status" ? `${op.kind}:${op.service}` : op.kind;
114
+ }
115
+ /** Abort is propagated without exposing arbitrary AbortSignal.reason/provider errors. */
116
+ export function checkHostAbort(signal) {
117
+ if (signal.aborted)
118
+ throw signal.reason instanceof HostTransportError
119
+ ? signal.reason : new HostTransportError("HOST_CANCELLED");
120
+ }
121
+ export async function hostWait(work, signal) {
122
+ // Attach the losing promise too: a late provider rejection must not become unhandled.
123
+ return new Promise((resolve, reject) => {
124
+ const abort = () => {
125
+ try {
126
+ checkHostAbort(signal);
127
+ }
128
+ catch (error) {
129
+ reject(error);
130
+ }
131
+ };
132
+ signal.addEventListener("abort", abort, { once: true });
133
+ work.then(resolve, reject).finally(() => signal.removeEventListener("abort", abort));
134
+ abort();
135
+ });
136
+ }
137
+ //# sourceMappingURL=contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../../src/host/contracts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { type ChildProcessByStdio } from "node:child_process";
2
+ import type { Readable } from "node:stream";
3
+ /** Exactly matches stdio=[ignore,pipe,pipe]; stdin is null, not Writable. */
4
+ export interface HostSpawn {
5
+ (file: string, args: readonly string[], options: {
6
+ stdio: ["ignore", "pipe", "pipe"];
7
+ detached: true;
8
+ shell: false;
9
+ cwd: string;
10
+ env: NodeJS.ProcessEnv;
11
+ }): ChildProcessByStdio<null, Readable, Readable>;
12
+ }
13
+ export declare const nativeHostSpawn: HostSpawn;
14
+ export interface HostProcessResult {
15
+ readonly stdout: Buffer;
16
+ readonly exitCode: number | null;
17
+ }
18
+ /** Private process primitive. No callers or MCP arguments can supply these parameters. */
19
+ export declare function runHostProcess(spawnProcess: HostSpawn, file: string, args: readonly string[], directory: string, signal: AbortSignal): Promise<Readonly<HostProcessResult>>;
20
+ //# sourceMappingURL=process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../../src/host/process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAI5C,6EAA6E;AAC7E,MAAM,WAAW,SAAS;IACxB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,EAAE;QAC/C,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAClC,QAAQ,EAAE,IAAI,CAAC;QACf,KAAK,EAAE,KAAK,CAAC;QACb,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;KACxB,GAAG,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;CACnD;AACD,eAAO,MAAM,eAAe,EAAE,SAA+D,CAAC;AAI9F,MAAM,WAAW,iBAAiB;IAAG,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAAE;AAEjG,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,EAC3F,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAqE9E"}
@@ -0,0 +1,98 @@
1
+ import { spawn } from "node:child_process";
2
+ import { checkHostAbort, HostTransportError } from "./contracts.js";
3
+ export const nativeHostSpawn = (file, args, options) => spawn(file, args, options);
4
+ const MAX_BYTES = 16 * 1024;
5
+ const CLEANUP_MS = 500;
6
+ /** Private process primitive. No callers or MCP arguments can supply these parameters. */
7
+ export function runHostProcess(spawnProcess, file, args, directory, signal) {
8
+ checkHostAbort(signal);
9
+ return new Promise((resolve, reject) => {
10
+ let child;
11
+ try {
12
+ child = spawnProcess(file, args, {
13
+ stdio: ["ignore", "pipe", "pipe"], detached: true, shell: false, cwd: directory,
14
+ env: { PATH: "/usr/bin:/bin", LANG: "C", LC_ALL: "C", HOME: directory, NODE_V8_COVERAGE: "" },
15
+ });
16
+ }
17
+ catch {
18
+ reject(new HostTransportError("HOST_PROCESS_FAILED"));
19
+ return;
20
+ }
21
+ let failure;
22
+ let finished = false;
23
+ let cleanupTimer;
24
+ let bytes = 0;
25
+ const chunks = [];
26
+ const killGroup = () => {
27
+ if (typeof child.pid === "number" && child.pid > 1) {
28
+ try {
29
+ process.kill(-child.pid, "SIGKILL");
30
+ }
31
+ catch { /* ESRCH is normal after exit. */ }
32
+ }
33
+ try {
34
+ child.kill("SIGKILL");
35
+ }
36
+ catch { /* close/readback, not this return, proves exit. */ }
37
+ };
38
+ const finish = (code) => {
39
+ if (finished)
40
+ return;
41
+ finished = true;
42
+ clearTimeout(cleanupTimer);
43
+ signal.removeEventListener("abort", onAbort);
44
+ if (failure)
45
+ reject(failure);
46
+ else
47
+ resolve(Object.freeze({ stdout: Buffer.concat(chunks), exitCode: code }));
48
+ };
49
+ const cleanupDeadline = () => {
50
+ cleanupTimer ??= setTimeout(() => {
51
+ failure = new HostTransportError("HOST_CLEANUP_UNCONFIRMED");
52
+ // Do not claim success when close/reaping was not observed within the bound.
53
+ child.stdout.destroy();
54
+ child.stderr.destroy();
55
+ finish(null);
56
+ }, CLEANUP_MS);
57
+ };
58
+ const stop = (code) => {
59
+ if (finished || failure)
60
+ return;
61
+ failure = new HostTransportError(code);
62
+ cleanupDeadline();
63
+ killGroup();
64
+ };
65
+ const onAbort = () => {
66
+ try {
67
+ checkHostAbort(signal);
68
+ }
69
+ catch (error) {
70
+ stop(error instanceof HostTransportError ? error.code : "HOST_CANCELLED");
71
+ }
72
+ };
73
+ child.on("error", () => stop("HOST_PROCESS_FAILED"));
74
+ child.once("exit", () => {
75
+ // The root may exit while descendants retain its pipes or run in the group.
76
+ cleanupDeadline();
77
+ killGroup();
78
+ });
79
+ child.once("close", finish);
80
+ const data = (chunk, stdout) => {
81
+ if (finished || failure)
82
+ return;
83
+ const buffer = typeof chunk === "string" ? Buffer.from(chunk) : chunk;
84
+ bytes += buffer.length;
85
+ if (bytes > MAX_BYTES)
86
+ stop("HOST_OUTPUT_INVALID");
87
+ else if (stdout)
88
+ chunks.push(buffer);
89
+ };
90
+ child.stdout.on("data", chunk => data(chunk, true));
91
+ child.stderr.on("data", chunk => data(chunk, false));
92
+ child.stdout.on("error", () => stop("HOST_PROCESS_FAILED"));
93
+ child.stderr.on("error", () => stop("HOST_PROCESS_FAILED"));
94
+ signal.addEventListener("abort", onAbort, { once: true });
95
+ onAbort();
96
+ });
97
+ }
98
+ //# sourceMappingURL=process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.js","sourceRoot":"","sources":["../../../src/host/process.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { ResolvedHostBinding } from "./contracts.js";
1
2
  import type { CanonicalCommandResult } from "../canonical/types.js";
2
3
  /** Trusted composition input, never an MCP argument or an alternate catalog. */
3
4
  export interface CanonicalHostReader {
@@ -9,18 +10,7 @@ export declare class HostResolutionError extends Error {
9
10
  readonly code: HostResolutionCode;
10
11
  constructor(code: HostResolutionCode);
11
12
  }
12
- /** Internal selection evidence, NOT a live identity check or permission grant. */
13
- export interface ResolvedHostBinding {
14
- readonly scope: "inventory_binding_not_live_identity_or_authorization";
15
- readonly assetId: string;
16
- readonly machineId: string;
17
- readonly tailnetHostname: string;
18
- readonly remoteUser: string;
19
- readonly sshHostKeySha256: string;
20
- readonly capabilityClass: "lab-admin" | "worker";
21
- /** Digest reported by the canonical reader; not independently attested here. */
22
- readonly inventorySha256: string;
23
- }
13
+ export type { ResolvedHostBinding } from "./contracts.js";
24
14
  /**
25
15
  * Inert resolver behind the existing canonical bridge. No SSH, secret lookup,
26
16
  * fallback IP/alias, MCP registration, caching, or automatic host enrollment.
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../../src/host/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAEpE,gFAAgF;AAChF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;CAClF;AAED,MAAM,MAAM,kBAAkB,GAC1B,uBAAuB,GACvB,4BAA4B,GAC5B,uBAAuB,GACvB,wBAAwB,GACxB,oBAAoB,GACpB,uBAAuB,GACvB,sBAAsB,GACtB,sBAAsB,GACtB,wBAAwB,CAAC;AAE7B,qBAAa,mBAAoB,SAAQ,KAAK;IAChC,QAAQ,CAAC,IAAI,EAAE,kBAAkB;gBAAxB,IAAI,EAAE,kBAAkB;CAK9C;AAED,kFAAkF;AAClF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,sDAAsD,CAAC;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,eAAe,EAAE,WAAW,GAAG,QAAQ,CAAC;IACjD,gFAAgF;IAChF,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AA+DD;;;;;;GAMG;AACH,qBAAa,qBAAqB;IACpB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,mBAAmB;IAErD,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC;CAsDxE"}
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../../src/host/resolver.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAEpE,gFAAgF;AAChF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;CAClF;AAED,MAAM,MAAM,kBAAkB,GAC1B,uBAAuB,GACvB,4BAA4B,GAC5B,uBAAuB,GACvB,wBAAwB,GACxB,oBAAoB,GACpB,uBAAuB,GACvB,sBAAsB,GACtB,sBAAsB,GACtB,wBAAwB,CAAC;AAE7B,qBAAa,mBAAoB,SAAQ,KAAK;IAChC,QAAQ,CAAC,IAAI,EAAE,kBAAkB;gBAAxB,IAAI,EAAE,kBAAkB;CAK9C;AAED,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAoD1D;;;;;;GAMG;AACH,qBAAa,qBAAqB;IACpB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,mBAAmB;IAErD,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC;CAsDxE"}
@@ -1,3 +1,4 @@
1
+ import { isHostKeyFingerprint, isHostMachineId, isHostCatalogDigest, isHostRemoteUser, isHostTailnet, isHostTailnetHostname, isHostCapabilityClass } from "./contracts.js";
1
2
  export class HostResolutionError extends Error {
2
3
  code;
3
4
  constructor(code) {
@@ -12,11 +13,6 @@ const MAX_ASSETS = 10_000;
12
13
  const READ_TIMEOUT_MS = 10_000;
13
14
  const ASSET_ID = /^[a-z][a-z0-9_-]{0,127}$/;
14
15
  const CATALOG_ID = /^[a-z0-9][a-z0-9._-]{0,255}$/;
15
- const MACHINE_ID = /^(?!0{32}$)[a-f0-9]{32}$/;
16
- const SHA256 = /^[a-f0-9]{64}$/;
17
- const DNS_LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
18
- const TAILNET = /^tail[a-z0-9]{1,59}\.ts\.net$/;
19
- const REMOTE_USER = /^[a-z_][a-z0-9_-]{0,31}$/;
20
16
  const BINDING_KEYS = [
21
17
  "schema", "status", "asset_id", "machine_id", "tailnet", "hostname",
22
18
  "remote_user", "ssh_host_key_sha256", "capability_class",
@@ -35,12 +31,6 @@ function matches(value, pattern) {
35
31
  function exactKeys(value, keys) {
36
32
  return Object.keys(value).length === keys.length && keys.every(key => Object.hasOwn(value, key));
37
33
  }
38
- function fingerprint(value) {
39
- if (typeof value !== "string" || !/^SHA256:[A-Za-z0-9+/]{43}$/.test(value))
40
- return false;
41
- const bytes = Buffer.from(value.slice(7), "base64");
42
- return bytes.length === 32 && bytes.toString("base64").replace(/=+$/, "") === value.slice(7);
43
- }
44
34
  function inventory(stdout) {
45
35
  requireThat(typeof stdout === "string" && Buffer.byteLength(stdout, "utf8") <= MAX_INVENTORY_BYTES, "HOST_INVENTORY_INVALID");
46
36
  let payload;
@@ -54,7 +44,7 @@ function inventory(stdout) {
54
44
  // selects the first match and cannot establish the absence of duplicate IDs).
55
45
  requireThat(record(payload) && exactKeys(payload, ["inventory_path", "inventory_sha256", "asset_count", "assets"]), "HOST_INVENTORY_INVALID");
56
46
  requireThat(typeof payload.inventory_path === "string" && payload.inventory_path.length > 0
57
- && matches(payload.inventory_sha256, SHA256), "HOST_INVENTORY_INVALID");
47
+ && isHostCatalogDigest(payload.inventory_sha256), "HOST_INVENTORY_INVALID");
58
48
  requireThat(Array.isArray(payload.assets) && payload.assets.length <= MAX_ASSETS
59
49
  && Number.isInteger(payload.asset_count) && payload.asset_count === payload.assets.length, "HOST_INVENTORY_INVALID");
60
50
  const ids = new Set();
@@ -105,14 +95,14 @@ export class InventoryHostResolver {
105
95
  const binding = relationships.host_transport;
106
96
  requireThat(record(binding) && exactKeys(binding, BINDING_KEYS)
107
97
  && binding.schema === "ct-lab-host-transport/v1" && binding.status === "approved", "HOST_BINDING_INVALID");
108
- requireThat(matches(relationships.machine_id, MACHINE_ID) && matches(binding.machine_id, MACHINE_ID)
98
+ requireThat(isHostMachineId(relationships.machine_id) && isHostMachineId(binding.machine_id)
109
99
  && binding.asset_id === assetId && binding.machine_id === relationships.machine_id, "HOST_IDENTITY_MISMATCH");
110
- requireThat(matches(binding.tailnet, TAILNET) && typeof binding.hostname === "string", "HOST_BINDING_INVALID");
100
+ requireThat(isHostTailnet(binding.tailnet) && typeof binding.hostname === "string", "HOST_BINDING_INVALID");
111
101
  const suffix = `.${binding.tailnet}`;
112
102
  requireThat(binding.hostname.endsWith(suffix)
113
- && matches(binding.hostname.slice(0, -suffix.length), DNS_LABEL)
114
- && matches(binding.remote_user, REMOTE_USER) && fingerprint(binding.ssh_host_key_sha256)
115
- && (binding.capability_class === "lab-admin" || binding.capability_class === "worker"), "HOST_BINDING_INVALID");
103
+ && isHostTailnetHostname(binding.hostname)
104
+ && isHostRemoteUser(binding.remote_user) && isHostKeyFingerprint(binding.ssh_host_key_sha256)
105
+ && isHostCapabilityClass(binding.capability_class), "HOST_BINDING_INVALID");
116
106
  // Two durable IDs must not silently authorize the same machine/destination.
117
107
  requireThat(!assets.some(other => {
118
108
  if (other === asset || !record(other.relationships))
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../../src/host/resolver.ts"],"names":[],"mappings":"AAmBA,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IACvB;IAArB,YAAqB,IAAwB;QAC3C,6EAA6E;QAC7E,KAAK,CAAC,IAAI,CAAC,CAAC;QAFO,SAAI,GAAJ,IAAI,CAAoB;QAG3C,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAeD,MAAM,mBAAmB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAC5C,MAAM,UAAU,GAAG,MAAM,CAAC;AAC1B,MAAM,eAAe,GAAG,MAAM,CAAC;AAC/B,MAAM,QAAQ,GAAG,0BAA0B,CAAC;AAC5C,MAAM,UAAU,GAAG,8BAA8B,CAAC;AAClD,MAAM,UAAU,GAAG,0BAA0B,CAAC;AAC9C,MAAM,MAAM,GAAG,gBAAgB,CAAC;AAChC,MAAM,SAAS,GAAG,wCAAwC,CAAC;AAC3D,MAAM,OAAO,GAAG,+BAA+B,CAAC;AAChD,MAAM,WAAW,GAAG,0BAA0B,CAAC;AAC/C,MAAM,YAAY,GAAG;IACnB,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU;IACnE,aAAa,EAAE,qBAAqB,EAAE,kBAAkB;CACzD,CAAC;AACF,MAAM,OAAO,GAAG,CAAC,eAAe,EAAE,MAAM,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,CAAC,CAAC;AAG1G,SAAS,MAAM,CAAC,KAAc;IAC5B,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AACD,SAAS,WAAW,CAAC,EAAW,EAAE,IAAwB;IACxD,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,mBAAmB,CAAC,IAAI,CAAC,CAAC;AAC/C,CAAC;AACD,SAAS,OAAO,CAAC,KAAc,EAAE,OAAe;IAC9C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC/F,CAAC;AACD,SAAS,SAAS,CAAC,KAAkB,EAAE,IAAc;IACnD,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;AACnG,CAAC;AACD,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACzF,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACpD,OAAO,KAAK,CAAC,MAAM,KAAK,EAAE,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC/F,CAAC;AAED,SAAS,SAAS,CAAC,MAAe;IAChC,WAAW,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,mBAAmB,EAChG,wBAAwB,CAAC,CAAC;IAC5B,IAAI,OAAgB,CAAC;IACrB,IAAI,CAAC;QAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAAC,CAAC;IACrC,MAAM,CAAC;QAAC,MAAM,IAAI,mBAAmB,CAAC,wBAAwB,CAAC,CAAC;IAAC,CAAC;IAClE,0EAA0E;IAC1E,8EAA8E;IAC9E,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC,OAAO,EAC9C,CAAC,gBAAgB,EAAE,kBAAkB,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC,EAAE,wBAAwB,CAAC,CAAC;IAC9F,WAAW,CAAC,OAAO,OAAO,CAAC,cAAc,KAAK,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC;WACtF,OAAO,CAAC,OAAO,CAAC,gBAAgB,EAAE,MAAM,CAAC,EAAE,wBAAwB,CAAC,CAAC;IAC1E,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,UAAU;WAC3E,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EACzF,wBAAwB,CAAC,CAAC;IAC5B,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAC9E,wBAAwB,CAAC,CAAC;QAC5B,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,gBAAgB,EAAE,CAAC;AACtD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,qBAAqB;IACH;IAA7B,YAA6B,SAA8B;QAA9B,cAAS,GAAT,SAAS,CAAqB;IAAG,CAAC;IAE/D,KAAK,CAAC,OAAO,CAAC,OAAgB;QAC5B,4EAA4E;QAC5E,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,uBAAuB,CAAC,CAAC;QACjE,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,KAAK,IAAI,EAAE,4BAA4B,CAAC,CAAC;QAChF,IAAI,MAA8B,CAAC;QACnC,IAAI,CAAC;YAAC,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,eAAe,CAAC,CAAC;QAAC,CAAC;QAC9E,MAAM,CAAC;YAAC,MAAM,IAAI,mBAAmB,CAAC,4BAA4B,CAAC,CAAC;QAAC,CAAC;QACtE,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS;eACjF,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,KAAK,KAAK,CAAC,EAAE,uBAAuB,CAAC,CAAC;QAC5F,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;QACjE,WAAW,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC;QACzC,qEAAqE;QACrE,2EAA2E;QAC3E,WAAW,CAAC,KAAK,CAAC,IAAI,KAAK,eAAe,IAAI,KAAK,CAAC,QAAQ,KAAK,OAAO;eACnE,KAAK,CAAC,SAAS,KAAK,YAAY,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,uBAAuB,CAAC,CAAC;QACjG,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,sBAAsB,CAAC,CAAC;QACjE,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC;QAC1C,WAAW,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,EAAE,uBAAuB,CAAC,CAAC;QAC9F,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,EAAE,sBAAsB,CAAC,CAAC;QACpF,MAAM,OAAO,GAAG,aAAa,CAAC,cAAc,CAAC;QAC7C,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC;eAC1D,OAAO,CAAC,MAAM,KAAK,0BAA0B,IAAI,OAAO,CAAC,MAAM,KAAK,UAAU,EACjF,sBAAsB,CAAC,CAAC;QAC1B,WAAW,CAAC,OAAO,CAAC,aAAa,CAAC,UAAU,EAAE,UAAU,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,UAAU,CAAC;eAC/F,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,OAAO,CAAC,UAAU,KAAK,aAAa,CAAC,UAAU,EAClF,wBAAwB,CAAC,CAAC;QAC5B,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,EACnF,sBAAsB,CAAC,CAAC;QAC1B,MAAM,MAAM,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACrC,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;eACxC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;eAC7D,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC,mBAAmB,CAAC;eACrF,CAAC,OAAO,CAAC,gBAAgB,KAAK,WAAW,IAAI,OAAO,CAAC,gBAAgB,KAAK,QAAQ,CAAC,EACtF,sBAAsB,CAAC,CAAC;QAC1B,4EAA4E;QAC5E,WAAW,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;YAC/B,IAAI,KAAK,KAAK,KAAK,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC;gBAAE,OAAO,KAAK,CAAC;YAClE,MAAM,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC,cAAc,CAAC;YACxD,OAAO,KAAK,CAAC,aAAa,CAAC,UAAU,KAAK,OAAO,CAAC,UAAU;mBACvD,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,KAAK,OAAO,CAAC,UAAU;uBACtE,YAAY,CAAC,QAAQ,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QACtD,CAAC,CAAC,EAAE,wBAAwB,CAAC,CAAC;QAC9B,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,KAAK,EAAE,sDAA+D;YACtE,OAAO;YACP,SAAS,EAAE,OAAO,CAAC,UAAU;YAC7B,eAAe,EAAE,OAAO,CAAC,QAAQ;YACjC,UAAU,EAAE,OAAO,CAAC,WAAW;YAC/B,gBAAgB,EAAE,OAAO,CAAC,mBAAmB;YAC7C,eAAe,EAAE,OAAO,CAAC,gBAAgB;YACzC,eAAe,EAAE,MAAM;SACxB,CAAC,CAAC;IACL,CAAC;CACF"}
1
+ {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../../src/host/resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { CanonicalHostReader } from "./resolver.js";
2
+ import { BoundedHostTransport } from "./transport.js";
3
+ import type { HostKeyEnrollmentReader, HostReadResult } from "./transport.js";
4
+ /** Supplied by a trusted per-connection authentication adapter, never tool arguments/headers verbatim. */
5
+ export interface HostSessionAuthority {
6
+ authenticate(signal: AbortSignal): Promise<unknown>;
7
+ readPolicy(subject: string, signal: AbortSignal): Promise<unknown>;
8
+ }
9
+ export interface HostReadSessionOptions {
10
+ readonly authority: HostSessionAuthority;
11
+ readonly enrollment: HostKeyEnrollmentReader;
12
+ /** Sole trusted transport injection seam; never an MCP input or serialized policy field. */
13
+ readonly transport?: BoundedHostTransport;
14
+ }
15
+ /** Per-session policy composition, still unregistered: no host MCP tools are activated. */
16
+ export declare class HostReadSession {
17
+ private readonly options;
18
+ private readonly resolver;
19
+ private readonly transport;
20
+ private identity?;
21
+ constructor(canonical: CanonicalHostReader, options: HostReadSessionOptions);
22
+ read(input: unknown, cancellation?: AbortSignal): Promise<Readonly<HostReadResult>>;
23
+ }
24
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/host/session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAuB,MAAM,eAAe,CAAC;AAI9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAE9E,0GAA0G;AAC1G,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACpD,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpE;AACD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,SAAS,EAAE,oBAAoB,CAAC;IACzC,QAAQ,CAAC,UAAU,EAAE,uBAAuB,CAAC;IAC7C,4FAA4F;IAC5F,QAAQ,CAAC,SAAS,CAAC,EAAE,oBAAoB,CAAC;CAC3C;AAuBD,2FAA2F;AAC3F,qBAAa,eAAe;IAKkB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJpE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuB;IACjD,OAAO,CAAC,QAAQ,CAAC,CAAY;gBAEjB,SAAS,EAAE,mBAAmB,EAAmB,OAAO,EAAE,sBAAsB;IAKtF,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;CAmD1F"}
@@ -0,0 +1,113 @@
1
+ import { InventoryHostResolver } from "./resolver.js";
2
+ import { checkHostAbort, exactRecord, failHost, HostTransportError, hostOperationId, hostWait, isHostAssetId, isHostCapabilityClass, literal, readHostOperation } from "./contracts.js";
3
+ import { BoundedHostTransport } from "./transport.js";
4
+ function principal(value) {
5
+ if (!exactRecord(value, ["subject", "sessionId"])
6
+ || !literal(value.subject, /^[a-zA-Z0-9][a-zA-Z0-9:._@/-]{0,255}$/)
7
+ || !literal(value.sessionId, /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,127}$/))
8
+ failHost("HOST_UNAUTHENTICATED");
9
+ return Object.freeze({ subject: value.subject, sessionId: value.sessionId });
10
+ }
11
+ function grants(value, subject) {
12
+ if (!exactRecord(value, ["subject", "revision", "grants"]) || value.subject !== subject
13
+ || !literal(value.revision, /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/)
14
+ || !Array.isArray(value.grants) || value.grants.length > 1024)
15
+ failHost("HOST_FORBIDDEN");
16
+ return value.grants.map(row => {
17
+ if (!exactRecord(row, ["assetId", "capabilityClass", "operation"]) || !isHostAssetId(row.assetId)
18
+ || !isHostCapabilityClass(row.capabilityClass))
19
+ failHost("HOST_FORBIDDEN");
20
+ let operation;
21
+ try {
22
+ operation = readHostOperation(row.operation);
23
+ }
24
+ catch {
25
+ failHost("HOST_FORBIDDEN");
26
+ }
27
+ return Object.freeze({ assetId: row.assetId, capabilityClass: row.capabilityClass, operation });
28
+ });
29
+ }
30
+ /** Per-session policy composition, still unregistered: no host MCP tools are activated. */
31
+ export class HostReadSession {
32
+ options;
33
+ resolver;
34
+ transport;
35
+ identity;
36
+ constructor(canonical, options) {
37
+ this.options = options;
38
+ this.resolver = new InventoryHostResolver(canonical);
39
+ this.transport = options.transport ?? new BoundedHostTransport(options.enrollment);
40
+ }
41
+ async read(input, cancellation) {
42
+ if (!exactRecord(input, ["assetId", "operation"]) || !isHostAssetId(input.assetId))
43
+ failHost("HOST_OPERATION_INVALID");
44
+ // Snapshot caller data before the first await; a caller cannot swap operations/targets in flight.
45
+ const assetId = input.assetId, operation = readHostOperation(input.operation);
46
+ const controller = new AbortController(), signal = controller.signal;
47
+ const cancel = () => controller.abort(new HostTransportError("HOST_CANCELLED"));
48
+ cancellation?.addEventListener("abort", cancel, { once: true });
49
+ if (cancellation?.aborted)
50
+ cancel();
51
+ const timer = setTimeout(() => controller.abort(new HostTransportError("HOST_TIMEOUT")), 15_000);
52
+ try {
53
+ const authorize = async (binding) => {
54
+ checkHostAbort(signal);
55
+ let current;
56
+ try {
57
+ current = principal(await hostWait(Promise.resolve().then(() => this.options.authority.authenticate(signal)), signal));
58
+ }
59
+ catch {
60
+ checkHostAbort(signal);
61
+ failHost("HOST_UNAUTHENTICATED");
62
+ }
63
+ if (!this.identity)
64
+ this.identity = current;
65
+ if (this.identity.subject !== current.subject || this.identity.sessionId !== current.sessionId)
66
+ failHost("HOST_UNAUTHENTICATED");
67
+ let policy;
68
+ try {
69
+ policy = await hostWait(Promise.resolve().then(() => this.options.authority.readPolicy(current.subject, signal)), signal);
70
+ }
71
+ catch {
72
+ checkHostAbort(signal);
73
+ failHost("HOST_POLICY_UNAVAILABLE");
74
+ }
75
+ let rules;
76
+ try {
77
+ rules = grants(policy, current.subject);
78
+ }
79
+ catch {
80
+ failHost("HOST_FORBIDDEN");
81
+ }
82
+ const allowed = rules.some(grant => grant.assetId === assetId
83
+ && hostOperationId(grant.operation) === hostOperationId(operation)
84
+ && (!binding || grant.capabilityClass === binding.capabilityClass));
85
+ if (!allowed)
86
+ failHost("HOST_FORBIDDEN");
87
+ checkHostAbort(signal);
88
+ };
89
+ // Denied users cannot trigger inventory, public-key enrollment or SSH work.
90
+ await authorize();
91
+ const binding = await hostWait(this.resolver.resolve(assetId), signal);
92
+ await authorize(binding);
93
+ const result = await this.transport.read(binding, operation, {
94
+ signal, beforeSpawn: async () => {
95
+ await authorize(binding);
96
+ const current = await hostWait(this.resolver.resolve(assetId), signal);
97
+ if (JSON.stringify(current) !== JSON.stringify(binding))
98
+ failHost("HOST_BINDING_INVALID");
99
+ // The inventory reread may yield; close the policy-revocation window it creates.
100
+ await authorize(binding);
101
+ },
102
+ });
103
+ // A revocation/session change while the read was running also suppresses its result.
104
+ await authorize(binding);
105
+ return result;
106
+ }
107
+ finally {
108
+ clearTimeout(timer);
109
+ cancellation?.removeEventListener("abort", cancel);
110
+ }
111
+ }
112
+ }
113
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/host/session.ts"],"names":[],"mappings":"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"}
@@ -1,27 +1,11 @@
1
- import { type ChildProcessWithoutNullStreams } from "node:child_process";
2
1
  import type { ResolvedHostBinding } from "./resolver.js";
3
- export type HostReadOperation = {
4
- readonly kind: "host_status";
5
- } | {
6
- readonly kind: "service_status";
7
- readonly service: "bifrost" | "tailscaled" | "ct-agent";
8
- } | {
9
- readonly kind: "tailnet_status";
10
- };
11
- export type HostTransportCode = "HOST_OPERATION_INVALID" | "HOST_ENROLLMENT_MISSING" | "HOST_HOSTKEY_INVALID" | "HOST_PROCESS_FAILED" | "HOST_TIMEOUT" | "HOST_OUTPUT_INVALID" | "HOST_IDENTITY_MISMATCH";
12
- export declare class HostTransportError extends Error {
13
- readonly code: HostTransportCode;
14
- constructor(code: HostTransportCode);
15
- }
2
+ import type { HostReadOperation } from "./contracts.js";
3
+ import type { HostSpawn } from "./process.js";
4
+ export { HostTransportError } from "./contracts.js";
5
+ export type { HostReadOperation, HostTransportCode } from "./contracts.js";
6
+ export type { HostSpawn } from "./process.js";
16
7
  export interface HostKeyEnrollmentReader {
17
- getPublicHostKey(assetId: string): Promise<string | undefined>;
18
- }
19
- export interface HostSpawn {
20
- (file: string, args: readonly string[], options: {
21
- stdio: ["ignore", "pipe", "pipe"];
22
- detached: boolean;
23
- env: NodeJS.ProcessEnv;
24
- }): ChildProcessWithoutNullStreams;
8
+ getPublicHostKey(assetId: string, signal?: AbortSignal): Promise<string | undefined>;
25
9
  }
26
10
  export interface HostReadResult {
27
11
  readonly scope: "read_only_host_status";
@@ -31,12 +15,18 @@ export interface HostReadResult {
31
15
  readonly status: "ok" | "degraded" | "unknown";
32
16
  readonly detail: string;
33
17
  }
18
+ export interface HostExecutionChecks {
19
+ readonly signal?: AbortSignal;
20
+ /** Server-owned policy recheck after enrollment and immediately before spawn. */
21
+ readonly beforeSpawn?: () => Promise<void>;
22
+ }
23
+ /** Internal only. The server's HostReadSession owns authentication/authorization. */
34
24
  export declare class BoundedHostTransport {
35
25
  private readonly enrollment;
36
26
  private readonly spawnProcess;
37
27
  private readonly sshExecutable;
38
28
  private readonly timeoutMs;
39
29
  constructor(enrollment: HostKeyEnrollmentReader, spawnProcess?: HostSpawn, sshExecutable?: string, timeoutMs?: number);
40
- read(binding: Readonly<ResolvedHostBinding>, input: unknown): Promise<Readonly<HostReadResult>>;
30
+ read(value: Readonly<ResolvedHostBinding>, input: unknown, checks?: HostExecutionChecks): Promise<Readonly<HostReadResult>>;
41
31
  }
42
32
  //# sourceMappingURL=transport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../src/host/transport.ts"],"names":[],"mappings":"AAIA,OAAO,EAAS,KAAK,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEzD,MAAM,MAAM,iBAAiB,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;CAAE,GAChC;IAAE,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,GAAG,YAAY,GAAG,UAAU,CAAA;CAAE,GAC5F;IAAE,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,CAAC;AACxC,MAAM,MAAM,iBAAiB,GAAG,wBAAwB,GAAC,yBAAyB,GAAC,sBAAsB,GAAC,qBAAqB,GAAC,cAAc,GAAC,qBAAqB,GAAC,wBAAwB,CAAC;AAC9L,qBAAa,kBAAmB,SAAQ,KAAK;IAAe,QAAQ,CAAC,IAAI,EAAE,iBAAiB;gBAAvB,IAAI,EAAE,iBAAiB;CAAoD;AAChJ,MAAM,WAAW,uBAAuB;IAAG,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAC,SAAS,CAAC,CAAC;CAAE;AAC1G,MAAM,WAAW,SAAS;IAAG,CAAC,IAAI,EAAC,MAAM,EAAC,IAAI,EAAC,SAAS,MAAM,EAAE,EAAC,OAAO,EAAC;QAAC,KAAK,EAAC,CAAC,QAAQ,EAAC,MAAM,EAAC,MAAM,CAAC,CAAC;QAAA,QAAQ,EAAC,OAAO,CAAC;QAAA,GAAG,EAAC,MAAM,CAAC,UAAU,CAAA;KAAC,GAAE,8BAA8B,CAAC;CAAE;AACnL,MAAM,WAAW,cAAc;IAAG,QAAQ,CAAC,KAAK,EAAC,uBAAuB,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAC,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAC,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAC,IAAI,GAAC,UAAU,GAAC,SAAS,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAC,MAAM,CAAC;CAAE;AAmChP,qBAAa,oBAAoB;IACnB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAAyB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAA8B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAAgB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAtK,UAAU,EAAC,uBAAuB,EAAkB,YAAY,GAAC,SAA4B,EAAkB,aAAa,SAAe,EAAkB,SAAS,SAAW;IACxM,IAAI,CAAC,OAAO,EAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAC,KAAK,EAAC,OAAO,GAAE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;CAkBlG"}
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../src/host/transport.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAGzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC3E,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,WAAW,uBAAuB;IACtC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACtF;AACD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,uBAAuB,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,IAAI,GAAG,UAAU,GAAG,SAAS,CAAC;IAC/C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AACD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,iFAAiF;IACjF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C;AAiCD,qFAAqF;AACrF,qBAAa,oBAAoB;IACnB,OAAO,CAAC,QAAQ,CAAC,UAAU;IACrC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAAmB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAFhD,UAAU,EAAE,uBAAuB,EAC7C,YAAY,GAAE,SAA2B,EACzC,aAAa,SAAiB,EAAmB,SAAS,SAAQ;IAK/E,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,GAAE,mBAAwB,GAAG,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;CAmDtI"}
@@ -1,110 +1,126 @@
1
- import { createHash } from "node:crypto";
2
1
  import { mkdtemp, rm, writeFile } from "node:fs/promises";
3
2
  import { tmpdir } from "node:os";
4
- import { join } from "node:path";
5
- import { spawn } from "node:child_process";
6
- export class HostTransportError extends Error {
7
- code;
8
- constructor(code) {
9
- super(code);
10
- this.code = code;
11
- this.name = "HostTransportError";
12
- }
13
- }
14
- const MAX_BYTES = 16 * 1024, TIMEOUT_MS = 8_000;
15
- const SERVICES = new Set(["bifrost", "tailscaled", "ct-agent"]);
16
- const PUBLIC_KEY = /^(ssh-ed25519|ecdsa-sha2-nistp256) ([A-Za-z0-9+/]+={0,2})$/;
17
- function fail(code) { throw new HostTransportError(code); }
18
- function readOperation(input) {
19
- if (!input || typeof input !== "object" || Array.isArray(input))
20
- fail("HOST_OPERATION_INVALID");
21
- const r = input;
22
- if ((r.kind === "host_status" || r.kind === "tailnet_status") && Object.keys(r).length === 1)
23
- return { kind: r.kind };
24
- if (r.kind === "service_status" && typeof r.service === "string" && SERVICES.has(r.service) && Object.keys(r).length === 2)
25
- return { kind: r.kind, service: r.service };
26
- fail("HOST_OPERATION_INVALID");
27
- }
28
- function fingerprint(key) {
29
- const m = PUBLIC_KEY.exec(key);
30
- if (!m)
31
- fail("HOST_HOSTKEY_INVALID");
32
- const bytes = Buffer.from(m[2], "base64");
33
- if (!bytes.length || bytes.toString("base64").replace(/=+$/, "") !== m[2].replace(/=+$/, ""))
34
- fail("HOST_HOSTKEY_INVALID");
35
- return "SHA256:" + createHash("sha256").update(bytes).digest("base64").replace(/=+$/, "");
36
- }
37
- function remoteScript(op) {
38
- const p = 'm=$(cat /etc/machine-id 2>/dev/null) || exit 40; printf "CTMID=%s\\n" "$m"; ';
3
+ import { isAbsolute, join } from "node:path";
4
+ import { checkHostAbort, failHost, HostTransportError, hostWait, snapshotHostBinding, publicHostKeyFingerprint, readHostOperation } from "./contracts.js";
5
+ import { nativeHostSpawn, runHostProcess } from "./process.js";
6
+ export { HostTransportError } from "./contracts.js";
7
+ // Remote status protocol owned only by this adapter, not by the local process runner.
8
+ const REMOTE_IDENTITY_MISMATCH = 41;
9
+ function remoteScript(binding, op) {
10
+ // machineId is an independently validated hex literal, never raw caller text.
11
+ const prefix = 'export PATH=/usr/bin:/bin LC_ALL=C; m=$(cat /etc/machine-id 2>/dev/null) || exit 40; '
12
+ + `[ "$m" = '${binding.machineId}' ] || exit ${REMOTE_IDENTITY_MISMATCH}; printf "CTMID=%s\\n" "$m"; `;
39
13
  if (op.kind === "host_status")
40
- return p + 'printf "CTSTATUS=ok\\nCTDETAIL=reachable\\n"';
14
+ return prefix + 'printf "CTSTATUS=ok\\nCTDETAIL=reachable\\n"';
41
15
  const service = op.kind === "tailnet_status" ? "tailscaled" : op.service;
42
- return p + `systemctl is-active --quiet ${service} && s=ok || s=degraded; printf "CTSTATUS=%s\\nCTDETAIL=${service}\\n" "$s"`;
16
+ return prefix + `case "$(systemctl is-active -- ${service} 2>/dev/null)" in `
17
+ + 'active) s=ok;; inactive|failed) s=degraded;; *) s=unknown;; esac; '
18
+ + `printf "CTSTATUS=%s\\nCTDETAIL=${service}\\n" "$s"`;
43
19
  }
44
- function parse(stdout, b, op) {
45
- const l = stdout.split("\n").filter(Boolean);
46
- if (l.length !== 3 || !l[0].startsWith("CTMID=") || !l[1].startsWith("CTSTATUS=") || !l[2].startsWith("CTDETAIL="))
47
- fail("HOST_OUTPUT_INVALID");
48
- const machineId = l[0].slice(6);
49
- if (!/^[a-f0-9]{32}$/.test(machineId) || machineId !== b.machineId)
50
- fail("HOST_IDENTITY_MISMATCH");
51
- const status = l[1].slice(9);
20
+ function parse(bytes, b, op) {
21
+ let stdout;
22
+ try {
23
+ stdout = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
24
+ }
25
+ catch {
26
+ failHost("HOST_OUTPUT_INVALID");
27
+ }
28
+ const lines = stdout.split("\n");
29
+ if (lines.length !== 4 || lines[3] !== "" || !lines[0].startsWith("CTMID=")
30
+ || !lines[1].startsWith("CTSTATUS=") || !lines[2].startsWith("CTDETAIL="))
31
+ failHost("HOST_OUTPUT_INVALID");
32
+ const machineId = lines[0].slice(6);
33
+ if (machineId !== b.machineId)
34
+ failHost("HOST_IDENTITY_MISMATCH");
35
+ const status = lines[1].slice(9);
52
36
  if (status !== "ok" && status !== "degraded" && status !== "unknown")
53
- fail("HOST_OUTPUT_INVALID");
54
- const detail = l[2].slice(9), expected = op.kind === "host_status" ? "reachable" : op.kind === "tailnet_status" ? "tailscaled" : op.service;
37
+ failHost("HOST_OUTPUT_INVALID");
38
+ const detail = lines[2].slice(9);
39
+ const expected = op.kind === "host_status" ? "reachable" : op.kind === "tailnet_status" ? "tailscaled" : op.service;
55
40
  if (detail !== expected)
56
- fail("HOST_OUTPUT_INVALID");
41
+ failHost("HOST_OUTPUT_INVALID");
57
42
  return Object.freeze({ scope: "read_only_host_status", assetId: b.assetId, operation: op.kind, machineId, status, detail });
58
43
  }
44
+ /** Internal only. The server's HostReadSession owns authentication/authorization. */
59
45
  export class BoundedHostTransport {
60
46
  enrollment;
61
47
  spawnProcess;
62
48
  sshExecutable;
63
49
  timeoutMs;
64
- constructor(enrollment, spawnProcess = spawn, sshExecutable = "/usr/bin/ssh", timeoutMs = TIMEOUT_MS) {
50
+ constructor(enrollment, spawnProcess = nativeHostSpawn, sshExecutable = "/usr/bin/ssh", timeoutMs = 8_000) {
65
51
  this.enrollment = enrollment;
66
52
  this.spawnProcess = spawnProcess;
67
53
  this.sshExecutable = sshExecutable;
68
54
  this.timeoutMs = timeoutMs;
55
+ if (!isAbsolute(sshExecutable) || !Number.isInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 8_000)
56
+ failHost("HOST_PROCESS_FAILED");
69
57
  }
70
- async read(binding, input) {
71
- const op = readOperation(input), key = await this.enrollment.getPublicHostKey(binding.assetId);
72
- if (typeof key !== "string")
73
- fail("HOST_ENROLLMENT_MISSING");
74
- if (fingerprint(key) !== binding.sshHostKeySha256)
75
- fail("HOST_HOSTKEY_INVALID");
76
- const dir = await mkdtemp(join(tmpdir(), "ct-host-")), knownHosts = join(dir, "known_hosts");
58
+ async read(value, input, checks = {}) {
59
+ const binding = snapshotHostBinding(value), op = readHostOperation(input);
60
+ const controller = new AbortController();
61
+ const relay = () => controller.abort(checks.signal?.reason instanceof HostTransportError
62
+ ? checks.signal.reason : new HostTransportError("HOST_CANCELLED"));
63
+ checks.signal?.addEventListener("abort", relay, { once: true });
64
+ if (checks.signal?.aborted)
65
+ relay();
66
+ const signal = controller.signal;
67
+ const timer = setTimeout(() => controller.abort(new HostTransportError("HOST_TIMEOUT")), this.timeoutMs);
68
+ let dir;
77
69
  try {
70
+ checkHostAbort(signal);
71
+ let key;
72
+ try {
73
+ key = await hostWait(Promise.resolve().then(() => this.enrollment.getPublicHostKey(binding.assetId, signal)), signal);
74
+ }
75
+ catch {
76
+ checkHostAbort(signal);
77
+ failHost("HOST_ENROLLMENT_MISSING");
78
+ }
79
+ if (key === undefined)
80
+ failHost("HOST_ENROLLMENT_MISSING");
81
+ if (publicHostKeyFingerprint(key) !== binding.sshHostKeySha256)
82
+ failHost("HOST_HOSTKEY_INVALID");
83
+ checkHostAbort(signal);
84
+ dir = await mkdtemp(join(tmpdir(), "ct-host-"));
85
+ const knownHosts = join(dir, "known_hosts");
78
86
  await writeFile(knownHosts, `${binding.tailnetHostname} ${key}\n`, { encoding: "utf8", mode: 0o600 });
79
- const args = ["-F", "/dev/null", "-T", "-o", "BatchMode=yes", "-o", "StrictHostKeyChecking=yes", "-o", `UserKnownHostsFile=${knownHosts}`, "-o", "GlobalKnownHostsFile=/dev/null", "-o", "CheckHostIP=no", "-o", "ConnectTimeout=5", "-o", "ConnectionAttempts=1", "--", `${binding.remoteUser}@${binding.tailnetHostname}`, remoteScript(op)];
80
- const child = this.spawnProcess(this.sshExecutable, args, { stdio: ["ignore", "pipe", "pipe"], detached: true, env: { PATH: "/usr/bin:/bin", LANG: "C", LC_ALL: "C" } });
81
- const out = [];
82
- let bytes = 0, overflow = false, timedOut = false;
83
- child.stdout.on("data", (c) => { bytes += c.length; if (bytes <= MAX_BYTES)
84
- out.push(c);
85
- else
86
- overflow = true; });
87
- child.stderr.on("data", (c) => { bytes += c.length; if (bytes > MAX_BYTES)
88
- overflow = true; });
89
- const timer = setTimeout(() => { timedOut = true; if (typeof child.pid === "number")
87
+ if (checks.beforeSpawn)
88
+ await hostWait(Promise.resolve().then(checks.beforeSpawn), signal);
89
+ checkHostAbort(signal);
90
+ // Tailscale SSH's node identity is the only supported authentication here.
91
+ // None of OpenSSH's implicit ~/.ssh keys, agents, certificates or providers may be used.
92
+ const options = ["BatchMode=yes", "StrictHostKeyChecking=yes", `UserKnownHostsFile=${knownHosts}`,
93
+ "GlobalKnownHostsFile=/dev/null", "KnownHostsCommand=none", "CheckHostIP=no", "UpdateHostKeys=no",
94
+ "Port=22", "ConnectTimeout=5", "ConnectionAttempts=1", "CanonicalizeHostname=no",
95
+ "IdentityFile=none", "IdentityAgent=none", "CertificateFile=none", "IdentitiesOnly=yes",
96
+ "PubkeyAuthentication=no", "PasswordAuthentication=no", "KbdInteractiveAuthentication=no",
97
+ "HostbasedAuthentication=no", "GSSAPIAuthentication=no", "PreferredAuthentications=none", "PKCS11Provider=none",
98
+ "ProxyCommand=none", "ProxyJump=none", "PermitLocalCommand=no", "ClearAllForwardings=yes",
99
+ "ForwardAgent=no", "ForwardX11=no", "ControlMaster=no", "ControlPath=none", "ControlPersist=no"];
100
+ const args = ["-F", "/dev/null", "-T", ...options.flatMap(option => ["-o", option]),
101
+ "--", `${binding.remoteUser}@${binding.tailnetHostname}`, remoteScript(binding, op)];
102
+ const processResult = await runHostProcess(this.spawnProcess, this.sshExecutable, args, dir, signal);
103
+ if (processResult.exitCode !== 0)
104
+ failHost(processResult.exitCode === REMOTE_IDENTITY_MISMATCH
105
+ ? "HOST_IDENTITY_MISMATCH" : "HOST_PROCESS_FAILED");
106
+ return parse(processResult.stdout, binding, op);
107
+ }
108
+ catch (error) {
109
+ if (error instanceof HostTransportError)
110
+ throw error;
111
+ throw new HostTransportError("HOST_PROCESS_FAILED");
112
+ }
113
+ finally {
114
+ clearTimeout(timer);
115
+ checks.signal?.removeEventListener("abort", relay);
116
+ if (dir) {
90
117
  try {
91
- process.kill(-child.pid, "SIGKILL");
118
+ await rm(dir, { recursive: true, force: true });
119
+ }
120
+ catch {
121
+ failHost("HOST_CLEANUP_UNCONFIRMED");
92
122
  }
93
- catch { } ; try {
94
- child.kill("SIGKILL");
95
123
  }
96
- catch { } }, this.timeoutMs);
97
- const code = await new Promise((resolve, reject) => { child.once("error", reject); child.once("close", resolve); }).catch(() => fail("HOST_PROCESS_FAILED")).finally(() => clearTimeout(timer));
98
- if (timedOut)
99
- fail("HOST_TIMEOUT");
100
- if (overflow)
101
- fail("HOST_OUTPUT_INVALID");
102
- if (code !== 0)
103
- fail("HOST_PROCESS_FAILED");
104
- return parse(Buffer.concat(out).toString("utf8"), binding, op);
105
- }
106
- finally {
107
- await rm(dir, { recursive: true, force: true }).catch(() => undefined);
108
124
  }
109
125
  }
110
126
  }
@@ -1 +1 @@
1
- {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../src/host/transport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../src/host/transport.ts"],"names":[],"mappings":"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"}
@@ -15,7 +15,10 @@ import { CredentialResolutionResult, ProxmoxHostConfig, EsxiHostConfig } from ".
15
15
  import { TelemetryRegistry } from "./telemetry/index.js";
16
16
  import { CanonicalLabBridge } from "./canonical/bridge.js";
17
17
  import type { CredentialResolutionError } from "./credentials/errors.js";
18
+ import { type HostReadSessionOptions } from "./host/session.js";
18
19
  export interface McpServerOptions {
20
+ /** Trusted process dependencies only. Authentication is supplied per connection, never server-wide. */
21
+ hostReadSession?: Omit<HostReadSessionOptions, "authority">;
19
22
  name?: string;
20
23
  version?: string;
21
24
  description?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAgC,MAAM,wBAAwB,CAAC;AAE7F,OAAO,EAAmB,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG1D,OAAO,EAAE,0BAA0B,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACvG,OAAO,EAAa,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEzE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,iBAAiB,CAAC,EAAE,sBAAsB,CAAC;IAC3C,eAAe,CAAC,EAAE,qBAAqB,CAAC;IACxC,iBAAiB,CAAC,EAAE,kBAAkB,CAAC;IACvC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,WAAW,CAAC,EAAE,0BAA0B,CAAC;IACzC,eAAe,CAAC,EAAE,yBAAyB,CAAC;IAC5C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACrC,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;IAC/B,WAAW,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAClC,cAAc,CAAC,EAAE,uBAAuB,CAAC;IACzC,eAAe,CAAC,EAAE,kBAAkB,CAAC;IACrC,+EAA+E;IAC/E,KAAK,CAAC,EAAE,QAAQ,CAAC;CAClB;AAED,eAAO,MAAM,2BAA2B,QAW8J,CAAC;AAEvM;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,gBAAqB,GAAG,SAAS,CAgGzE"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAgC,MAAM,wBAAwB,CAAC;AAE7F,OAAO,EAAmB,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG1D,OAAO,EAAE,0BAA0B,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACvG,OAAO,EAAa,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEzE,OAAO,EAAmB,KAAK,sBAAsB,EAA6B,MAAM,mBAAmB,CAAC;AAE5G,MAAM,WAAW,gBAAgB;IAC/B,uGAAuG;IACvG,eAAe,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,WAAW,CAAC,CAAC;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,iBAAiB,CAAC,EAAE,sBAAsB,CAAC;IAC3C,eAAe,CAAC,EAAE,qBAAqB,CAAC;IACxC,iBAAiB,CAAC,EAAE,kBAAkB,CAAC;IACvC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,WAAW,CAAC,EAAE,0BAA0B,CAAC;IACzC,eAAe,CAAC,EAAE,yBAAyB,CAAC;IAC5C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACrC,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;IAC/B,WAAW,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAClC,cAAc,CAAC,EAAE,uBAAuB,CAAC;IACzC,eAAe,CAAC,EAAE,kBAAkB,CAAC;IACrC,+EAA+E;IAC/E,KAAK,CAAC,EAAE,QAAQ,CAAC;CAClB;AAED,eAAO,MAAM,2BAA2B,QAW8J,CAAC;AAEvM;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,gBAAqB,GAAG,SAAS,CA4GzE"}
@@ -14,6 +14,7 @@ import { applianceSshExecutor } from "./appliance/executor.js";
14
14
  import { mockApplianceExecutor } from "./appliance/mock.js";
15
15
  import { telemetry } from "./telemetry/index.js";
16
16
  import { CanonicalLabBridge } from "./canonical/bridge.js";
17
+ import { HostReadSession } from "./host/session.js";
17
18
  export const DEFAULT_SERVER_INSTRUCTIONS = "You are connected to @calltelemetry/ct-lab-mcp, the unified Call Telemetry lab, fleet, and appliance management MCP server.\n\n" +
18
19
  "Capabilities:\n" +
19
20
  "- Multi-Hypervisor Capacity & Health: Query Proxmox VE (proxmox-lab, proxmox-mini) and VMware ESXi (esxi-intel-192-168-123-176) with 'list_hosts'.\n" +
@@ -102,6 +103,16 @@ export function createMcpServer(options = {}) {
102
103
  }),
103
104
  plane: options.plane,
104
105
  };
106
+ // No host tools are exposed. Transport options are never derived from ToolContext credentials.
107
+ if (options.hostReadSession) {
108
+ const { enrollment, transport } = options.hostReadSession;
109
+ Object.defineProperty(server, "_createHostReadSession", {
110
+ // A future trusted connection adapter owns the returned session and its lifecycle.
111
+ // Two connections on one server never share a latched principal/session identity.
112
+ value: (authority) => new HostReadSession(context.canonicalBridge, { enrollment, transport, authority }),
113
+ writable: false, enumerable: false,
114
+ });
115
+ }
105
116
  // 6. Register all MCP tools
106
117
  registerAllTools(server, context);
107
118
  // Attach context for testing and reflection
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,EAAyB,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAe,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,eAAe,EAAiB,MAAM,iBAAiB,CAAC;AAEjE,OAAO,EAAwB,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EAAyB,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEnF,OAAO,EAAE,SAAS,EAAqB,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAG3D,OAAO,EAAE,eAAe,EAA0D,MAAM,mBAAmB,CAAC;AA0B5G,MAAM,CAAC,MAAM,2BAA2B,GACtC,iIAAiI;IACjI,iBAAiB;IACjB,sJAAsJ;IACtJ,oKAAoK;IACpK,6LAA6L;IAC7L,0hBAA0hB;IAC1hB,wHAAwH;IACxH,qdAAqd;IACrd,iMAAiM;IACjM,iOAAiO;IACjO,oMAAoM,CAAC;AAEvM;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,UAA4B,EAAE;IAC5D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,YAAY,CAAC;IAC1C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,eAAe,CAAC;IACnD,MAAM,WAAW,GACf,OAAO,CAAC,WAAW;QACnB,2GAA2G,CAAC;IAC9G,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,2BAA2B,CAAC;IAEzE,6BAA6B;IAC7B,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,4BAA4B,CAAC;IAEhF,8BAA8B;IAC9B,IAAI,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAClD,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,iBAAiB,GAAG,IAAI,sBAAsB,CAAC;YAC7C,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,WAAW;YAC7D,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,YAAY,EAAE,eAAe;YAC7B,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC,CAAC;IACL,CAAC;IAED,kBAAkB;IAClB,IAAI,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IACtC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,WAAW,GAAG,IAAI,WAAW,CAAC;YAC5B,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,iBAAiB;YACjB,eAAe;YACf,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,IAAI,SAAS;YACzD,WAAW,EAAE,IAAI;SAClB,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,WAAW,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;QACpD,WAAW,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;IAClD,CAAC;IAED,+BAA+B;IAC/B,IAAI,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAClD,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,MAAM,MAAM,GACV,OAAO,CAAC,SAAS;YACjB,OAAO,CAAC,WAAW,EAAE,IAAI,KAAK,eAAe,CAAC;QAEhD,IAAI,MAAM,EAAE,CAAC;YACX,iBAAiB,GAAG,qBAAqB,CAAC;QAC5C,CAAC;aAAM,CAAC;YACN,iBAAiB,GAAG,oBAAoB,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B;QACE,IAAI;QACJ,OAAO;QACP,WAAW;KACZ,EACD;QACE,YAAY,EAAE;YACZ,KAAK,EAAE;gBACL,WAAW,EAAE,IAAI;aAClB;YACD,OAAO,EAAE,EAAE;SACZ;QACD,YAAY;KACb,CACF,CAAC;IAEF,MAAM,OAAO,GAAgB;QAC3B,WAAW;QACX,iBAAiB;QACjB,eAAe;QACf,iBAAiB;QACjB,cAAc,EAAE,OAAO,CAAC,cAAc;QACtC,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,eAAe,EAAE,OAAO,CAAC,eAAe;QACxC,aAAa,EAAE,OAAO,CAAC,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,WAAW,EAAE,IAAI,KAAK,eAAe,CAAC;QAC1F,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,IAAI,kBAAkB,CAAC;YACjE,WAAW,EAAE,OAAO,CAAC,WAAW;SACjC,CAAC;QACF,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC;IAEF,+FAA+F;IAC/F,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;QAC5B,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC;QAC1D,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,wBAAwB,EAAE;YACtD,mFAAmF;YACnF,kFAAkF;YAClF,KAAK,EAAE,CAAC,SAA+B,EAAE,EAAE,CAAC,IAAI,eAAe,CAAC,OAAO,CAAC,eAAgB,EACtF,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;YACvC,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK;SACnC,CAAC,CAAC;IACL,CAAC;IAED,4BAA4B;IAC5B,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAElC,4CAA4C;IAC5C,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE;QACxC,KAAK,EAAE,OAAO;QACd,QAAQ,EAAE,KAAK;QACf,UAAU,EAAE,KAAK;KAClB,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@calltelemetry/ct-lab-mcp",
3
- "version": "0.8.40",
3
+ "version": "0.8.42",
4
4
  "description": "Expanded Model Context Protocol (MCP) server for Call Telemetry lab, fleet, and appliance management across Proxmox VE and VMware ESXi.",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",