/** * Agent & MCP Security Scanner Types * * Types for scanning MCP servers, agent systems, and AI tool chains. * These scanners extend the deterministic scanner layer with agent-specific * security checks: prompt injection fuzzing, exfiltration path analysis, * manifest auditing, and permission minimization. * * @module scanners/agent/types */ import { z } from "zod"; import type { Severity } from "../../certification/types.js"; import type { ScannerResult } from "../types.js"; /** * Supported agent scanner types */ export type AgentScannerType = "manifest-audit" | "tool-description-drift" | "prompt-injection-fuzzer" | "exfil-path-graph" | "permission-minimiser" | "supply-chain-mcp" | "sandbox-audit" | "credential-scope-audit"; /** * All agent scanner types as an array for iteration */ export declare const AGENT_SCANNER_TYPES: AgentScannerType[]; /** * MCP tool parameter schema (subset of JSON Schema) */ export interface MCPParameterSchema { type: string; description?: string; required?: boolean; enum?: string[]; default?: unknown; properties?: Record; items?: MCPParameterSchema; } /** * MCP tool definition from server manifest */ export interface MCPToolDefinition { /** Tool name (e.g., "read_file") */ name: string; /** Human-readable description */ description: string; /** Zod-validated input schema or JSON schema */ inputSchema?: MCPParameterSchema | z.ZodTypeAny; /** Whether this tool can modify state (write, delete, etc.) */ destructiveHint?: boolean; /** Whether this tool only reads data */ readOnlyHint?: boolean; /** Allowed origins for cross-origin requests */ allowedOrigins?: string[]; /** Whether this tool can access network */ networkAccess?: boolean; /** Whether this tool can execute code */ codeExecution?: boolean; /** Required permissions/scopes */ requiredPermissions?: string[]; } /** * MCP resource definition */ export interface MCPResourceDefinition { /** Resource URI template (e.g., "file://{path}") */ uri: string; /** Human-readable name */ name: string; /** Description of the resource */ description?: string; /** MIME type of the resource content */ mimeType?: string; } /** * MCP prompt definition */ export interface MCPPromptDefinition { /** Prompt name */ name: string; /** Human-readable description */ description?: string; /** Arguments the prompt accepts */ arguments?: { name: string; description?: string; required?: boolean; }[]; } /** * Complete MCP server manifest */ export interface MCPManifest { /** Server name */ name: string; /** Server version */ version: string; /** Human-readable description */ description?: string; /** Available tools */ tools: MCPToolDefinition[]; /** Available resources */ resources?: MCPResourceDefinition[]; /** Available prompts */ prompts?: MCPPromptDefinition[]; /** Server capabilities */ capabilities?: { tools?: boolean; resources?: boolean; prompts?: boolean; logging?: boolean; }; /** Server configuration */ config?: Record; } /** * Zod schema for MCPManifest validation */ export declare const MCPManifestSchema: z.ZodObject<{ name: z.ZodString; version: z.ZodString; description: z.ZodOptional; tools: z.ZodArray; destructiveHint: z.ZodOptional; readOnlyHint: z.ZodOptional; allowedOrigins: z.ZodOptional>; networkAccess: z.ZodOptional; codeExecution: z.ZodOptional; requiredPermissions: z.ZodOptional>; }, "strip", z.ZodTypeAny, { name: string; description: string; readOnlyHint?: boolean | undefined; inputSchema?: any; destructiveHint?: boolean | undefined; allowedOrigins?: string[] | undefined; networkAccess?: boolean | undefined; codeExecution?: boolean | undefined; requiredPermissions?: string[] | undefined; }, { name: string; description: string; readOnlyHint?: boolean | undefined; inputSchema?: any; destructiveHint?: boolean | undefined; allowedOrigins?: string[] | undefined; networkAccess?: boolean | undefined; codeExecution?: boolean | undefined; requiredPermissions?: string[] | undefined; }>, "many">; resources: z.ZodOptional; mimeType: z.ZodOptional; }, "strip", z.ZodTypeAny, { name: string; uri: string; description?: string | undefined; mimeType?: string | undefined; }, { name: string; uri: string; description?: string | undefined; mimeType?: string | undefined; }>, "many">>; prompts: z.ZodOptional; arguments: z.ZodOptional; required: z.ZodOptional; }, "strip", z.ZodTypeAny, { name: string; description?: string | undefined; required?: boolean | undefined; }, { name: string; description?: string | undefined; required?: boolean | undefined; }>, "many">>; }, "strip", z.ZodTypeAny, { name: string; description?: string | undefined; arguments?: { name: string; description?: string | undefined; required?: boolean | undefined; }[] | undefined; }, { name: string; description?: string | undefined; arguments?: { name: string; description?: string | undefined; required?: boolean | undefined; }[] | undefined; }>, "many">>; capabilities: z.ZodOptional; resources: z.ZodOptional; prompts: z.ZodOptional; logging: z.ZodOptional; }, "strip", z.ZodTypeAny, { tools?: boolean | undefined; resources?: boolean | undefined; prompts?: boolean | undefined; logging?: boolean | undefined; }, { tools?: boolean | undefined; resources?: boolean | undefined; prompts?: boolean | undefined; logging?: boolean | undefined; }>>; config: z.ZodOptional>; }, "strip", z.ZodTypeAny, { name: string; version: string; tools: { name: string; description: string; readOnlyHint?: boolean | undefined; inputSchema?: any; destructiveHint?: boolean | undefined; allowedOrigins?: string[] | undefined; networkAccess?: boolean | undefined; codeExecution?: boolean | undefined; requiredPermissions?: string[] | undefined; }[]; description?: string | undefined; config?: Record | undefined; resources?: { name: string; uri: string; description?: string | undefined; mimeType?: string | undefined; }[] | undefined; prompts?: { name: string; description?: string | undefined; arguments?: { name: string; description?: string | undefined; required?: boolean | undefined; }[] | undefined; }[] | undefined; capabilities?: { tools?: boolean | undefined; resources?: boolean | undefined; prompts?: boolean | undefined; logging?: boolean | undefined; } | undefined; }, { name: string; version: string; tools: { name: string; description: string; readOnlyHint?: boolean | undefined; inputSchema?: any; destructiveHint?: boolean | undefined; allowedOrigins?: string[] | undefined; networkAccess?: boolean | undefined; codeExecution?: boolean | undefined; requiredPermissions?: string[] | undefined; }[]; description?: string | undefined; config?: Record | undefined; resources?: { name: string; uri: string; description?: string | undefined; mimeType?: string | undefined; }[] | undefined; prompts?: { name: string; description?: string | undefined; arguments?: { name: string; description?: string | undefined; required?: boolean | undefined; }[] | undefined; }[] | undefined; capabilities?: { tools?: boolean | undefined; resources?: boolean | undefined; prompts?: boolean | undefined; logging?: boolean | undefined; } | undefined; }>; /** * Extended scanner result for agent-specific scanners */ export interface AgentScannerResult extends Omit { /** Which agent scanner was run */ scanner: AgentScannerType; /** Target MCP server URL, config file, or npm package */ target?: string; /** SHA256 hash of scanned manifest */ manifestHash?: string; /** MCP server name if available */ mcpServerName?: string; /** MCP server version if available */ mcpServerVersion?: string; } /** * Check if an agent scanner is available */ export interface AgentScannerAvailability { scanner: AgentScannerType; available: boolean; version?: string; path?: string; error?: string; } /** * Categories of prompt injection payloads */ export type PayloadCategory = "override-instructions" | "exfil-prompt" | "homoglyph" | "tag-smuggling" | "indirect-injection" | "jailbreak" | "system-prompt-extraction" | "tool-misuse" | "multi-turn" | "context-manipulation" | "output-redirection" | "token-smuggling" | "mcp-specific" | "tool-chaining" | "privilege-escalation"; /** * A single injection payload */ export interface InjectionPayload { /** Unique payload ID */ id: string; /** The payload text to inject */ text: string; /** Category of attack */ category: PayloadCategory; /** Expected severity if injection succeeds */ severity: Severity; /** Human-readable description of what this payload attempts */ description: string; /** Tags for filtering (e.g., ["unicode", "invisible"]) */ tags?: string[]; /** Source/attribution if from known research */ source?: string; } /** * Result of fuzzing a single tool with a single payload */ export interface FuzzResult { /** The payload that was tested */ payload: string; /** Payload ID for reference */ payloadId: string; /** Category of the payload */ payloadCategory: PayloadCategory; /** Which tool was fuzzed */ tool: string; /** Whether the injection was blocked (true = safe) */ passed: boolean; /** Raw response from the tool (redacted for sensitive data) */ response?: string; /** Whether the model's behavior changed due to injection */ behaviorChange: boolean; /** Specific indicators of behavior change detected */ behaviorIndicators?: string[]; /** Assigned severity based on behavior change */ severity: Severity; /** Time taken for this fuzz test in ms */ duration: number; /** Error if the fuzz test failed to execute */ error?: string; } /** * Aggregated fuzzer results */ export interface FuzzerSummary { /** Total payloads tested */ totalPayloads: number; /** Payloads that were blocked (passed) */ passedCount: number; /** Payloads that caused behavior changes (failed) */ failedCount: number; /** Pass rate as percentage */ passRate: number; /** Breakdown by payload category */ byCategory: Record; /** Breakdown by tool */ byTool: Record; /** Most vulnerable tools (highest failure rate) */ vulnerableTools: string[]; /** Most effective payload categories */ effectiveCategories: PayloadCategory[]; } /** * Options for running the fuzzer */ export interface FuzzerOptions { /** Corpus size: quick (~100), standard (~400), thorough (~800), exhaustive (~1000+) */ corpus?: "quick" | "standard" | "thorough" | "exhaustive"; /** Path to custom payload file or directory */ customCorpus?: string; /** Specific categories to test */ categories?: PayloadCategory[]; /** Specific tools to fuzz (default: all) */ tools?: string[]; /** Timeout per fuzz test in ms */ timeout?: number; /** Maximum parallel fuzz tests */ concurrency?: number; /** Stop on first failure */ failFast?: boolean; /** Redact sensitive data in responses */ redactResponses?: boolean; } /** * Classification of a tool's capabilities */ export type ToolCapability = "reads_secrets" | "reads_files" | "reads_env" | "reads_database" | "writes_files" | "writes_database" | "network_access" | "executes_code" | "modifies_state" | "sends_email" | "sends_webhook" | "accesses_external_api"; /** * A node in the tool capability graph */ export interface ToolNode { /** Tool name */ name: string; /** Tool description */ description: string; /** Classified capabilities */ capabilities: ToolCapability[]; /** Risk score (0-100) */ riskScore: number; /** Whether this tool could be a source of secrets */ isSecretSource: boolean; /** Whether this tool has network/external access */ isNetworkSink: boolean; } /** * An edge representing data flow between tools */ export interface ToolEdge { /** Source tool name */ source: string; /** Target tool name */ target: string; /** Type of data flow */ dataFlow: "input" | "output" | "chained" | "implicit"; /** Description of the flow */ description?: string; } /** * A potential exfiltration path through the tool graph */ export interface ExfilPath { /** Tool that reads secrets/sensitive data */ source: string; /** Tool with network/external access */ sink: string; /** Intermediate tools in the path */ path: string[]; /** Full path including source and sink */ fullPath: string[]; /** Risk level based on path characteristics */ riskLevel: Severity; /** Description of the exfiltration risk */ description: string; /** Suggested mitigations */ mitigations: string[]; } /** * Complete tool capability graph */ export interface ToolGraph { /** All tools as nodes */ nodes: Map; /** Data flow edges between tools */ edges: ToolEdge[]; /** Identified exfiltration paths */ exfilPaths: ExfilPath[]; /** Minimal set of tools to sandbox to cut all paths */ cutSet: string[]; /** Mermaid diagram representation */ mermaidDiagram: string; } /** * Types of manifest audit findings */ export type ManifestAuditCheck = "missing-destructive-hint" | "missing-readonly-hint" | "missing-input-schema" | "unbounded-origins" | "version-drift" | "missing-description" | "excessive-permissions" | "undeclared-network" | "undeclared-code-execution"; /** * A finding from manifest audit */ export interface ManifestAuditFinding { /** Type of issue found */ check: ManifestAuditCheck; /** Severity of the finding */ severity: Severity; /** Which tool has the issue */ tool: string; /** Human-readable description */ description: string; /** Suggested fix */ suggestion: string; /** Current value if applicable */ currentValue?: unknown; /** Expected value if applicable */ expectedValue?: unknown; } /** * Types of drift that can occur in tool definitions */ export type DriftType = "tool-added" | "tool-removed" | "description-changed" | "schema-changed" | "permission-changed" | "capability-changed"; /** * A baseline snapshot of a tool definition */ export interface ToolBaseline { /** Tool name */ name: string; /** Hash of tool definition */ hash: string; /** Original description */ description: string; /** Original input schema hash */ schemaHash: string; /** Original hints */ hints: { destructive?: boolean; readOnly?: boolean; }; /** Timestamp when baseline was captured */ capturedAt: string; } /** * Complete baseline for an MCP server */ export interface ServerBaseline { /** MCP server name */ serverName: string; /** Server version at baseline */ version: string; /** Overall manifest hash */ manifestHash: string; /** Individual tool baselines */ tools: ToolBaseline[]; /** When the baseline was signed */ signedAt: string; /** Signature if available */ signature?: string; } /** * A detected drift from baseline */ export interface DriftFinding { /** Type of drift */ type: DriftType; /** Severity based on drift type */ severity: Severity; /** Affected tool name */ tool: string; /** Description of the change */ description: string; /** Value in baseline */ baselineValue?: string; /** Current value */ currentValue?: string; /** When the drift was detected */ detectedAt: string; } /** * A record of actual tool usage */ export interface ToolUsageRecord { /** Tool name */ tool: string; /** Number of invocations */ invocations: number; /** Arguments patterns seen */ argumentPatterns: string[]; /** Files/resources accessed */ resourcesAccessed: string[]; /** Last used timestamp */ lastUsed: string; /** First used timestamp */ firstUsed: string; } /** * A permission tightening proposal */ export interface PermissionProposal { /** Type of proposal */ type: "disable-unused" | "scope-down" | "remove-permission" | "add-constraint"; /** Affected tool */ tool: string; /** Current permission/state */ current: string; /** Proposed permission/state */ proposed: string; /** Rationale for the change */ rationale: string; /** Risk reduction if applied (0-100) */ riskReduction: number; /** Confidence in the proposal (0-100) */ confidence: number; } /** * Supply chain vulnerability in MCP server dependencies */ export interface MCPSupplyChainVuln { /** Vulnerable package name */ package: string; /** Installed version */ installedVersion: string; /** Fixed version if available */ fixedVersion?: string; /** CVE ID if applicable */ cveId?: string; /** GHSA ID if applicable */ ghsaId?: string; /** Severity */ severity: Severity; /** Description */ description: string; /** Whether the package is a direct or transitive dependency */ isDirect: boolean; /** Dependency path if transitive */ dependencyPath?: string[]; } /** * Sigstore verification result */ export interface SigstoreVerification { /** Whether the package/release is signed */ isSigned: boolean; /** Whether the signature is valid */ signatureValid?: boolean; /** Certificate issuer */ issuer?: string; /** Certificate subject */ subject?: string; /** Signature timestamp */ signedAt?: string; /** Verification errors */ errors?: string[]; } /** * Sandbox escape patterns to detect */ export type SandboxEscape = "child_process" | "eval" | "Function" | "vm" | "require" | "import-dynamic" | "fs-outside-scope" | "net-undeclared" | "env-access" | "process-access"; /** * A sandbox escape finding */ export interface SandboxFinding { /** Type of escape */ escape: SandboxEscape; /** Tool with the escape */ tool: string; /** File where escape was found */ file: string; /** Line number */ line: number; /** Code snippet */ evidence: string; /** Severity (most are critical or high) */ severity: Severity; /** Description */ description: string; } /** * Credential types we can audit */ export type CredentialType = "github-pat" | "github-app" | "aws-access-key" | "aws-iam-role" | "gcp-service-account" | "azure-service-principal" | "api-key" | "oauth-token" | "jwt" | "sigstore-audience" | "unknown"; /** * Scope overprovisioning finding */ export interface CredentialScopeFinding { /** Type of credential */ credentialType: CredentialType; /** Identifier (redacted) */ identifier: string; /** Current scopes/permissions */ currentScopes: string[]; /** Recommended scopes based on usage */ recommendedScopes: string[]; /** Unused scopes that could be removed */ unusedScopes: string[]; /** Severity */ severity: Severity; /** Age of the credential in days */ ageInDays?: number; /** Whether rotation is recommended */ rotationRecommended: boolean; /** Last rotation date if known */ lastRotated?: string; } /** * Target for agent scanning */ export interface AgentScanTarget { /** MCP server URL (stdio or HTTP) */ url?: string; /** Path to MCP config file (server.json, mcp.json) */ configFile?: string; /** npm package name */ npmPackage?: string; /** Path to MCP server source code */ sourcePath?: string; /** Pre-loaded manifest (skip discovery) */ manifest?: MCPManifest; } /** * Options for running agent scanners */ export interface AgentScannerOptions { /** Target to scan */ target: AgentScanTarget; /** Which scanners to run */ scanners?: { manifestAudit?: boolean; toolDrift?: boolean; promptInjection?: boolean; exfilPath?: boolean; permissionMinimiser?: boolean; supplyChain?: boolean; sandboxAudit?: boolean; credentialScope?: boolean; }; /** Path to baselines for drift detection */ baselinesDir?: string; /** Path to tool traces for permission analysis */ tracesDir?: string; /** Fuzzer options (legacy, prefer specific options below) */ fuzzerOptions?: FuzzerOptions; /** Explicit authorization for scanning (required) */ authorized: boolean; /** Timeout per scanner in milliseconds */ timeout?: number; /** Maximum parallel scanners */ concurrency?: number; /** Skip specific manifest audit checks */ manifestAuditSkipChecks?: ManifestAuditCheck[]; /** Only run specific manifest audit checks */ manifestAuditOnlyChecks?: ManifestAuditCheck[]; /** Create baseline if none exists */ createBaselineIfMissing?: boolean; /** Force create a new baseline (overwrite existing) */ forceNewBaseline?: boolean; /** Skip specific drift types */ driftSkipTypes?: DriftType[]; /** Fuzzer corpus size: quick (~100), standard (~400), thorough (~800), exhaustive (~1000+) */ fuzzerCorpus?: "quick" | "standard" | "thorough" | "exhaustive"; /** Path to custom payload directory */ customPayloadsDir?: string; /** Specific payload categories to test */ fuzzerCategories?: PayloadCategory[]; /** Specific tools to fuzz (default: all) */ fuzzerTools?: string[]; /** Timeout per fuzz test in ms */ fuzzerTimeout?: number; /** Stop fuzzer on first failure */ fuzzerFailFast?: boolean; /** Include all edges in diagram (default: only exfil paths) */ exfilIncludeAllEdges?: boolean; /** Maximum path length to consider */ exfilMaxPathLength?: number; /** Output file for permission proposals */ permissionProposalsOutput?: string; /** Minimum confidence threshold (0-100) */ permissionMinConfidence?: number; /** Minimum risk reduction threshold (0-100) */ permissionMinRiskReduction?: number; /** Path to MCP server package */ supplyChainPackagePath?: string; /** Skip npm audit */ supplyChainSkipVulnScan?: boolean; /** Skip license check */ supplyChainSkipLicenseCheck?: boolean; /** Skip typosquatting check */ supplyChainSkipTyposquatCheck?: boolean; /** Skip Sigstore verification */ supplyChainSkipSigstoreCheck?: boolean; /** Path to scan for source files */ sandboxSourcePath?: string; /** Maximum directory depth */ sandboxMaxDepth?: number; /** Patterns to exclude */ sandboxExclude?: RegExp[]; /** Only check specific tools */ sandboxTools?: string[]; /** Directory to scan for config files */ credentialScanPath?: string; /** Also scan environment variables */ credentialScanEnvironment?: boolean; /** Additional files to scan */ credentialAdditionalFiles?: string[]; } /** * Default agent scanner options */ export declare const DEFAULT_AGENT_SCANNER_OPTIONS: Partial; /** * Aggregated results from running all agent scanners */ export interface AggregatedAgentScanResult { /** When the scan started */ timestamp: string; /** Target that was scanned */ target: AgentScanTarget; /** MCP manifest if discovered */ manifest?: MCPManifest; /** Manifest hash */ manifestHash?: string; /** Results from each scanner */ scanners: AgentScannerResult[]; /** Total findings across all scanners */ totalFindings: number; /** Findings grouped by severity */ bySeverity: Record; /** Findings grouped by scanner */ byScanner: Partial>; /** Total scan duration in milliseconds */ totalDuration: number; /** Whether all scanners succeeded */ allSucceeded: boolean; /** Scanners that failed */ failedScanners: AgentScannerType[]; /** Fuzzer summary if run */ fuzzerSummary?: FuzzerSummary; /** Exfil graph if computed */ exfilGraph?: ToolGraph; /** Permission proposals if computed */ permissionProposals?: PermissionProposal[]; /** Overall risk score (0-100) */ riskScore: number; /** Certification readiness */ certificationReadiness: "ready" | "needs-review" | "blocked"; } /** * Convert agent scanner type to finding ID prefix */ export declare function toAgentFindingId(scanner: AgentScannerType, index: number): string; /** * Severity mappings for agent scanner findings */ export declare const AGENT_SEVERITY_MAPPINGS: Record; //# sourceMappingURL=types.d.ts.map