/** * Operator-supplied URL safety guard for the ACP REST endpoints. * * Two operator-controlled paths reach `fetch()` in this codebase: * 1. POST /api/agents/acp/discover → discoverAgents(baseUrl) (no auth forwarded) * 2. POST /api/agents/acp/test → new ACPClient({endpoint, auth}) (auth IS forwarded) * * Without validation, an authenticated operator (or someone holding a * leaked admin token) could: * * SSRF: probe internal services via http://127.0.0.1:6379/..., * http://169.254.169.254/latest/meta-data/, IPv6 ULA, link-local. * * Credential exfil: send `auth.token` to an attacker-chosen host * (via /test). * * The guard: * * Enforces http/https scheme (rejects file:, gopher:, etc.). * * For credentialed calls, requires https. * * Resolves the hostname via DNS and refuses loopback, link-local, * and RFC1918 / IPv6 ULA addresses. This catches both a literal IP * (192.168.1.1) and a name that resolves to one * (metadata.internal → 169.254.169.254). * * Escape hatch: AGIM_ACP_ALLOW_LOOPBACK=1 disables the private-address * block. Intended for development against `localhost:` ACP * services; never set this in shared deployments. * * Callers should also pass `redirect: 'manual'` to fetch() so an * allowed origin can't 302 the request into a blocked address. */ export interface AssertSafeOptions { /** When true, only https URLs are accepted (the request will carry a * bearer / apikey token). Drops the http allowance entirely so a * passive on-path observer can't sniff the token. */ forwardsCredentials: boolean; } type LookupHost = (hostname: string) => Promise<{ address: string; family: number; }>; export declare class UnsafeAcpUrlError extends Error { readonly reason: string; constructor(message: string, reason: string); } export declare function assertSafeAcpUrl(raw: string, opts: AssertSafeOptions, lookupHost?: LookupHost): Promise; /** RFC1918 + loopback + link-local + IPv6 ULA + 0.0.0.0. Exported for * unit tests. */ export declare function isPrivateAddr(ip: string, family: 4 | 6): boolean; export {}; //# sourceMappingURL=url-guard.d.ts.map