@agentix-security/nextjs 0.1.1 → 0.1.3

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.
package/dist/index.cjs CHANGED
@@ -230,6 +230,12 @@ var DEFAULT_CONTROL_PLANE = "https://agentix-control-plane.onrender.com";
230
230
  var AgentixSDK = class {
231
231
  constructor(config) {
232
232
  this.config = config;
233
+ if (config.routes) {
234
+ for (const [intent, route] of Object.entries(config.routes)) {
235
+ this.registerIntent(intent);
236
+ this.registerIntentRoute(intent, route);
237
+ }
238
+ }
233
239
  }
234
240
  config;
235
241
  lease = null;
@@ -302,7 +308,13 @@ var AgentixSDK = class {
302
308
  return this.engine;
303
309
  }
304
310
  registerIntent(intent, mode = "enforce") {
305
- this.intentRegistry.set(intent, mode);
311
+ if (!this.intentRegistry.has(intent)) {
312
+ this.intentRegistry.set(intent, { mode, routes: /* @__PURE__ */ new Set() });
313
+ }
314
+ }
315
+ registerIntentRoute(intent, route) {
316
+ const entry = this.intentRegistry.get(intent);
317
+ if (entry) entry.routes.add(route);
306
318
  }
307
319
  getIntentRegistry() {
308
320
  return this.intentRegistry;
@@ -411,13 +423,13 @@ function bearer(req) {
411
423
  if (!auth?.startsWith("Bearer ")) return null;
412
424
  return auth.slice("Bearer ".length).trim();
413
425
  }
414
- async function shipAudit2(url, key, row) {
415
- if (!key) return;
426
+ async function shipAudit2(url, licenseKey, row) {
427
+ if (!licenseKey || !url) return;
416
428
  try {
417
- await fetch(`${url}/v1/audit/decisions`, {
429
+ await fetch(`${url}/v1/audit/events`, {
418
430
  method: "POST",
419
- headers: { authorization: `Bearer ${key}`, "content-type": "application/json" },
420
- body: JSON.stringify(row)
431
+ headers: { "content-type": "application/json" },
432
+ body: JSON.stringify({ license_key: licenseKey, rows: [row] })
421
433
  });
422
434
  } catch {
423
435
  }
@@ -443,11 +455,14 @@ function agentixMiddleware(sdk) {
443
455
  const fp = await fingerprint2(req);
444
456
  const baseUrl = req.nextUrl.origin;
445
457
  const cp = (sdk.config.controlPlaneUrl ?? "https://agentix-control-plane.onrender.com").replace(/\/$/, "");
446
- const adminKey = sdk.config.controlPlaneAdminKey;
458
+ const licenseKey = sdk.config.licenseKey;
447
459
  const tokenSecret = sdk.getResolvedTokenSecret();
448
460
  if (req.method === "GET" && pathname === "/.well-known/ai-agent.json") {
449
- const allIntents = [...sdk.getIntentRegistry().keys()];
450
- void shipAudit2(cp, adminKey, auditRow(sdk, req, pathname, 200, fp, {
461
+ const registry = sdk.getIntentRegistry();
462
+ const tools = Object.fromEntries(
463
+ [...registry.entries()].map(([intent, entry]) => [intent, { routes: [...entry.routes] }])
464
+ );
465
+ void shipAudit2(cp, licenseKey, auditRow(sdk, req, pathname, 200, fp, {
451
466
  trust_mode: "unknown",
452
467
  intent_scope: "none",
453
468
  token_id: null,
@@ -461,7 +476,8 @@ function agentixMiddleware(sdk) {
461
476
  tenant_id: sdk.getResolvedTenantId(),
462
477
  deployment_id: sdk.getDeploymentId(),
463
478
  discovery: { well_known: `${baseUrl}/.well-known/ai-agent.json`, token_endpoint: `${baseUrl}/agent/v1/declare_intent` },
464
- intents: allIntents
479
+ intents: [...registry.keys()],
480
+ tools
465
481
  }, { headers: { "cache-control": "no-store" } });
466
482
  }
467
483
  if (req.method === "POST" && pathname === "/agent/v1/declare_intent") {
@@ -472,7 +488,7 @@ function agentixMiddleware(sdk) {
472
488
  }
473
489
  const validIntents = [...sdk.getIntentRegistry().keys()];
474
490
  if (!body.intent || !isValidIntent(body.intent, validIntents)) {
475
- void shipAudit2(cp, adminKey, auditRow(sdk, req, pathname, 400, fp, {
491
+ void shipAudit2(cp, licenseKey, auditRow(sdk, req, pathname, 400, fp, {
476
492
  trust_mode: "unmanaged_automation",
477
493
  intent_scope: "none",
478
494
  token_id: null,
@@ -489,7 +505,7 @@ function agentixMiddleware(sdk) {
489
505
  const exp = iat + Math.floor(ttl / 1e3);
490
506
  const raw = await issueTokenWeb(tokenSecret, { intent, domain: sdk.getResolvedDomain(), binding: fp, iat, exp });
491
507
  const jti = tokenIdWeb(raw);
492
- void shipAudit2(cp, adminKey, auditRow(sdk, req, pathname, 200, fp, {
508
+ void shipAudit2(cp, licenseKey, auditRow(sdk, req, pathname, 200, fp, {
493
509
  trust_mode: "managed_agent",
494
510
  intent_scope: intent,
495
511
  token_id: jti,
@@ -514,6 +530,7 @@ function agentixMiddleware(sdk) {
514
530
  function secure(sdk, intent, handler, opts = {}) {
515
531
  const mode = opts.mode ?? "enforce";
516
532
  sdk.registerIntent(intent, mode);
533
+ if (opts.path) sdk.registerIntentRoute(intent, opts.path);
517
534
  return async (req, ctx) => {
518
535
  await sdk.ensureInitialized();
519
536
  const fp = await fingerprint2(req);
package/dist/index.d.cts CHANGED
@@ -41,7 +41,10 @@ interface EngineOptions {
41
41
  controlPlaneUrl: string;
42
42
  controlPlaneAdminKey?: string;
43
43
  getLease: () => LicenseLease | null;
44
- getRegisteredIntents?: () => ReadonlyMap<string, 'enforce' | 'shadow'>;
44
+ getRegisteredIntents?: () => ReadonlyMap<string, {
45
+ mode: 'enforce' | 'shadow';
46
+ routes: Set<string>;
47
+ }>;
45
48
  devMode?: boolean;
46
49
  }
47
50
  declare class Engine {
@@ -67,6 +70,9 @@ interface AgentixSDKConfig {
67
70
  declareLimit?: number;
68
71
  declareWindowMs?: number;
69
72
  controlPlaneAdminKey?: string;
73
+ /** Map of intent → route string (e.g. { read_jobs: 'GET /api/jobs' }).
74
+ * Registered at init time so routes appear in discovery before any request. */
75
+ routes?: Record<string, string>;
70
76
  }
71
77
 
72
78
  declare class AgentixSDK {
@@ -86,7 +92,11 @@ declare class AgentixSDK {
86
92
  private _init;
87
93
  getEngine(): Engine;
88
94
  registerIntent(intent: string, mode?: 'enforce' | 'shadow'): void;
89
- getIntentRegistry(): ReadonlyMap<string, 'enforce' | 'shadow'>;
95
+ registerIntentRoute(intent: string, route: string): void;
96
+ getIntentRegistry(): ReadonlyMap<string, {
97
+ mode: 'enforce' | 'shadow';
98
+ routes: Set<string>;
99
+ }>;
90
100
  getResolvedDomain(): string;
91
101
  getResolvedTenantId(): string;
92
102
  getResolvedTokenSecret(): string;
@@ -109,6 +119,7 @@ declare function agentixMiddleware(sdk: AgentixSDK): NextMiddleware;
109
119
  */
110
120
  declare function secure(sdk: AgentixSDK, intent: string, handler: (req: NextRequest, ctx?: unknown) => Promise<Response> | Response, opts?: {
111
121
  mode?: 'enforce' | 'shadow';
122
+ path?: string;
112
123
  }): (req: NextRequest, ctx?: unknown) => Promise<Response>;
113
124
  interface PagesRes {
114
125
  status(code: number): PagesRes;
package/dist/index.d.ts CHANGED
@@ -41,7 +41,10 @@ interface EngineOptions {
41
41
  controlPlaneUrl: string;
42
42
  controlPlaneAdminKey?: string;
43
43
  getLease: () => LicenseLease | null;
44
- getRegisteredIntents?: () => ReadonlyMap<string, 'enforce' | 'shadow'>;
44
+ getRegisteredIntents?: () => ReadonlyMap<string, {
45
+ mode: 'enforce' | 'shadow';
46
+ routes: Set<string>;
47
+ }>;
45
48
  devMode?: boolean;
46
49
  }
47
50
  declare class Engine {
@@ -67,6 +70,9 @@ interface AgentixSDKConfig {
67
70
  declareLimit?: number;
68
71
  declareWindowMs?: number;
69
72
  controlPlaneAdminKey?: string;
73
+ /** Map of intent → route string (e.g. { read_jobs: 'GET /api/jobs' }).
74
+ * Registered at init time so routes appear in discovery before any request. */
75
+ routes?: Record<string, string>;
70
76
  }
71
77
 
72
78
  declare class AgentixSDK {
@@ -86,7 +92,11 @@ declare class AgentixSDK {
86
92
  private _init;
87
93
  getEngine(): Engine;
88
94
  registerIntent(intent: string, mode?: 'enforce' | 'shadow'): void;
89
- getIntentRegistry(): ReadonlyMap<string, 'enforce' | 'shadow'>;
95
+ registerIntentRoute(intent: string, route: string): void;
96
+ getIntentRegistry(): ReadonlyMap<string, {
97
+ mode: 'enforce' | 'shadow';
98
+ routes: Set<string>;
99
+ }>;
90
100
  getResolvedDomain(): string;
91
101
  getResolvedTenantId(): string;
92
102
  getResolvedTokenSecret(): string;
@@ -109,6 +119,7 @@ declare function agentixMiddleware(sdk: AgentixSDK): NextMiddleware;
109
119
  */
110
120
  declare function secure(sdk: AgentixSDK, intent: string, handler: (req: NextRequest, ctx?: unknown) => Promise<Response> | Response, opts?: {
111
121
  mode?: 'enforce' | 'shadow';
122
+ path?: string;
112
123
  }): (req: NextRequest, ctx?: unknown) => Promise<Response>;
113
124
  interface PagesRes {
114
125
  status(code: number): PagesRes;
package/dist/index.js CHANGED
@@ -228,6 +228,12 @@ var DEFAULT_CONTROL_PLANE = "https://agentix-control-plane.onrender.com";
228
228
  var AgentixSDK = class {
229
229
  constructor(config) {
230
230
  this.config = config;
231
+ if (config.routes) {
232
+ for (const [intent, route] of Object.entries(config.routes)) {
233
+ this.registerIntent(intent);
234
+ this.registerIntentRoute(intent, route);
235
+ }
236
+ }
231
237
  }
232
238
  config;
233
239
  lease = null;
@@ -300,7 +306,13 @@ var AgentixSDK = class {
300
306
  return this.engine;
301
307
  }
302
308
  registerIntent(intent, mode = "enforce") {
303
- this.intentRegistry.set(intent, mode);
309
+ if (!this.intentRegistry.has(intent)) {
310
+ this.intentRegistry.set(intent, { mode, routes: /* @__PURE__ */ new Set() });
311
+ }
312
+ }
313
+ registerIntentRoute(intent, route) {
314
+ const entry = this.intentRegistry.get(intent);
315
+ if (entry) entry.routes.add(route);
304
316
  }
305
317
  getIntentRegistry() {
306
318
  return this.intentRegistry;
@@ -409,13 +421,13 @@ function bearer(req) {
409
421
  if (!auth?.startsWith("Bearer ")) return null;
410
422
  return auth.slice("Bearer ".length).trim();
411
423
  }
412
- async function shipAudit2(url, key, row) {
413
- if (!key) return;
424
+ async function shipAudit2(url, licenseKey, row) {
425
+ if (!licenseKey || !url) return;
414
426
  try {
415
- await fetch(`${url}/v1/audit/decisions`, {
427
+ await fetch(`${url}/v1/audit/events`, {
416
428
  method: "POST",
417
- headers: { authorization: `Bearer ${key}`, "content-type": "application/json" },
418
- body: JSON.stringify(row)
429
+ headers: { "content-type": "application/json" },
430
+ body: JSON.stringify({ license_key: licenseKey, rows: [row] })
419
431
  });
420
432
  } catch {
421
433
  }
@@ -441,11 +453,14 @@ function agentixMiddleware(sdk) {
441
453
  const fp = await fingerprint2(req);
442
454
  const baseUrl = req.nextUrl.origin;
443
455
  const cp = (sdk.config.controlPlaneUrl ?? "https://agentix-control-plane.onrender.com").replace(/\/$/, "");
444
- const adminKey = sdk.config.controlPlaneAdminKey;
456
+ const licenseKey = sdk.config.licenseKey;
445
457
  const tokenSecret = sdk.getResolvedTokenSecret();
446
458
  if (req.method === "GET" && pathname === "/.well-known/ai-agent.json") {
447
- const allIntents = [...sdk.getIntentRegistry().keys()];
448
- void shipAudit2(cp, adminKey, auditRow(sdk, req, pathname, 200, fp, {
459
+ const registry = sdk.getIntentRegistry();
460
+ const tools = Object.fromEntries(
461
+ [...registry.entries()].map(([intent, entry]) => [intent, { routes: [...entry.routes] }])
462
+ );
463
+ void shipAudit2(cp, licenseKey, auditRow(sdk, req, pathname, 200, fp, {
449
464
  trust_mode: "unknown",
450
465
  intent_scope: "none",
451
466
  token_id: null,
@@ -459,7 +474,8 @@ function agentixMiddleware(sdk) {
459
474
  tenant_id: sdk.getResolvedTenantId(),
460
475
  deployment_id: sdk.getDeploymentId(),
461
476
  discovery: { well_known: `${baseUrl}/.well-known/ai-agent.json`, token_endpoint: `${baseUrl}/agent/v1/declare_intent` },
462
- intents: allIntents
477
+ intents: [...registry.keys()],
478
+ tools
463
479
  }, { headers: { "cache-control": "no-store" } });
464
480
  }
465
481
  if (req.method === "POST" && pathname === "/agent/v1/declare_intent") {
@@ -470,7 +486,7 @@ function agentixMiddleware(sdk) {
470
486
  }
471
487
  const validIntents = [...sdk.getIntentRegistry().keys()];
472
488
  if (!body.intent || !isValidIntent(body.intent, validIntents)) {
473
- void shipAudit2(cp, adminKey, auditRow(sdk, req, pathname, 400, fp, {
489
+ void shipAudit2(cp, licenseKey, auditRow(sdk, req, pathname, 400, fp, {
474
490
  trust_mode: "unmanaged_automation",
475
491
  intent_scope: "none",
476
492
  token_id: null,
@@ -487,7 +503,7 @@ function agentixMiddleware(sdk) {
487
503
  const exp = iat + Math.floor(ttl / 1e3);
488
504
  const raw = await issueTokenWeb(tokenSecret, { intent, domain: sdk.getResolvedDomain(), binding: fp, iat, exp });
489
505
  const jti = tokenIdWeb(raw);
490
- void shipAudit2(cp, adminKey, auditRow(sdk, req, pathname, 200, fp, {
506
+ void shipAudit2(cp, licenseKey, auditRow(sdk, req, pathname, 200, fp, {
491
507
  trust_mode: "managed_agent",
492
508
  intent_scope: intent,
493
509
  token_id: jti,
@@ -512,6 +528,7 @@ function agentixMiddleware(sdk) {
512
528
  function secure(sdk, intent, handler, opts = {}) {
513
529
  const mode = opts.mode ?? "enforce";
514
530
  sdk.registerIntent(intent, mode);
531
+ if (opts.path) sdk.registerIntentRoute(intent, opts.path);
515
532
  return async (req, ctx) => {
516
533
  await sdk.ensureInitialized();
517
534
  const fp = await fingerprint2(req);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentix-security/nextjs",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Agentix Next.js adapter — AI agent intent-based authorization for Next.js apps",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",