import "../../_dnt.polyfills.js"; import type { Agent } from "../agent/types.js"; import type { DiscoveryResult } from "../discovery/index.js"; import type { HandlerContext } from "../types/server.js"; import type { InferSchema, Schema } from "../extensions/schema/index.js"; /** Shared control plane agents list path value. */ export declare const CONTROL_PLANE_AGENTS_LIST_PATH = "/api/control-plane/agents/list"; /** Shared control plane runs path prefix value. */ export declare const CONTROL_PLANE_RUNS_PATH_PREFIX = "/api/control-plane/runs/"; /** Shared control plane run stream path value. */ export declare const CONTROL_PLANE_RUN_STREAM_PATH = "/api/control-plane/runs/:runId/stream"; /** Request header the control plane carries its signed operation envelope in. */ export declare const CONTROL_PLANE_JWS_HEADER = "x-veryfront-control-plane-jws"; /** Request header a platform channel dispatch carries its signed envelope in. */ export declare const DISPATCH_JWS_HEADER = "x-veryfront-dispatch-jws"; /** The one route that accepts a signed channel dispatch envelope. */ export declare const CHANNEL_INVOKE_PATH = "/channels/invoke"; /** * True when a method and path pair addresses a registered control-plane handler. * * The reserved namespace is wider than the set of routes the runtime actually * serves. Only these shapes reach a handler that authenticates a signed * operation envelope through `verifyControlPlaneRequest`: * * - `POST /api/control-plane/agents/list` * - `POST /api/control-plane/runs/{runId}/execute` * - `POST /api/control-plane/runs/{runId}/stream` * - `POST /api/control-plane/runs/{runId}/resume` * - `DELETE /api/control-plane/runs/{runId}` * * Any other path under the prefix falls through to project code, so treating * the prefix as proof of a control-plane request would hand a project's own * routes whatever exemption the caller grants. * * Match this against `URL.pathname`, which resolves dot segments, so a path * cannot be smuggled past the anchored patterns. */ export declare function isControlPlaneSurfaceRoute(method: string, pathname: string | undefined): boolean; /** * True for a request that is a control-plane dispatch rather than a browser one. * * Both conditions must hold. The method and path must address a registered * control-plane handler (see {@link isControlPlaneSurfaceRoute}), and the * request must carry a control-plane signature header. The receiving handler * verifies that envelope against the dispatch signing key, and the signature * covers the request method and path, so an envelope minted for one surface * cannot be replayed against another. * * Callers use this to keep gates that assume a browser client, such as CSRF * double-submit validation, from standing in front of platform dispatch. * * Do not read a true result as evidence that the caller is the platform, and do * not argue the exemption is safe because the header is hard to attach. It is * not hard to attach. A project can configure a permissive `security.cors`, and * on the default path `resolveNormalizedCORSPreflightPolicy` reflects whatever * `Access-Control-Request-Headers` asked for, so the runtime will advertise this * header to a cross-origin caller. The proxy likewise forwards an unverified * `x-veryfront-*-jws` from a public request rather than stripping it. Assume an * attacker can set this header at will. * * The exemption is safe for a narrower reason that does not depend on who can * set the header. Skipping the gate concedes only the browser-credential check; * authority still comes from the signature the receiving handler verifies, which * an attacker cannot forge. And every route this predicate admits is owned by a * handler registered ahead of `ApiHandlerWrapper` and instantiated * unconditionally, so an admitted request always terminates at that verification * and can never fall through to project code. A forged header buys a different * rejection, nothing more. That ordering is the load-bearing part; it is pinned * by `server/runtime-handler/dispatch-exemption-ordering.test.ts`, and the * behaviour it protects by `security/http/dispatch-exemption-matrix.test.ts`. * * A project route that merely sits at a look-alike path is not a registered * surface and does not satisfy this predicate at all. * * This is not authentication. It only reports that authority for the request * comes from a signature the handler checks, never from ambient credentials. */ export declare function isSignedControlPlaneDispatch(req: Request): boolean; /** * True when a method and path pair addresses the channel dispatch handler. * * `POST /channels/invoke` is the one route `ChannelInvokeHandler` registers, * and the only route that verifies a channel dispatch envelope. It is * deliberately not part of {@link isControlPlaneSurfaceRoute}: the control * plane's `channels` surface names a product surface inside a control-plane * envelope, not this HTTP route, and this route carries a different envelope. * * The `/channels/` namespace is reserved but not exclusively routed, so any * sibling or child path is matched exactly rather than by prefix. Match this * against `URL.pathname`, which resolves dot segments. */ export declare function isChannelDispatchRoute(method: string, pathname: string | undefined): boolean; /** * True for a request that is a platform channel dispatch rather than a browser one. * * Both conditions must hold. The method and path must be the one route the * channel invoke handler owns (see {@link isChannelDispatchRoute}), and the * request must carry a dispatch signature header. The handler then verifies * that envelope with `verifyDispatchJws`, which binds the Ed25519 signature to * the issuer, the project audience, the project id, the dispatch id, the * platform and a SHA-256 hash of the body, with expiry and skew bounds; the * handler additionally rejects an envelope whose claims do not match the * dispatch id, platform and project id in the payload it acts on. * * Callers use this to keep gates that assume a browser client, such as CSRF * double-submit validation, from standing in front of platform dispatch. The * channel dispatcher and the runtime-owner re-dispatch in * `resolveRuntimeOwnerInvokeUrl` hold no `__Host-vf_csrf` cookie to echo and * derive no authority from one. * * As with {@link isSignedControlPlaneDispatch}, assume an attacker can set this * header: a permissive project `security.cors` makes the runtime advertise it on * a preflight, and the proxy forwards an unverified one. The exemption is safe * because it concedes only the browser-credential check (authority still comes * from the envelope `ChannelInvokeHandler` verifies, which an attacker cannot * forge), and because `ChannelInvokeHandler` is registered ahead of * `ApiHandlerWrapper` and instantiated unconditionally, so an admitted request * always terminates at that verification rather than at project code. * * This is not authentication. It only reports that authority for the request * comes from a signature the handler checks, never from ambient credentials. */ export declare function isSignedChannelDispatch(req: Request): boolean; /** * True for control-plane run surfaces that can dispatch without project config. * * Stream/resume/cancel use signed request payload/session state and must not be * blocked by stale release config bootstraps. Execute deliberately remains * strict because it can consume project config for React/CSS build inputs. */ export declare function isConfigOptionalControlPlaneRunRequest(method: string, pathname: string | undefined): boolean; /** Allowed control-plane surfaces — source of truth for the schema and {@link ControlPlaneSurface}. */ export declare const CONTROL_PLANE_SURFACES: readonly ["studio", "channels", "a2a", "mcp"]; /** Zod schema for get control plane surface. */ export declare const getControlPlaneSurfaceSchema: () => Schema<"mcp" | "studio" | "channels" | "a2a">; /** Zod schema for control plane surface. */ export declare const ControlPlaneSurfaceSchema: Schema<"mcp" | "studio" | "channels" | "a2a">; /** Zod schema for get control plane agents list request. */ export declare const getControlPlaneAgentsListRequestSchema: () => Schema; projectId: Schema; surface: Schema<"mcp" | "studio" | "channels" | "a2a">; }>>; /** Zod schema for control plane agents list request. */ export declare const ControlPlaneAgentsListRequestSchema: Schema; projectId: Schema; surface: Schema<"mcp" | "studio" | "channels" | "a2a">; }>>; /** Zod schema for get runtime agent skill. */ export declare const getRuntimeAgentSkillSchema: () => Schema; name: Schema; description: Schema; tags: Schema; examples: Schema; }>>; /** Zod schema for runtime agent skill. */ export declare const RuntimeAgentSkillSchema: Schema; name: Schema; description: Schema; tags: Schema; examples: Schema; }>>; /** Zod schema for get runtime suggestion. */ export declare const getRuntimeSuggestionSchema: () => Schema; title: Schema; prompt: Schema; }> | import("../extensions/schema/schema-validator.js").InferShape<{ id: Schema; type: Schema<"prompt">; }> | import("../extensions/schema/schema-validator.js").InferShape<{ type: Schema<"task">; id: Schema; }>>; /** Zod schema for runtime suggestion. */ export declare const RuntimeSuggestionSchema: Schema; title: Schema; prompt: Schema; }> | import("../extensions/schema/schema-validator.js").InferShape<{ id: Schema; type: Schema<"prompt">; }> | import("../extensions/schema/schema-validator.js").InferShape<{ type: Schema<"task">; id: Schema; }>>; /** Zod schema for get runtime suggestions. */ export declare const getRuntimeSuggestionsSchema: () => Schema; suggestions: Schema<(import("../extensions/schema/schema-validator.js").InferShape<{ type: Schema<"prompt">; title: Schema; prompt: Schema; }> | import("../extensions/schema/schema-validator.js").InferShape<{ id: Schema; type: Schema<"prompt">; }> | import("../extensions/schema/schema-validator.js").InferShape<{ type: Schema<"task">; id: Schema; }>)[]>; }>>; /** Zod schema for runtime suggestions. */ export declare const RuntimeSuggestionsSchema: Schema; suggestions: Schema<(import("../extensions/schema/schema-validator.js").InferShape<{ type: Schema<"prompt">; title: Schema; prompt: Schema; }> | import("../extensions/schema/schema-validator.js").InferShape<{ id: Schema; type: Schema<"prompt">; }> | import("../extensions/schema/schema-validator.js").InferShape<{ type: Schema<"task">; id: Schema; }>)[]>; }>>; /** Zod schema for get runtime agent. */ export declare const getRuntimeAgentSchema: () => Schema; name: Schema; description: Schema; avatar_url: Schema; model: Schema; version: Schema; skills: Schema; name: Schema; description: Schema; tags: Schema; examples: Schema; }>[] | undefined>; suggestions: Schema; suggestions: Schema<(import("../extensions/schema/schema-validator.js").InferShape<{ type: Schema<"prompt">; title: Schema; prompt: Schema; }> | import("../extensions/schema/schema-validator.js").InferShape<{ id: Schema; type: Schema<"prompt">; }> | import("../extensions/schema/schema-validator.js").InferShape<{ type: Schema<"task">; id: Schema; }>)[]>; }> | undefined>; }>>; /** Zod schema for runtime agent. */ export declare const RuntimeAgentSchema: Schema; name: Schema; description: Schema; avatar_url: Schema; model: Schema; version: Schema; skills: Schema; name: Schema; description: Schema; tags: Schema; examples: Schema; }>[] | undefined>; suggestions: Schema; suggestions: Schema<(import("../extensions/schema/schema-validator.js").InferShape<{ type: Schema<"prompt">; title: Schema; prompt: Schema; }> | import("../extensions/schema/schema-validator.js").InferShape<{ id: Schema; type: Schema<"prompt">; }> | import("../extensions/schema/schema-validator.js").InferShape<{ type: Schema<"task">; id: Schema; }>)[]>; }> | undefined>; }>>; /** Zod schema for get runtime agent list response. */ export declare const getRuntimeAgentListResponseSchema: () => Schema; name: Schema; description: Schema; avatar_url: Schema; model: Schema; version: Schema; skills: Schema; name: Schema; description: Schema; tags: Schema; examples: Schema; }>[] | undefined>; suggestions: Schema; suggestions: Schema<(import("../extensions/schema/schema-validator.js").InferShape<{ type: Schema<"prompt">; title: Schema; prompt: Schema; }> | import("../extensions/schema/schema-validator.js").InferShape<{ id: Schema; type: Schema<"prompt">; }> | import("../extensions/schema/schema-validator.js").InferShape<{ type: Schema<"task">; id: Schema; }>)[]>; }> | undefined>; }>[]>; }>>; /** Zod schema for runtime agent list response. */ export declare const RuntimeAgentListResponseSchema: Schema; name: Schema; description: Schema; avatar_url: Schema; model: Schema; version: Schema; skills: Schema; name: Schema; description: Schema; tags: Schema; examples: Schema; }>[] | undefined>; suggestions: Schema; suggestions: Schema<(import("../extensions/schema/schema-validator.js").InferShape<{ type: Schema<"prompt">; title: Schema; prompt: Schema; }> | import("../extensions/schema/schema-validator.js").InferShape<{ id: Schema; type: Schema<"prompt">; }> | import("../extensions/schema/schema-validator.js").InferShape<{ type: Schema<"task">; id: Schema; }>)[]>; }> | undefined>; }>[]>; }>>; /** Zod schema for get dispatch claims. */ declare const getDispatchClaimsSchema: () => Schema; aud: Schema; sub: Schema; project_id: Schema; platform: Schema; body_sha256: Schema; iat: Schema; exp: Schema; }>>; /** Zod schema for get control plane claims. */ declare const getControlPlaneClaimsSchema: () => Schema; aud: Schema; sub: Schema; surface: Schema<"mcp" | "studio" | "channels" | "a2a">; project_id: Schema; request_hash: Schema; request_method: Schema; request_path: Schema; iat: Schema; exp: Schema; }>>; /** Public API contract for control plane surface (literal union, not widened to `string`). */ export type ControlPlaneSurface = (typeof CONTROL_PLANE_SURFACES)[number]; /** Request payload for control plane agents list. */ export type ControlPlaneAgentsListRequest = InferSchema>; /** Public API contract for runtime agent skill. */ export type RuntimeAgentSkill = InferSchema>; /** Public API contract for runtime suggestion. */ export type RuntimeSuggestion = InferSchema>; /** Public API contract for runtime suggestions. */ export type RuntimeSuggestions = InferSchema>; /** Public API contract for runtime agent. */ export type RuntimeAgent = InferSchema>; /** Public API contract for browser-safe runtime agent metadata. */ export type RuntimeAgentPublicMetadata = Pick; /** Response payload for runtime agent list. */ export type RuntimeAgentListResponse = InferSchema>; /** Public API contract for dispatch claims. */ export type DispatchClaims = InferSchema>; /** Public API contract for control plane claims. */ export type ControlPlaneClaims = InferSchema>; /** Public API contract for runtime agent discovery deps. */ export interface RuntimeAgentDiscoveryDeps { ensureProjectDiscovery: (ctx: HandlerContext) => Promise; getAgent: (id: string) => Agent | undefined; getAllAgentIds: () => string[]; } export declare function resolveAgentSkills(agent: Agent): RuntimeAgentSkill[]; /** Get browser-safe runtime metadata for an agent. */ export declare function getRuntimeAgentPublicMetadata(id: string, agent: Agent): RuntimeAgentPublicMetadata; /** List runtime agents. */ export declare function listRuntimeAgents(ctx: HandlerContext, deps: RuntimeAgentDiscoveryDeps): Promise; /** * Verify the Ed25519 signature of a dispatch JWS and the recency of its * timestamps, without binding to a particular request body or audience. * * This is intentionally weaker than {@link verifyDispatchJws}: it answers * "was this JWS minted by a holder of the control-plane private key and is it * still fresh?" and is used as a trust signal in code paths (proxy-trust, * adapter selection) that don't yet have access to the authoritative request * body or project audience. Callers that consume request payloads MUST still * call {@link verifyDispatchJws} / {@link verifyControlPlaneJws} to bind the * signature to the body and project. * * Returns true iff the signature verifies and `iat`/`exp` are within the * allowed skew and max-age window. All other failures (including parsing * errors) resolve to false so callers can treat the signal as present-but-not- * proven without raising. */ export declare function verifyDispatchJwsSignature(jws: string, options: { audience?: string; expectedProjectId?: string; publicKeyPem: string; maxAgeSeconds: number; }): Promise; /** * Verify the signature, freshness, and exact HTTP operation binding of a * control-plane JWS without granting body or subject authorization. * * This is still not sufficient to authorize a request. Request handlers must * use {@link verifyControlPlaneJws} to bind the signature to the request body. */ export declare function verifyControlPlaneJwsSignature(jws: string, options: { audience?: string; expectedProjectId?: string; publicKeyPem: string; maxAgeSeconds: number; requestMethod: string; requestPath: string; }): Promise; /** * Verify a control-plane JWS against its request body without depending on the * extension-backed schema registry. * * The split proxy uses this after it has resolved the project audience. It * needs the signed body binding before it may turn target metadata in the body * into trusted downstream headers, while the authoritative request handler * still performs the full schema-backed verification. */ export declare function verifyControlPlaneJwsRequestSignature(jws: string, body: string, options: { audience: string; expectedProjectId?: string; publicKeyPem: string; maxAgeSeconds: number; requestMethod: string; requestPath: string; }): Promise; /** Verify dispatch JWS. */ export declare function verifyDispatchJws(jws: string, body: string, options: { audience: string; expectedPlatform?: string; expectedProjectId?: string; expectedSubject?: string; maxAgeSeconds: number; publicKeyPem: string; }): Promise; /** Verify a control-plane JWS against its body and canonical HTTP operation. */ export declare function verifyControlPlaneJws(jws: string, body: string, options: { audience: string; expectedProjectId?: string; expectedSubject?: string; expectedSurface?: ControlPlaneSurface; maxAgeSeconds: number; publicKeyPem: string; requestMethod: string; requestPath: string; }): Promise; export {}; //# sourceMappingURL=control-plane.d.ts.map