@kya-os/agentshield-nextjs
v0.1.41
Published
Next.js middleware for AgentShield AI agent detection
Downloads
123
Readme
@kya-os/agentshield-nextjs
Next.js middleware and React hooks for AgentShield AI agent detection and protection.
Features
- 🚀 Next.js Middleware: Edge-compatible middleware for all routes
- ⚛️ React Hooks: Client-side detection and monitoring
- 🎯 Flexible Actions: Block, redirect, rewrite, or log detected agents
- 🛡️ Edge Runtime: Optimized for Vercel Edge Functions
- 📊 Built-in Analytics: Track detection patterns and statistics
Installation
npm install @kya-os/agentshield-nextjsQuick Start
Middleware Setup
Create middleware.js (or middleware.ts) in your project root:
import { agentShield } from '@kya-os/agentshield-nextjs';
export default agentShield({
onAgentDetected: 'block',
confidenceThreshold: 0.8,
// NEW: Session tracking (v0.1.27+)
sessionTracking: {
enabled: true, // Track continued sessions from AI agents
},
});
export const config = {
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};React Hooks
'use client';
import { useAgentDetection } from '@kya-os/agentshield-nextjs';
export default function SecurityMonitor() {
const { detect, isDetecting, lastResult } = useAgentDetection({
confidenceThreshold: 0.7,
});
const handleCheck = async () => {
const result = await detect();
if (result.isAgent) {
alert('Agent detected!');
}
};
return (
<div>
<button onClick={handleCheck} disabled={isDetecting}>
{isDetecting ? 'Checking...' : 'Check for Agents'}
</button>
{lastResult && (
<div>
<p>Is Agent: {lastResult.isAgent ? 'Yes' : 'No'}</p>
<p>Confidence: {(lastResult.confidence * 100).toFixed(1)}%</p>
</div>
)}
</div>
);
}Middleware Configuration
import { agentShield } from '@kya-os/agentshield-nextjs';
export default agentShield({
// Core detection options
confidenceThreshold: 0.7,
enablePatternMatching: true,
enableBehaviorAnalysis: true,
// Action when agent is detected
onAgentDetected: 'block', // 'block' | 'redirect' | 'rewrite' | 'allow' | 'log'
// Skip detection for paths
skipPaths: ['/api/webhooks', /^\/admin/],
// Custom responses
blockedResponse: {
status: 403,
message: 'Access denied',
},
redirectUrl: '/blocked',
rewriteUrl: '/blocked',
// Custom handler
onDetection: async (request, result) => {
console.log('Agent detected:', result);
// Return custom NextResponse or void
},
});Actions
Block Agents
export default agentShield({
onAgentDetected: 'block',
blockedResponse: {
status: 403,
message: 'Automated access not allowed',
headers: {
'Content-Type': 'application/json',
'X-Robots-Tag': 'noindex',
},
},
});Redirect Agents
export default agentShield({
onAgentDetected: 'redirect',
redirectUrl: '/blocked',
confidenceThreshold: 0.8,
});Rewrite Requests
export default agentShield({
onAgentDetected: 'rewrite',
rewriteUrl: '/bot-content',
confidenceThreshold: 0.6,
});Custom Logic
export default agentShield({
onDetection: async (request, result) => {
if (result.confidence > 0.9) {
// High confidence - block
return NextResponse.json({ error: 'Blocked' }, { status: 403 });
} else if (result.confidence > 0.5) {
// Medium confidence - redirect to captcha
return NextResponse.redirect(new URL('/verify', request.url));
}
// Low confidence - continue
},
});React Hooks
useAgentDetection
Client-side agent detection:
import { useAgentDetection } from '@kya-os/agentshield-nextjs';
function SecurityComponent() {
const { detect, isDetecting, lastResult, detector } = useAgentDetection({
confidenceThreshold: 0.7,
});
useEffect(() => {
// Auto-detect on component mount
detect();
}, [detect]);
return (
<div>
{lastResult?.isAgent && (
<div className='alert'>Agent detected with {lastResult.confidence} confidence</div>
)}
</div>
);
}useDetectionMonitor
Monitor and track detection events:
import { useDetectionMonitor } from '@kya-os/agentshield-nextjs';
function AnalyticsDashboard() {
const { detectionHistory, getStats, clearHistory } = useDetectionMonitor(context => {
// Handle each detection
console.log('Detection event:', context);
});
const stats = getStats();
return (
<div>
<h2>Detection Statistics</h2>
<p>Total Requests: {stats.total}</p>
<p>Agents Detected: {stats.detected}</p>
<p>Detection Rate: {(stats.detectionRate * 100).toFixed(1)}%</p>
<p>Average Confidence: {(stats.avgConfidence * 100).toFixed(1)}%</p>
<button onClick={clearHistory}>Clear History</button>
</div>
);
}API Routes Integration
Protect API routes with server-side detection:
// pages/api/protected.js or app/api/protected/route.js
import { AgentDetector } from '@kya-os/agentshield';
const detector = new AgentDetector();
export async function GET(request) {
const context = {
userAgent: request.headers.get('user-agent'),
ip: request.ip,
headers: Object.fromEntries(request.headers.entries()),
};
const result = await detector.analyze(context);
if (result.isAgent && result.confidence > 0.7) {
return NextResponse.json({ error: 'Automated access detected' }, { status: 403 });
}
return NextResponse.json({ data: 'Protected content' });
}Advanced Usage
Path-Specific Configuration
import { NextRequest, NextResponse } from 'next/server';
import { AgentDetector } from '@kya-os/agentshield';
const detector = new AgentDetector();
export async function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
// Different thresholds for different paths
let threshold = 0.7;
if (pathname.startsWith('/api/')) {
threshold = 0.5; // More sensitive for API
} else if (pathname.startsWith('/admin/')) {
threshold = 0.9; // Less sensitive for admin (humans expected)
}
const context = {
userAgent: request.headers.get('user-agent') ?? undefined,
ip: request.ip,
headers: Object.fromEntries(request.headers.entries()),
url: request.url,
};
const result = await detector.analyze(context);
if (result.isAgent && result.confidence >= threshold) {
return NextResponse.json(
{ error: 'Access denied' },
{ status: 403 }
);
}
return NextResponse.next();
}Server Components
Use detection results in Server Components:
// app/dashboard/page.tsx
import { headers } from 'next/headers';
import { AgentDetector } from '@kya-os/agentshield';
export default async function Dashboard() {
const headersList = headers();
const detector = new AgentDetector();
const result = await detector.analyze({
userAgent: headersList.get('user-agent') ?? undefined,
headers: Object.fromEntries(headersList.entries()),
});
if (result.isAgent) {
return <div>Automated access detected</div>;
}
return <div>Welcome to the dashboard!</div>;
}TypeScript Support
Full TypeScript support with proper types:
import { NextRequest } from 'next/server';
import { agentShield, NextJSMiddlewareConfig } from '@kya-os/agentshield-nextjs';
const config: NextJSMiddlewareConfig = {
onAgentDetected: 'block',
confidenceThreshold: 0.8,
onDetection: async (request: NextRequest, result) => {
// Fully typed parameters
console.log(result.confidence);
},
};
export default agentShield(config);Examples
E-commerce Protection
// Protect product pages from scrapers
export default agentShield({
onAgentDetected: 'redirect',
redirectUrl: '/captcha',
confidenceThreshold: 0.6,
skipPaths: ['/api/webhooks', '/health'],
});
export const config = {
matcher: ['/products/:path*', '/search/:path*'],
};Content Publishing
// Allow search engines, block other bots
export default agentShield({
onDetection: async (request, result) => {
const userAgent = request.headers.get('user-agent') || '';
// Allow known search engines
if (/googlebot|bingbot|slurp/i.test(userAgent)) {
return; // Continue
}
// Block other agents
if (result.isAgent && result.confidence > 0.5) {
return NextResponse.json({ error: 'Bot access restricted' }, { status: 403 });
}
},
});License
MIT OR Apache-2.0
