UNPKG

@kya-os/agentshield-nextjs

Version:

Next.js middleware for AgentShield AI agent detection

196 lines (194 loc) 5.51 kB
/** * AgentShield API Client * * Lightweight client for calling the AgentShield enforce API from middleware. * Designed for Edge Runtime compatibility (no Node.js-specific APIs). */ /** * API client configuration */ interface AgentShieldClientConfig { /** API key for authentication */ apiKey: string; /** API base URL (defaults to production) */ baseUrl?: string; /** * Use edge detection for lower latency (~30-50ms vs ~150ms) and better coverage. * Edge detection can identify non-JS clients (curl, Python, Claude Code WebFetch) * that the pixel cannot detect since they don't execute JavaScript. * @default true */ useEdge?: boolean; /** Request timeout in milliseconds (default: 5000) */ timeout?: number; /** Enable debug logging */ debug?: boolean; } /** * Enforcement action */ type EnforcementAction = 'allow' | 'block' | 'redirect' | 'challenge' | 'log'; /** * Enforcement decision from the API */ interface EnforcementDecision { action: EnforcementAction; reason: string; isAgent: boolean; confidence: number; agentName?: string; agentType?: string; redirectUrl?: string; message?: string; metadata?: { policyVersion?: string; signatureVerified?: boolean; denyListMatch?: { clientDid?: string; agentDid?: string; clientName?: string; reason?: string; }; }; } /** * Detection result (optional in response) */ interface DetectionResult { isAgent: boolean; confidence: number; agentName?: string; agentType?: string; /** Detection class: 'human', 'ai_agent', 'bot', 'incomplete_data' */ detectionClass?: string; verificationMethod?: string; reasons?: string[]; /** Detection engine used: 'wasm' or 'javascript-fallback' */ detectionMethod?: string; } /** * Enforce API response */ interface EnforceResponse { success: boolean; data?: { decision: EnforcementDecision; processingTimeMs: number; requestId: string; detection?: DetectionResult; }; error?: { code: string; message: string; }; } /** * Request input for enforce API */ interface EnforceInput { /** HTTP headers from the incoming request */ headers?: Record<string, string>; /** User-Agent header */ userAgent?: string; /** Client IP address */ ipAddress?: string; /** Request path */ path?: string; /** Request URL */ url?: string; /** HTTP method */ method?: string; /** Request ID for tracing */ requestId?: string; /** Options */ options?: { /** Include full detection result */ includeDetectionResult?: boolean; /** Cache TTL override */ cacheTTL?: number; }; } /** * Input for logging a detection result */ interface LogDetectionInput { /** Detection result from Gateway */ detection: DetectionResult; /** Request context */ context: { userAgent?: string; ipAddress?: string; path?: string; url?: string; method?: string; }; /** Source of the detection */ source?: 'gateway' | 'middleware'; } /** * AgentShield API Client * * @example * ```typescript * const client = new AgentShieldClient({ * apiKey: process.env.AGENTSHIELD_API_KEY!, * }); * * const result = await client.enforce({ * headers: Object.fromEntries(request.headers), * path: request.nextUrl.pathname, * method: request.method, * }); * * if (result.decision.action === 'block') { * return new Response('Access denied', { status: 403 }); * } * ``` */ declare class AgentShieldClient { private apiKey; private baseUrl; private useEdge; private timeout; private debug; constructor(config: AgentShieldClientConfig); /** * Call the enforce API to check if a request should be allowed */ enforce(input: EnforceInput): Promise<EnforceResponse>; /** * Quick check - returns just the action without full response parsing * Useful for very fast middleware that just needs allow/block */ quickCheck(input: EnforceInput): Promise<{ action: EnforcementAction; error?: string; }>; /** * Check if this client is using edge detection (Gateway Worker) */ isUsingEdge(): boolean; /** * Log a detection result to AgentShield database. * Use after Gateway Worker detection to persist results. * Fire-and-forget - returns immediately without waiting for DB write. * * @example * ```typescript * // After receiving Gateway response * if (client.isUsingEdge() && response.data?.detection) { * client.logDetection({ * detection: response.data.detection, * context: { userAgent, ipAddress, path, url, method } * }).catch(err => console.error('Log failed:', err)); * } * ``` */ logDetection(input: LogDetectionInput): Promise<void>; } declare function getAgentShieldClient(config?: Partial<AgentShieldClientConfig>): AgentShieldClient; /** * Reset the singleton client (useful for testing) */ declare function resetAgentShieldClient(): void; export { AgentShieldClient, type AgentShieldClientConfig, type DetectionResult, type EnforceInput, type EnforceResponse, type EnforcementAction, type EnforcementDecision, type LogDetectionInput, getAgentShieldClient, resetAgentShieldClient };