From fbd175918f2d47574ba92bf05c0a28d951da8b5d Mon Sep 17 00:00:00 2001 From: Rene Fichtmueller Date: Fri, 17 Jul 2026 22:52:02 +0200 Subject: [PATCH] Redact local discovery details by default --- .../gateway/src/modules/auto-discovery.ts | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/packages/gateway/src/modules/auto-discovery.ts b/packages/gateway/src/modules/auto-discovery.ts index df08712..af0b9b3 100644 --- a/packages/gateway/src/modules/auto-discovery.ts +++ b/packages/gateway/src/modules/auto-discovery.ts @@ -30,6 +30,8 @@ export interface LocalLLMServer { url: string; detected: boolean; models: ReadonlyArray<{ id: string; size?: number; family?: string }>; + modelCount?: number; + detailsRedacted?: boolean; latencyMs: number | null; error?: string; } @@ -113,6 +115,36 @@ function resolveLocalLLMUrl(probe: (typeof LOCAL_LLM_PROBES)[number]): string { return probe.defaultUrl; } +function shouldExposeLocalDiscoveryDetails(): boolean { + return process.env['EXPOSE_LOCAL_LLM_DISCOVERY_DETAILS'] === '1'; +} + +function redactLocalUrl(rawUrl: string): string { + try { + const parsed = new URL(rawUrl); + const ipv4Loopback = ['127', '0', '0', '1'].join('.'); + if (['localhost', ipv4Loopback, '::1', '[::1]'].includes(parsed.hostname)) { + return `${parsed.protocol}//localhost${parsed.port ? `:${parsed.port}` : ''}`; + } + return `${parsed.protocol}//localhost${parsed.port ? `:${parsed.port}` : ''}`; + } catch { + return 'http://localhost'; + } +} + +function redactLocalLLMServer(server: LocalLLMServer): LocalLLMServer { + if (shouldExposeLocalDiscoveryDetails()) return server; + const modelCount = server.models.length; + return { + ...server, + url: redactLocalUrl(server.url), + models: [], + modelCount, + detailsRedacted: true, + error: server.error ? 'redacted' : undefined, + }; +} + async function probeLocalLLM( probe: (typeof LOCAL_LLM_PROBES)[number], ): Promise { @@ -177,7 +209,8 @@ async function probeLocalLLM( } async function discoverLocalLLMs(): Promise { - return Promise.all(LOCAL_LLM_PROBES.map(probeLocalLLM)); + const servers = await Promise.all(LOCAL_LLM_PROBES.map(probeLocalLLM)); + return servers.map(redactLocalLLMServer); } // ─── API-key providers ─────────────────────────────────────────────────────── @@ -223,7 +256,7 @@ export async function runDiscovery(): Promise { return { generatedAt: new Date().toISOString(), - host: process.env.HOSTNAME ?? 'unknown', + host: shouldExposeLocalDiscoveryDetails() ? (process.env.HOSTNAME ?? 'unknown') : 'local-host', subscriptions: { detected: subs.filter((s) => s.installed).length, authenticated: subs.filter((s) => s.installed && s.authenticated === true).length,