@kya-os/agentshield-nextjs 0.1.41 → 0.1.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/dist/.tsbuildinfo +1 -0
  2. package/dist/api-client.d.mts +145 -0
  3. package/dist/api-client.d.ts +145 -0
  4. package/dist/api-client.js +130 -0
  5. package/dist/api-client.js.map +1 -0
  6. package/dist/api-client.mjs +126 -0
  7. package/dist/api-client.mjs.map +1 -0
  8. package/dist/api-middleware.d.mts +118 -0
  9. package/dist/api-middleware.d.ts +118 -0
  10. package/dist/api-middleware.js +295 -0
  11. package/dist/api-middleware.js.map +1 -0
  12. package/dist/api-middleware.mjs +292 -0
  13. package/dist/api-middleware.mjs.map +1 -0
  14. package/dist/create-middleware.d.mts +2 -1
  15. package/dist/create-middleware.d.ts +2 -1
  16. package/dist/create-middleware.js +474 -200
  17. package/dist/create-middleware.js.map +1 -1
  18. package/dist/create-middleware.mjs +454 -200
  19. package/dist/create-middleware.mjs.map +1 -1
  20. package/dist/edge/index.d.mts +110 -0
  21. package/dist/edge/index.d.ts +110 -0
  22. package/dist/edge/index.js +253 -0
  23. package/dist/edge/index.js.map +1 -0
  24. package/dist/edge/index.mjs +251 -0
  25. package/dist/edge/index.mjs.map +1 -0
  26. package/dist/edge-detector-wrapper.d.mts +6 -15
  27. package/dist/edge-detector-wrapper.d.ts +6 -15
  28. package/dist/edge-detector-wrapper.js +314 -95
  29. package/dist/edge-detector-wrapper.js.map +1 -1
  30. package/dist/edge-detector-wrapper.mjs +294 -95
  31. package/dist/edge-detector-wrapper.mjs.map +1 -1
  32. package/dist/edge-runtime-loader.d.mts +1 -1
  33. package/dist/edge-runtime-loader.d.ts +1 -1
  34. package/dist/edge-runtime-loader.js +10 -25
  35. package/dist/edge-runtime-loader.js.map +1 -1
  36. package/dist/edge-runtime-loader.mjs +11 -23
  37. package/dist/edge-runtime-loader.mjs.map +1 -1
  38. package/dist/edge-wasm-middleware.js +2 -1
  39. package/dist/edge-wasm-middleware.js.map +1 -1
  40. package/dist/edge-wasm-middleware.mjs +2 -1
  41. package/dist/edge-wasm-middleware.mjs.map +1 -1
  42. package/dist/enhanced-middleware.d.mts +153 -0
  43. package/dist/enhanced-middleware.d.ts +153 -0
  44. package/dist/enhanced-middleware.js +1074 -0
  45. package/dist/enhanced-middleware.js.map +1 -0
  46. package/dist/enhanced-middleware.mjs +1072 -0
  47. package/dist/enhanced-middleware.mjs.map +1 -0
  48. package/dist/index.d.mts +8 -153
  49. package/dist/index.d.ts +8 -153
  50. package/dist/index.js +821 -233
  51. package/dist/index.js.map +1 -1
  52. package/dist/index.mjs +797 -234
  53. package/dist/index.mjs.map +1 -1
  54. package/dist/middleware.d.mts +2 -1
  55. package/dist/middleware.d.ts +2 -1
  56. package/dist/middleware.js +474 -200
  57. package/dist/middleware.js.map +1 -1
  58. package/dist/middleware.mjs +454 -200
  59. package/dist/middleware.mjs.map +1 -1
  60. package/dist/session-tracker.d.mts +1 -1
  61. package/dist/session-tracker.d.ts +1 -1
  62. package/dist/session-tracker.js.map +1 -1
  63. package/dist/session-tracker.mjs.map +1 -1
  64. package/dist/signature-verifier.d.mts +1 -0
  65. package/dist/signature-verifier.d.ts +1 -0
  66. package/dist/signature-verifier.js +204 -44
  67. package/dist/signature-verifier.js.map +1 -1
  68. package/dist/signature-verifier.mjs +184 -44
  69. package/dist/signature-verifier.mjs.map +1 -1
  70. package/dist/{types-BJTEUa4T.d.mts → types-DVmy9NE3.d.mts} +19 -2
  71. package/dist/{types-BJTEUa4T.d.ts → types-DVmy9NE3.d.ts} +19 -2
  72. package/dist/wasm-middleware.js +15 -6
  73. package/dist/wasm-middleware.js.map +1 -1
  74. package/dist/wasm-middleware.mjs +15 -6
  75. package/dist/wasm-middleware.mjs.map +1 -1
  76. package/package.json +27 -6
  77. package/wasm/agentshield_wasm.js +209 -152
  78. package/wasm/agentshield_wasm_bg.wasm +0 -0
  79. package/wasm/package.json +30 -0
@@ -0,0 +1,130 @@
1
+ 'use strict';
2
+
3
+ // src/api-client.ts
4
+ var DEFAULT_BASE_URL = "https://api.agentshield.ai";
5
+ var DEFAULT_TIMEOUT = 5e3;
6
+ var AgentShieldClient = class {
7
+ apiKey;
8
+ baseUrl;
9
+ timeout;
10
+ debug;
11
+ constructor(config) {
12
+ if (!config.apiKey) {
13
+ throw new Error("AgentShield API key is required");
14
+ }
15
+ this.apiKey = config.apiKey;
16
+ this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;
17
+ this.timeout = config.timeout || DEFAULT_TIMEOUT;
18
+ this.debug = config.debug || false;
19
+ }
20
+ /**
21
+ * Call the enforce API to check if a request should be allowed
22
+ */
23
+ async enforce(input) {
24
+ const startTime = Date.now();
25
+ try {
26
+ const controller = new AbortController();
27
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
28
+ try {
29
+ const response = await fetch(`${this.baseUrl}/api/v1/enforce`, {
30
+ method: "POST",
31
+ headers: {
32
+ "Content-Type": "application/json",
33
+ Authorization: `Bearer ${this.apiKey}`,
34
+ "X-Request-ID": input.requestId || crypto.randomUUID()
35
+ },
36
+ body: JSON.stringify(input),
37
+ signal: controller.signal
38
+ });
39
+ clearTimeout(timeoutId);
40
+ const data = await response.json();
41
+ if (this.debug) {
42
+ console.log("[AgentShield] Enforce response:", {
43
+ status: response.status,
44
+ action: data.data?.decision.action,
45
+ processingTimeMs: Date.now() - startTime
46
+ });
47
+ }
48
+ if (!response.ok) {
49
+ return {
50
+ success: false,
51
+ error: {
52
+ code: `HTTP_${response.status}`,
53
+ message: data.error?.message || `HTTP error: ${response.status}`
54
+ }
55
+ };
56
+ }
57
+ return data;
58
+ } catch (error) {
59
+ clearTimeout(timeoutId);
60
+ throw error;
61
+ }
62
+ } catch (error) {
63
+ if (error instanceof Error && error.name === "AbortError") {
64
+ if (this.debug) {
65
+ console.warn("[AgentShield] Request timed out");
66
+ }
67
+ return {
68
+ success: false,
69
+ error: {
70
+ code: "TIMEOUT",
71
+ message: `Request timed out after ${this.timeout}ms`
72
+ }
73
+ };
74
+ }
75
+ if (this.debug) {
76
+ console.error("[AgentShield] Request failed:", error);
77
+ }
78
+ return {
79
+ success: false,
80
+ error: {
81
+ code: "NETWORK_ERROR",
82
+ message: error instanceof Error ? error.message : "Network request failed"
83
+ }
84
+ };
85
+ }
86
+ }
87
+ /**
88
+ * Quick check - returns just the action without full response parsing
89
+ * Useful for very fast middleware that just needs allow/block
90
+ */
91
+ async quickCheck(input) {
92
+ const result = await this.enforce(input);
93
+ if (!result.success || !result.data) {
94
+ return {
95
+ action: "allow",
96
+ error: result.error?.message
97
+ };
98
+ }
99
+ return {
100
+ action: result.data.decision.action
101
+ };
102
+ }
103
+ };
104
+ var clientInstance = null;
105
+ function getAgentShieldClient(config) {
106
+ if (!clientInstance) {
107
+ const apiKey = config?.apiKey || process.env.AGENTSHIELD_API_KEY;
108
+ if (!apiKey) {
109
+ throw new Error(
110
+ "AgentShield API key is required. Set AGENTSHIELD_API_KEY environment variable or pass apiKey in config."
111
+ );
112
+ }
113
+ clientInstance = new AgentShieldClient({
114
+ apiKey,
115
+ baseUrl: config?.baseUrl || process.env.AGENTSHIELD_API_URL,
116
+ timeout: config?.timeout,
117
+ debug: config?.debug || process.env.AGENTSHIELD_DEBUG === "true"
118
+ });
119
+ }
120
+ return clientInstance;
121
+ }
122
+ function resetAgentShieldClient() {
123
+ clientInstance = null;
124
+ }
125
+
126
+ exports.AgentShieldClient = AgentShieldClient;
127
+ exports.getAgentShieldClient = getAgentShieldClient;
128
+ exports.resetAgentShieldClient = resetAgentShieldClient;
129
+ //# sourceMappingURL=api-client.js.map
130
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api-client.ts"],"names":[],"mappings":"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","file":"api-client.js","sourcesContent":["/**\n * AgentShield API Client\n *\n * Lightweight client for calling the AgentShield enforce API from middleware.\n * Designed for Edge Runtime compatibility (no Node.js-specific APIs).\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * API client configuration\n */\nexport interface AgentShieldClientConfig {\n /** API key for authentication */\n apiKey: string;\n /** API base URL (defaults to production) */\n baseUrl?: string;\n /** Request timeout in milliseconds (default: 5000) */\n timeout?: number;\n /** Enable debug logging */\n debug?: boolean;\n}\n\n/**\n * Enforcement action\n */\nexport type EnforcementAction = 'allow' | 'block' | 'redirect' | 'challenge' | 'log';\n\n/**\n * Enforcement decision from the API\n */\nexport interface EnforcementDecision {\n action: EnforcementAction;\n reason: string;\n isAgent: boolean;\n confidence: number;\n agentName?: string;\n agentType?: string;\n redirectUrl?: string;\n message?: string;\n metadata?: {\n policyVersion?: string;\n signatureVerified?: boolean;\n denyListMatch?: {\n clientDid?: string;\n agentDid?: string;\n clientName?: string;\n reason?: string;\n };\n };\n}\n\n/**\n * Detection result (optional in response)\n */\nexport interface DetectionResult {\n isAgent: boolean;\n confidence: number;\n agentName?: string;\n agentType?: string;\n verificationMethod?: string;\n reasons?: string[];\n}\n\n/**\n * Enforce API response\n */\nexport interface EnforceResponse {\n success: boolean;\n data?: {\n decision: EnforcementDecision;\n processingTimeMs: number;\n requestId: string;\n detection?: DetectionResult;\n };\n error?: {\n code: string;\n message: string;\n };\n}\n\n/**\n * Request input for enforce API\n */\nexport interface EnforceInput {\n /** HTTP headers from the incoming request */\n headers?: Record<string, string>;\n /** User-Agent header */\n userAgent?: string;\n /** Client IP address */\n ipAddress?: string;\n /** Request path */\n path?: string;\n /** Request URL */\n url?: string;\n /** HTTP method */\n method?: string;\n /** Request ID for tracing */\n requestId?: string;\n /** Options */\n options?: {\n /** Include full detection result */\n includeDetectionResult?: boolean;\n /** Cache TTL override */\n cacheTTL?: number;\n };\n}\n\n// ============================================================================\n// Client Implementation\n// ============================================================================\n\nconst DEFAULT_BASE_URL = 'https://api.agentshield.ai';\nconst DEFAULT_TIMEOUT = 5000;\n\n/**\n * AgentShield API Client\n *\n * @example\n * ```typescript\n * const client = new AgentShieldClient({\n * apiKey: process.env.AGENTSHIELD_API_KEY!,\n * });\n *\n * const result = await client.enforce({\n * headers: Object.fromEntries(request.headers),\n * path: request.nextUrl.pathname,\n * method: request.method,\n * });\n *\n * if (result.decision.action === 'block') {\n * return new Response('Access denied', { status: 403 });\n * }\n * ```\n */\nexport class AgentShieldClient {\n private apiKey: string;\n private baseUrl: string;\n private timeout: number;\n private debug: boolean;\n\n constructor(config: AgentShieldClientConfig) {\n if (!config.apiKey) {\n throw new Error('AgentShield API key is required');\n }\n\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;\n this.timeout = config.timeout || DEFAULT_TIMEOUT;\n this.debug = config.debug || false;\n }\n\n /**\n * Call the enforce API to check if a request should be allowed\n */\n async enforce(input: EnforceInput): Promise<EnforceResponse> {\n const startTime = Date.now();\n\n try {\n // Create abort controller for timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(`${this.baseUrl}/api/v1/enforce`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n 'X-Request-ID': input.requestId || crypto.randomUUID(),\n },\n body: JSON.stringify(input),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n // Parse response\n const data = (await response.json()) as EnforceResponse;\n\n if (this.debug) {\n console.log('[AgentShield] Enforce response:', {\n status: response.status,\n action: data.data?.decision.action,\n processingTimeMs: Date.now() - startTime,\n });\n }\n\n // Handle non-2xx responses\n if (!response.ok) {\n return {\n success: false,\n error: {\n code: `HTTP_${response.status}`,\n message: data.error?.message || `HTTP error: ${response.status}`,\n },\n };\n }\n\n return data;\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n } catch (error) {\n // Handle timeout\n if (error instanceof Error && error.name === 'AbortError') {\n if (this.debug) {\n console.warn('[AgentShield] Request timed out');\n }\n return {\n success: false,\n error: {\n code: 'TIMEOUT',\n message: `Request timed out after ${this.timeout}ms`,\n },\n };\n }\n\n // Handle network errors\n if (this.debug) {\n console.error('[AgentShield] Request failed:', error);\n }\n\n return {\n success: false,\n error: {\n code: 'NETWORK_ERROR',\n message: error instanceof Error ? error.message : 'Network request failed',\n },\n };\n }\n }\n\n /**\n * Quick check - returns just the action without full response parsing\n * Useful for very fast middleware that just needs allow/block\n */\n async quickCheck(input: EnforceInput): Promise<{\n action: EnforcementAction;\n error?: string;\n }> {\n const result = await this.enforce(input);\n\n if (!result.success || !result.data) {\n // On error, default to allow (fail-open)\n return {\n action: 'allow',\n error: result.error?.message,\n };\n }\n\n return {\n action: result.data.decision.action,\n };\n }\n}\n\n/**\n * Create a singleton client instance\n *\n * @example\n * ```typescript\n * // In middleware.ts\n * import { getAgentShieldClient } from '@kya-os/agentshield-nextjs';\n *\n * const client = getAgentShieldClient();\n * ```\n */\nlet clientInstance: AgentShieldClient | null = null;\n\nexport function getAgentShieldClient(config?: Partial<AgentShieldClientConfig>): AgentShieldClient {\n if (!clientInstance) {\n const apiKey = config?.apiKey || process.env.AGENTSHIELD_API_KEY;\n\n if (!apiKey) {\n throw new Error(\n 'AgentShield API key is required. Set AGENTSHIELD_API_KEY environment variable or pass apiKey in config.'\n );\n }\n\n clientInstance = new AgentShieldClient({\n apiKey,\n baseUrl: config?.baseUrl || process.env.AGENTSHIELD_API_URL,\n timeout: config?.timeout,\n debug: config?.debug || process.env.AGENTSHIELD_DEBUG === 'true',\n });\n }\n\n return clientInstance;\n}\n\n/**\n * Reset the singleton client (useful for testing)\n */\nexport function resetAgentShieldClient(): void {\n clientInstance = null;\n}\n"]}
@@ -0,0 +1,126 @@
1
+ // src/api-client.ts
2
+ var DEFAULT_BASE_URL = "https://api.agentshield.ai";
3
+ var DEFAULT_TIMEOUT = 5e3;
4
+ var AgentShieldClient = class {
5
+ apiKey;
6
+ baseUrl;
7
+ timeout;
8
+ debug;
9
+ constructor(config) {
10
+ if (!config.apiKey) {
11
+ throw new Error("AgentShield API key is required");
12
+ }
13
+ this.apiKey = config.apiKey;
14
+ this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;
15
+ this.timeout = config.timeout || DEFAULT_TIMEOUT;
16
+ this.debug = config.debug || false;
17
+ }
18
+ /**
19
+ * Call the enforce API to check if a request should be allowed
20
+ */
21
+ async enforce(input) {
22
+ const startTime = Date.now();
23
+ try {
24
+ const controller = new AbortController();
25
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
26
+ try {
27
+ const response = await fetch(`${this.baseUrl}/api/v1/enforce`, {
28
+ method: "POST",
29
+ headers: {
30
+ "Content-Type": "application/json",
31
+ Authorization: `Bearer ${this.apiKey}`,
32
+ "X-Request-ID": input.requestId || crypto.randomUUID()
33
+ },
34
+ body: JSON.stringify(input),
35
+ signal: controller.signal
36
+ });
37
+ clearTimeout(timeoutId);
38
+ const data = await response.json();
39
+ if (this.debug) {
40
+ console.log("[AgentShield] Enforce response:", {
41
+ status: response.status,
42
+ action: data.data?.decision.action,
43
+ processingTimeMs: Date.now() - startTime
44
+ });
45
+ }
46
+ if (!response.ok) {
47
+ return {
48
+ success: false,
49
+ error: {
50
+ code: `HTTP_${response.status}`,
51
+ message: data.error?.message || `HTTP error: ${response.status}`
52
+ }
53
+ };
54
+ }
55
+ return data;
56
+ } catch (error) {
57
+ clearTimeout(timeoutId);
58
+ throw error;
59
+ }
60
+ } catch (error) {
61
+ if (error instanceof Error && error.name === "AbortError") {
62
+ if (this.debug) {
63
+ console.warn("[AgentShield] Request timed out");
64
+ }
65
+ return {
66
+ success: false,
67
+ error: {
68
+ code: "TIMEOUT",
69
+ message: `Request timed out after ${this.timeout}ms`
70
+ }
71
+ };
72
+ }
73
+ if (this.debug) {
74
+ console.error("[AgentShield] Request failed:", error);
75
+ }
76
+ return {
77
+ success: false,
78
+ error: {
79
+ code: "NETWORK_ERROR",
80
+ message: error instanceof Error ? error.message : "Network request failed"
81
+ }
82
+ };
83
+ }
84
+ }
85
+ /**
86
+ * Quick check - returns just the action without full response parsing
87
+ * Useful for very fast middleware that just needs allow/block
88
+ */
89
+ async quickCheck(input) {
90
+ const result = await this.enforce(input);
91
+ if (!result.success || !result.data) {
92
+ return {
93
+ action: "allow",
94
+ error: result.error?.message
95
+ };
96
+ }
97
+ return {
98
+ action: result.data.decision.action
99
+ };
100
+ }
101
+ };
102
+ var clientInstance = null;
103
+ function getAgentShieldClient(config) {
104
+ if (!clientInstance) {
105
+ const apiKey = config?.apiKey || process.env.AGENTSHIELD_API_KEY;
106
+ if (!apiKey) {
107
+ throw new Error(
108
+ "AgentShield API key is required. Set AGENTSHIELD_API_KEY environment variable or pass apiKey in config."
109
+ );
110
+ }
111
+ clientInstance = new AgentShieldClient({
112
+ apiKey,
113
+ baseUrl: config?.baseUrl || process.env.AGENTSHIELD_API_URL,
114
+ timeout: config?.timeout,
115
+ debug: config?.debug || process.env.AGENTSHIELD_DEBUG === "true"
116
+ });
117
+ }
118
+ return clientInstance;
119
+ }
120
+ function resetAgentShieldClient() {
121
+ clientInstance = null;
122
+ }
123
+
124
+ export { AgentShieldClient, getAgentShieldClient, resetAgentShieldClient };
125
+ //# sourceMappingURL=api-client.mjs.map
126
+ //# sourceMappingURL=api-client.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api-client.ts"],"names":[],"mappings":";AAkHA,IAAM,gBAAA,GAAmB,4BAAA;AACzB,IAAM,eAAA,GAAkB,GAAA;AAsBjB,IAAM,oBAAN,MAAwB;AAAA,EACrB,MAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EAER,YAAY,MAAA,EAAiC;AAC3C,IAAA,IAAI,CAAC,OAAO,MAAA,EAAQ;AAClB,MAAA,MAAM,IAAI,MAAM,iCAAiC,CAAA;AAAA,IACnD;AAEA,IAAA,IAAA,CAAK,SAAS,MAAA,CAAO,MAAA;AACrB,IAAA,IAAA,CAAK,OAAA,GAAU,OAAO,OAAA,IAAW,gBAAA;AACjC,IAAA,IAAA,CAAK,OAAA,GAAU,OAAO,OAAA,IAAW,eAAA;AACjC,IAAA,IAAA,CAAK,KAAA,GAAQ,OAAO,KAAA,IAAS,KAAA;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,KAAA,EAA+C;AAC3D,IAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAE3B,IAAA,IAAI;AAEF,MAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,MAAA,MAAM,YAAY,UAAA,CAAW,MAAM,WAAW,KAAA,EAAM,EAAG,KAAK,OAAO,CAAA;AAEnE,MAAA,IAAI;AACF,QAAA,MAAM,WAAW,MAAM,KAAA,CAAM,CAAA,EAAG,IAAA,CAAK,OAAO,CAAA,eAAA,CAAA,EAAmB;AAAA,UAC7D,MAAA,EAAQ,MAAA;AAAA,UACR,OAAA,EAAS;AAAA,YACP,cAAA,EAAgB,kBAAA;AAAA,YAChB,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,MAAM,CAAA,CAAA;AAAA,YACpC,cAAA,EAAgB,KAAA,CAAM,SAAA,IAAa,MAAA,CAAO,UAAA;AAAW,WACvD;AAAA,UACA,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA;AAAA,UAC1B,QAAQ,UAAA,CAAW;AAAA,SACpB,CAAA;AAED,QAAA,YAAA,CAAa,SAAS,CAAA;AAGtB,QAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAElC,QAAA,IAAI,KAAK,KAAA,EAAO;AACd,UAAA,OAAA,CAAQ,IAAI,iCAAA,EAAmC;AAAA,YAC7C,QAAQ,QAAA,CAAS,MAAA;AAAA,YACjB,MAAA,EAAQ,IAAA,CAAK,IAAA,EAAM,QAAA,CAAS,MAAA;AAAA,YAC5B,gBAAA,EAAkB,IAAA,CAAK,GAAA,EAAI,GAAI;AAAA,WAChC,CAAA;AAAA,QACH;AAGA,QAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,UAAA,OAAO;AAAA,YACL,OAAA,EAAS,KAAA;AAAA,YACT,KAAA,EAAO;AAAA,cACL,IAAA,EAAM,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,CAAA;AAAA,cAC7B,SAAS,IAAA,CAAK,KAAA,EAAO,OAAA,IAAW,CAAA,YAAA,EAAe,SAAS,MAAM,CAAA;AAAA;AAChE,WACF;AAAA,QACF;AAEA,QAAA,OAAO,IAAA;AAAA,MACT,SAAS,KAAA,EAAO;AACd,QAAA,YAAA,CAAa,SAAS,CAAA;AACtB,QAAA,MAAM,KAAA;AAAA,MACR;AAAA,IACF,SAAS,KAAA,EAAO;AAEd,MAAA,IAAI,KAAA,YAAiB,KAAA,IAAS,KAAA,CAAM,IAAA,KAAS,YAAA,EAAc;AACzD,QAAA,IAAI,KAAK,KAAA,EAAO;AACd,UAAA,OAAA,CAAQ,KAAK,iCAAiC,CAAA;AAAA,QAChD;AACA,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO;AAAA,YACL,IAAA,EAAM,SAAA;AAAA,YACN,OAAA,EAAS,CAAA,wBAAA,EAA2B,IAAA,CAAK,OAAO,CAAA,EAAA;AAAA;AAClD,SACF;AAAA,MACF;AAGA,MAAA,IAAI,KAAK,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAA,CAAM,iCAAiC,KAAK,CAAA;AAAA,MACtD;AAEA,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,KAAA,EAAO;AAAA,UACL,IAAA,EAAM,eAAA;AAAA,UACN,OAAA,EAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU;AAAA;AACpD,OACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,WAAW,KAAA,EAGd;AACD,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,OAAA,CAAQ,KAAK,CAAA;AAEvC,IAAA,IAAI,CAAC,MAAA,CAAO,OAAA,IAAW,CAAC,OAAO,IAAA,EAAM;AAEnC,MAAA,OAAO;AAAA,QACL,MAAA,EAAQ,OAAA;AAAA,QACR,KAAA,EAAO,OAAO,KAAA,EAAO;AAAA,OACvB;AAAA,IACF;AAEA,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,MAAA,CAAO,IAAA,CAAK,QAAA,CAAS;AAAA,KAC/B;AAAA,EACF;AACF;AAaA,IAAI,cAAA,GAA2C,IAAA;AAExC,SAAS,qBAAqB,MAAA,EAA8D;AACjG,EAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,IAAA,MAAM,MAAA,GAAS,MAAA,EAAQ,MAAA,IAAU,OAAA,CAAQ,GAAA,CAAI,mBAAA;AAE7C,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,cAAA,GAAiB,IAAI,iBAAA,CAAkB;AAAA,MACrC,MAAA;AAAA,MACA,OAAA,EAAS,MAAA,EAAQ,OAAA,IAAW,OAAA,CAAQ,GAAA,CAAI,mBAAA;AAAA,MACxC,SAAS,MAAA,EAAQ,OAAA;AAAA,MACjB,KAAA,EAAO,MAAA,EAAQ,KAAA,IAAS,OAAA,CAAQ,IAAI,iBAAA,KAAsB;AAAA,KAC3D,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,cAAA;AACT;AAKO,SAAS,sBAAA,GAA+B;AAC7C,EAAA,cAAA,GAAiB,IAAA;AACnB","file":"api-client.mjs","sourcesContent":["/**\n * AgentShield API Client\n *\n * Lightweight client for calling the AgentShield enforce API from middleware.\n * Designed for Edge Runtime compatibility (no Node.js-specific APIs).\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * API client configuration\n */\nexport interface AgentShieldClientConfig {\n /** API key for authentication */\n apiKey: string;\n /** API base URL (defaults to production) */\n baseUrl?: string;\n /** Request timeout in milliseconds (default: 5000) */\n timeout?: number;\n /** Enable debug logging */\n debug?: boolean;\n}\n\n/**\n * Enforcement action\n */\nexport type EnforcementAction = 'allow' | 'block' | 'redirect' | 'challenge' | 'log';\n\n/**\n * Enforcement decision from the API\n */\nexport interface EnforcementDecision {\n action: EnforcementAction;\n reason: string;\n isAgent: boolean;\n confidence: number;\n agentName?: string;\n agentType?: string;\n redirectUrl?: string;\n message?: string;\n metadata?: {\n policyVersion?: string;\n signatureVerified?: boolean;\n denyListMatch?: {\n clientDid?: string;\n agentDid?: string;\n clientName?: string;\n reason?: string;\n };\n };\n}\n\n/**\n * Detection result (optional in response)\n */\nexport interface DetectionResult {\n isAgent: boolean;\n confidence: number;\n agentName?: string;\n agentType?: string;\n verificationMethod?: string;\n reasons?: string[];\n}\n\n/**\n * Enforce API response\n */\nexport interface EnforceResponse {\n success: boolean;\n data?: {\n decision: EnforcementDecision;\n processingTimeMs: number;\n requestId: string;\n detection?: DetectionResult;\n };\n error?: {\n code: string;\n message: string;\n };\n}\n\n/**\n * Request input for enforce API\n */\nexport interface EnforceInput {\n /** HTTP headers from the incoming request */\n headers?: Record<string, string>;\n /** User-Agent header */\n userAgent?: string;\n /** Client IP address */\n ipAddress?: string;\n /** Request path */\n path?: string;\n /** Request URL */\n url?: string;\n /** HTTP method */\n method?: string;\n /** Request ID for tracing */\n requestId?: string;\n /** Options */\n options?: {\n /** Include full detection result */\n includeDetectionResult?: boolean;\n /** Cache TTL override */\n cacheTTL?: number;\n };\n}\n\n// ============================================================================\n// Client Implementation\n// ============================================================================\n\nconst DEFAULT_BASE_URL = 'https://api.agentshield.ai';\nconst DEFAULT_TIMEOUT = 5000;\n\n/**\n * AgentShield API Client\n *\n * @example\n * ```typescript\n * const client = new AgentShieldClient({\n * apiKey: process.env.AGENTSHIELD_API_KEY!,\n * });\n *\n * const result = await client.enforce({\n * headers: Object.fromEntries(request.headers),\n * path: request.nextUrl.pathname,\n * method: request.method,\n * });\n *\n * if (result.decision.action === 'block') {\n * return new Response('Access denied', { status: 403 });\n * }\n * ```\n */\nexport class AgentShieldClient {\n private apiKey: string;\n private baseUrl: string;\n private timeout: number;\n private debug: boolean;\n\n constructor(config: AgentShieldClientConfig) {\n if (!config.apiKey) {\n throw new Error('AgentShield API key is required');\n }\n\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;\n this.timeout = config.timeout || DEFAULT_TIMEOUT;\n this.debug = config.debug || false;\n }\n\n /**\n * Call the enforce API to check if a request should be allowed\n */\n async enforce(input: EnforceInput): Promise<EnforceResponse> {\n const startTime = Date.now();\n\n try {\n // Create abort controller for timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(`${this.baseUrl}/api/v1/enforce`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n 'X-Request-ID': input.requestId || crypto.randomUUID(),\n },\n body: JSON.stringify(input),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n // Parse response\n const data = (await response.json()) as EnforceResponse;\n\n if (this.debug) {\n console.log('[AgentShield] Enforce response:', {\n status: response.status,\n action: data.data?.decision.action,\n processingTimeMs: Date.now() - startTime,\n });\n }\n\n // Handle non-2xx responses\n if (!response.ok) {\n return {\n success: false,\n error: {\n code: `HTTP_${response.status}`,\n message: data.error?.message || `HTTP error: ${response.status}`,\n },\n };\n }\n\n return data;\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n } catch (error) {\n // Handle timeout\n if (error instanceof Error && error.name === 'AbortError') {\n if (this.debug) {\n console.warn('[AgentShield] Request timed out');\n }\n return {\n success: false,\n error: {\n code: 'TIMEOUT',\n message: `Request timed out after ${this.timeout}ms`,\n },\n };\n }\n\n // Handle network errors\n if (this.debug) {\n console.error('[AgentShield] Request failed:', error);\n }\n\n return {\n success: false,\n error: {\n code: 'NETWORK_ERROR',\n message: error instanceof Error ? error.message : 'Network request failed',\n },\n };\n }\n }\n\n /**\n * Quick check - returns just the action without full response parsing\n * Useful for very fast middleware that just needs allow/block\n */\n async quickCheck(input: EnforceInput): Promise<{\n action: EnforcementAction;\n error?: string;\n }> {\n const result = await this.enforce(input);\n\n if (!result.success || !result.data) {\n // On error, default to allow (fail-open)\n return {\n action: 'allow',\n error: result.error?.message,\n };\n }\n\n return {\n action: result.data.decision.action,\n };\n }\n}\n\n/**\n * Create a singleton client instance\n *\n * @example\n * ```typescript\n * // In middleware.ts\n * import { getAgentShieldClient } from '@kya-os/agentshield-nextjs';\n *\n * const client = getAgentShieldClient();\n * ```\n */\nlet clientInstance: AgentShieldClient | null = null;\n\nexport function getAgentShieldClient(config?: Partial<AgentShieldClientConfig>): AgentShieldClient {\n if (!clientInstance) {\n const apiKey = config?.apiKey || process.env.AGENTSHIELD_API_KEY;\n\n if (!apiKey) {\n throw new Error(\n 'AgentShield API key is required. Set AGENTSHIELD_API_KEY environment variable or pass apiKey in config.'\n );\n }\n\n clientInstance = new AgentShieldClient({\n apiKey,\n baseUrl: config?.baseUrl || process.env.AGENTSHIELD_API_URL,\n timeout: config?.timeout,\n debug: config?.debug || process.env.AGENTSHIELD_DEBUG === 'true',\n });\n }\n\n return clientInstance;\n}\n\n/**\n * Reset the singleton client (useful for testing)\n */\nexport function resetAgentShieldClient(): void {\n clientInstance = null;\n}\n"]}
@@ -0,0 +1,118 @@
1
+ import { NextRequest, NextResponse } from 'next/server';
2
+ import { EnforcementDecision } from './api-client.mjs';
3
+
4
+ /**
5
+ * API-based AgentShield Middleware for Next.js
6
+ *
7
+ * This middleware uses the AgentShield API for detection and enforcement,
8
+ * instead of running detection locally. This approach:
9
+ *
10
+ * 1. Works reliably in Edge Runtime (no WASM loading issues)
11
+ * 2. Ensures consistent detection across all platforms
12
+ * 3. Applies centralized policies from the dashboard
13
+ * 4. Supports deny lists, thresholds, and path rules
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * // middleware.ts
18
+ * import { withAgentShield } from '@kya-os/agentshield-nextjs/api-middleware';
19
+ *
20
+ * export default withAgentShield({
21
+ * apiKey: process.env.AGENTSHIELD_API_KEY!,
22
+ * // Optional overrides:
23
+ * onBlock: 'redirect', // 'block' | 'redirect' | 'challenge'
24
+ * redirectUrl: '/blocked',
25
+ * skipPaths: ['/api/health', '/_next/*'],
26
+ * });
27
+ *
28
+ * export const config = {
29
+ * matcher: ['/((?!_next/static|favicon.ico).*)'],
30
+ * };
31
+ * ```
32
+ */
33
+
34
+ /**
35
+ * Middleware configuration
36
+ */
37
+ interface AgentShieldMiddlewareConfig {
38
+ /** API key (or use AGENTSHIELD_API_KEY env var) */
39
+ apiKey?: string;
40
+ /** API base URL (defaults to production) */
41
+ apiUrl?: string;
42
+ /** Request timeout in ms (default: 5000) */
43
+ timeout?: number;
44
+ /**
45
+ * Action to take when an agent should be blocked
46
+ * - 'block': Return 403 response
47
+ * - 'redirect': Redirect to redirectUrl
48
+ * - 'challenge': Show a challenge page (future)
49
+ * Default: uses policy from dashboard
50
+ */
51
+ onBlock?: 'block' | 'redirect' | 'challenge';
52
+ /**
53
+ * URL to redirect to when blocking (if onBlock is 'redirect')
54
+ * Default: uses redirectUrl from dashboard policy
55
+ */
56
+ redirectUrl?: string;
57
+ /**
58
+ * Custom blocked response
59
+ */
60
+ blockedResponse?: {
61
+ status?: number;
62
+ message?: string;
63
+ headers?: Record<string, string>;
64
+ };
65
+ /**
66
+ * Paths to skip (in addition to dashboard policy)
67
+ * Supports glob patterns: '/api/*', '/_next/*'
68
+ */
69
+ skipPaths?: string[];
70
+ /**
71
+ * Only enforce on these paths (overrides dashboard policy)
72
+ */
73
+ includePaths?: string[];
74
+ /**
75
+ * Callback when an agent is detected
76
+ */
77
+ onAgentDetected?: (request: NextRequest, decision: EnforcementDecision) => void | Promise<void>;
78
+ /**
79
+ * Callback to customize the blocked response
80
+ */
81
+ customBlockedResponse?: (request: NextRequest, decision: EnforcementDecision) => NextResponse | Promise<NextResponse>;
82
+ /**
83
+ * Whether to fail open (allow) on API errors
84
+ * Default: true (recommended for production)
85
+ */
86
+ failOpen?: boolean;
87
+ /**
88
+ * Enable debug logging
89
+ */
90
+ debug?: boolean;
91
+ }
92
+ /**
93
+ * Create AgentShield middleware with API-based detection
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * // middleware.ts
98
+ * import { withAgentShield } from '@kya-os/agentshield-nextjs/api-middleware';
99
+ *
100
+ * export default withAgentShield({
101
+ * onBlock: 'block',
102
+ * skipPaths: ['/api/health'],
103
+ * });
104
+ * ```
105
+ */
106
+ declare function withAgentShield(config?: AgentShieldMiddlewareConfig): (request: NextRequest) => Promise<NextResponse>;
107
+ /**
108
+ * Convenience export for simple setup
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * // middleware.ts
113
+ * export { agentShieldMiddleware as default } from '@kya-os/agentshield-nextjs/api-middleware';
114
+ * ```
115
+ */
116
+ declare const agentShieldMiddleware: (request: NextRequest) => Promise<NextResponse>;
117
+
118
+ export { type AgentShieldMiddlewareConfig, agentShieldMiddleware, withAgentShield };
@@ -0,0 +1,118 @@
1
+ import { NextRequest, NextResponse } from 'next/server';
2
+ import { EnforcementDecision } from './api-client.js';
3
+
4
+ /**
5
+ * API-based AgentShield Middleware for Next.js
6
+ *
7
+ * This middleware uses the AgentShield API for detection and enforcement,
8
+ * instead of running detection locally. This approach:
9
+ *
10
+ * 1. Works reliably in Edge Runtime (no WASM loading issues)
11
+ * 2. Ensures consistent detection across all platforms
12
+ * 3. Applies centralized policies from the dashboard
13
+ * 4. Supports deny lists, thresholds, and path rules
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * // middleware.ts
18
+ * import { withAgentShield } from '@kya-os/agentshield-nextjs/api-middleware';
19
+ *
20
+ * export default withAgentShield({
21
+ * apiKey: process.env.AGENTSHIELD_API_KEY!,
22
+ * // Optional overrides:
23
+ * onBlock: 'redirect', // 'block' | 'redirect' | 'challenge'
24
+ * redirectUrl: '/blocked',
25
+ * skipPaths: ['/api/health', '/_next/*'],
26
+ * });
27
+ *
28
+ * export const config = {
29
+ * matcher: ['/((?!_next/static|favicon.ico).*)'],
30
+ * };
31
+ * ```
32
+ */
33
+
34
+ /**
35
+ * Middleware configuration
36
+ */
37
+ interface AgentShieldMiddlewareConfig {
38
+ /** API key (or use AGENTSHIELD_API_KEY env var) */
39
+ apiKey?: string;
40
+ /** API base URL (defaults to production) */
41
+ apiUrl?: string;
42
+ /** Request timeout in ms (default: 5000) */
43
+ timeout?: number;
44
+ /**
45
+ * Action to take when an agent should be blocked
46
+ * - 'block': Return 403 response
47
+ * - 'redirect': Redirect to redirectUrl
48
+ * - 'challenge': Show a challenge page (future)
49
+ * Default: uses policy from dashboard
50
+ */
51
+ onBlock?: 'block' | 'redirect' | 'challenge';
52
+ /**
53
+ * URL to redirect to when blocking (if onBlock is 'redirect')
54
+ * Default: uses redirectUrl from dashboard policy
55
+ */
56
+ redirectUrl?: string;
57
+ /**
58
+ * Custom blocked response
59
+ */
60
+ blockedResponse?: {
61
+ status?: number;
62
+ message?: string;
63
+ headers?: Record<string, string>;
64
+ };
65
+ /**
66
+ * Paths to skip (in addition to dashboard policy)
67
+ * Supports glob patterns: '/api/*', '/_next/*'
68
+ */
69
+ skipPaths?: string[];
70
+ /**
71
+ * Only enforce on these paths (overrides dashboard policy)
72
+ */
73
+ includePaths?: string[];
74
+ /**
75
+ * Callback when an agent is detected
76
+ */
77
+ onAgentDetected?: (request: NextRequest, decision: EnforcementDecision) => void | Promise<void>;
78
+ /**
79
+ * Callback to customize the blocked response
80
+ */
81
+ customBlockedResponse?: (request: NextRequest, decision: EnforcementDecision) => NextResponse | Promise<NextResponse>;
82
+ /**
83
+ * Whether to fail open (allow) on API errors
84
+ * Default: true (recommended for production)
85
+ */
86
+ failOpen?: boolean;
87
+ /**
88
+ * Enable debug logging
89
+ */
90
+ debug?: boolean;
91
+ }
92
+ /**
93
+ * Create AgentShield middleware with API-based detection
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * // middleware.ts
98
+ * import { withAgentShield } from '@kya-os/agentshield-nextjs/api-middleware';
99
+ *
100
+ * export default withAgentShield({
101
+ * onBlock: 'block',
102
+ * skipPaths: ['/api/health'],
103
+ * });
104
+ * ```
105
+ */
106
+ declare function withAgentShield(config?: AgentShieldMiddlewareConfig): (request: NextRequest) => Promise<NextResponse>;
107
+ /**
108
+ * Convenience export for simple setup
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * // middleware.ts
113
+ * export { agentShieldMiddleware as default } from '@kya-os/agentshield-nextjs/api-middleware';
114
+ * ```
115
+ */
116
+ declare const agentShieldMiddleware: (request: NextRequest) => Promise<NextResponse>;
117
+
118
+ export { type AgentShieldMiddlewareConfig, agentShieldMiddleware, withAgentShield };