@kya-os/agentshield-nextjs
Version:
Next.js middleware for AgentShield AI agent detection
151 lines (147 loc) • 5.41 kB
text/typescript
import { NextRequest, NextResponse } from 'next/server';
import { DetectionResult, PolicyConfig, PolicyEvaluationResult, PolicyEvaluationContext } from '@kya-os/agentshield-shared';
export { DEFAULT_POLICY, ENFORCEMENT_ACTIONS, PolicyConfig, PolicyEvaluationContext, PolicyEvaluationResult, createEvaluationContext, evaluatePolicy } from '@kya-os/agentshield-shared';
/**
* Policy Integration for agentshield-nextjs
*
* This module provides policy evaluation support for the Next.js middleware.
* It can use:
* - Local policy configuration (static)
* - Fetched policy from AgentShield API (dynamic with caching)
* - Fallback/default policies
*
* @example
* ```typescript
* import { createPolicyMiddleware } from '@kya-os/agentshield-nextjs/policy';
*
* export default createPolicyMiddleware({
* policy: {
* enabled: true,
* defaultAction: 'allow',
* thresholds: { confidenceThreshold: 80, confidenceAction: 'block' },
* allowList: [{ clientName: 'ChatGPT' }],
* },
* });
* ```
*/
/**
* Policy middleware configuration
*/
interface PolicyMiddlewareConfig {
/**
* Local policy configuration (static)
* If provided, this policy is used instead of fetching from API
*/
policy?: Partial<PolicyConfig>;
/**
* Fetch policy from AgentShield API
* Requires projectId and optionally an apiKey
*/
fetchPolicy?: {
/** Project ID to fetch policy for */
projectId: string;
/** API base URL (defaults to production) */
apiUrl?: string;
/** API key for authentication */
apiKey?: string;
/** Cache TTL in seconds (default: 300) */
cacheTtlSeconds?: number;
};
/**
* Fallback policy to use when fetch fails
* Defaults to DEFAULT_POLICY (allow all)
*/
fallbackPolicy?: Partial<PolicyConfig>;
/**
* Custom blocked response
*/
blockedResponse?: {
status?: number;
message?: string;
headers?: Record<string, string>;
};
/**
* Default redirect URL for redirect actions
*/
redirectUrl?: string;
/**
* Callback when policy decision is made
*/
onPolicyDecision?: (request: NextRequest, decision: PolicyEvaluationResult, context: PolicyEvaluationContext) => void | Promise<void>;
/**
* Custom response builder for blocked requests
*/
customBlockedResponse?: (request: NextRequest, decision: PolicyEvaluationResult) => NextResponse | Promise<NextResponse>;
/**
* Whether to fail open (allow) on policy evaluation errors
* Default: true (recommended for production)
*/
failOpen?: boolean;
/**
* Enable debug logging
*/
debug?: boolean;
}
/**
* Combined middleware configuration with policy support
*/
interface NextJSPolicyMiddlewareConfig extends PolicyMiddlewareConfig {
/**
* Paths to skip (in addition to policy excludedPaths)
*/
skipPaths?: string[];
/**
* Only enforce on these paths (overrides policy includedPaths)
*/
includePaths?: string[];
}
/**
* Create policy evaluation context from detection result and request
*/
declare function createContextFromDetection(detection: DetectionResult, request: NextRequest): PolicyEvaluationContext;
/**
* Evaluate policy for a detection result
*/
declare function evaluatePolicyForDetection(detection: DetectionResult, request: NextRequest, policy: PolicyConfig): PolicyEvaluationResult;
/**
* Build blocked response based on policy decision
*/
declare function buildBlockedResponse(decision: PolicyEvaluationResult, config: PolicyMiddlewareConfig): NextResponse;
/**
* Build redirect response based on policy decision
*/
declare function buildRedirectResponse(request: NextRequest, decision: PolicyEvaluationResult, config: PolicyMiddlewareConfig): NextResponse;
/**
* Build challenge response (placeholder - future implementation)
*/
declare function buildChallengeResponse(request: NextRequest, decision: PolicyEvaluationResult, config: PolicyMiddlewareConfig): NextResponse;
/**
* Handle policy decision and return appropriate response
*/
declare function handlePolicyDecision(request: NextRequest, decision: PolicyEvaluationResult, config: PolicyMiddlewareConfig): Promise<NextResponse | null>;
/**
* Get policy (local, fetched, or fallback)
*/
declare function getPolicy(config: PolicyMiddlewareConfig): Promise<PolicyConfig>;
/**
* Apply policy to a detection result
*
* This function can be used standalone to evaluate policy after detection.
* Supports extended config with skipPaths and includePaths for path-based filtering.
*
* @example
* ```typescript
* const result = await detector.analyze(context);
* const response = await applyPolicy(request, result, {
* policy: { thresholds: { confidenceThreshold: 80 } },
* skipPaths: ['/health', '/api/public/*'],
* includePaths: ['/api/*'],
* });
*
* if (response) {
* return response; // Policy blocked the request
* }
* ```
*/
declare function applyPolicy(request: NextRequest, detection: DetectionResult, config: NextJSPolicyMiddlewareConfig): Promise<NextResponse | null>;
export { type NextJSPolicyMiddlewareConfig, type PolicyMiddlewareConfig, applyPolicy, buildBlockedResponse, buildChallengeResponse, buildRedirectResponse, createContextFromDetection, evaluatePolicyForDetection, getPolicy, handlePolicyDecision };