@astrasyncai/verification-gateway 1.0.0

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 (40) hide show
  1. package/README.md +213 -0
  2. package/dist/adapters/express.d.mts +3 -0
  3. package/dist/adapters/express.d.ts +3 -0
  4. package/dist/adapters/express.js +516 -0
  5. package/dist/adapters/express.js.map +1 -0
  6. package/dist/adapters/express.mjs +486 -0
  7. package/dist/adapters/express.mjs.map +1 -0
  8. package/dist/adapters/nextjs.d.mts +3 -0
  9. package/dist/adapters/nextjs.d.ts +3 -0
  10. package/dist/adapters/nextjs.js +624 -0
  11. package/dist/adapters/nextjs.js.map +1 -0
  12. package/dist/adapters/nextjs.mjs +586 -0
  13. package/dist/adapters/nextjs.mjs.map +1 -0
  14. package/dist/adapters/sdk.d.mts +2 -0
  15. package/dist/adapters/sdk.d.ts +2 -0
  16. package/dist/adapters/sdk.js +505 -0
  17. package/dist/adapters/sdk.js.map +1 -0
  18. package/dist/adapters/sdk.mjs +473 -0
  19. package/dist/adapters/sdk.mjs.map +1 -0
  20. package/dist/express-BhD3mWsL.d.ts +64 -0
  21. package/dist/express-DUDYpvNZ.d.mts +64 -0
  22. package/dist/index.d.mts +353 -0
  23. package/dist/index.d.ts +353 -0
  24. package/dist/index.js +1499 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/index.mjs +1446 -0
  27. package/dist/index.mjs.map +1 -0
  28. package/dist/nextjs-BtqyLSVQ.d.mts +22 -0
  29. package/dist/nextjs-C9FPOjSh.d.ts +22 -0
  30. package/dist/sdk-BkVigGjF.d.ts +190 -0
  31. package/dist/sdk-xCbZgeZx.d.mts +190 -0
  32. package/dist/types-CS6v75-d.d.mts +359 -0
  33. package/dist/types-CS6v75-d.d.ts +359 -0
  34. package/dist/ui/index.d.mts +140 -0
  35. package/dist/ui/index.d.ts +140 -0
  36. package/dist/ui/index.js +826 -0
  37. package/dist/ui/index.js.map +1 -0
  38. package/dist/ui/index.mjs +782 -0
  39. package/dist/ui/index.mjs.map +1 -0
  40. package/package.json +89 -0
package/dist/index.js ADDED
@@ -0,0 +1,1499 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ ACCESS_LEVEL_DESCRIPTIONS: () => ACCESS_LEVEL_DESCRIPTIONS,
34
+ ACCESS_LEVEL_HIERARCHY: () => ACCESS_LEVEL_HIERARCHY,
35
+ AgentClient: () => AgentClient,
36
+ ChallengeHandler: () => ChallengeHandler,
37
+ DEFAULT_TRUST_THRESHOLDS: () => DEFAULT_TRUST_THRESHOLDS,
38
+ TRUST_LEVEL_RANGES: () => TRUST_LEVEL_RANGES,
39
+ VERSION: () => VERSION,
40
+ agent: () => agent_exports,
41
+ clearCache: () => clearCache,
42
+ determineAccessLevel: () => determineAccessLevel,
43
+ express: () => express_exports,
44
+ extractCredentials: () => extractCredentials,
45
+ getAccessLevelForScore: () => getAccessLevelForScore,
46
+ getCapabilities: () => getCapabilities,
47
+ getTrustLevel: () => getTrustLevel,
48
+ hasCredentials: () => hasCredentials,
49
+ hasMinimumAccess: () => hasMinimumAccess,
50
+ nextjs: () => nextjs_exports,
51
+ quickVerify: () => quickVerify,
52
+ recordDecision: () => recordDecision,
53
+ sdk: () => sdk_exports,
54
+ transport: () => transport_exports,
55
+ verify: () => verify
56
+ });
57
+ module.exports = __toCommonJS(src_exports);
58
+
59
+ // src/access-levels.ts
60
+ var ACCESS_LEVEL_HIERARCHY = {
61
+ none: 0,
62
+ guidance: 1,
63
+ "read-only": 2,
64
+ standard: 3,
65
+ full: 4,
66
+ internal: 5
67
+ };
68
+ var ACCESS_LEVEL_DESCRIPTIONS = {
69
+ none: "No access - credentials required",
70
+ guidance: "Guidance mode - registration information provided",
71
+ "read-only": "Read-only access - can browse but not modify",
72
+ standard: "Standard access - normal operations per PDLSS policy",
73
+ full: "Full access - all operations for high-trust agents",
74
+ internal: "Internal access - organization member privileges"
75
+ };
76
+ var DEFAULT_TRUST_THRESHOLDS = {
77
+ none: 0,
78
+ guidance: 0,
79
+ "read-only": 20,
80
+ standard: 40,
81
+ full: 70,
82
+ internal: 0
83
+ // Internal is based on org membership, not score
84
+ };
85
+ var TRUST_LEVEL_RANGES = {
86
+ BRONZE: { min: 0, max: 39 },
87
+ SILVER: { min: 40, max: 59 },
88
+ GOLD: { min: 60, max: 79 },
89
+ PLATINUM: { min: 80, max: 100 }
90
+ };
91
+ function getTrustLevel(score) {
92
+ if (score >= 80) return "PLATINUM";
93
+ if (score >= 60) return "GOLD";
94
+ if (score >= 40) return "SILVER";
95
+ return "BRONZE";
96
+ }
97
+ function hasMinimumAccess(actual, required) {
98
+ return ACCESS_LEVEL_HIERARCHY[actual] >= ACCESS_LEVEL_HIERARCHY[required];
99
+ }
100
+ function getAccessLevelForScore(trustScore, thresholds = DEFAULT_TRUST_THRESHOLDS) {
101
+ if (trustScore >= thresholds.full) return "full";
102
+ if (trustScore >= thresholds.standard) return "standard";
103
+ if (trustScore >= thresholds["read-only"]) return "read-only";
104
+ return "guidance";
105
+ }
106
+ function determineAccessLevel(verified, trustScore, isOrgMember, customThresholds) {
107
+ if (!verified) {
108
+ return "guidance";
109
+ }
110
+ if (isOrgMember) {
111
+ return "internal";
112
+ }
113
+ const thresholds = {
114
+ ...DEFAULT_TRUST_THRESHOLDS,
115
+ ...customThresholds
116
+ };
117
+ return getAccessLevelForScore(trustScore, thresholds);
118
+ }
119
+ function getCapabilities(accessLevel) {
120
+ switch (accessLevel) {
121
+ case "none":
122
+ return {
123
+ canRead: false,
124
+ canWrite: false,
125
+ canDelete: false,
126
+ canAdmin: false,
127
+ canAccessInternal: false
128
+ };
129
+ case "guidance":
130
+ return {
131
+ canRead: false,
132
+ canWrite: false,
133
+ canDelete: false,
134
+ canAdmin: false,
135
+ canAccessInternal: false
136
+ };
137
+ case "read-only":
138
+ return {
139
+ canRead: true,
140
+ canWrite: false,
141
+ canDelete: false,
142
+ canAdmin: false,
143
+ canAccessInternal: false
144
+ };
145
+ case "standard":
146
+ return {
147
+ canRead: true,
148
+ canWrite: true,
149
+ canDelete: false,
150
+ canAdmin: false,
151
+ canAccessInternal: false
152
+ };
153
+ case "full":
154
+ return {
155
+ canRead: true,
156
+ canWrite: true,
157
+ canDelete: true,
158
+ canAdmin: false,
159
+ canAccessInternal: false
160
+ };
161
+ case "internal":
162
+ return {
163
+ canRead: true,
164
+ canWrite: true,
165
+ canDelete: true,
166
+ canAdmin: true,
167
+ canAccessInternal: true
168
+ };
169
+ default:
170
+ return {
171
+ canRead: false,
172
+ canWrite: false,
173
+ canDelete: false,
174
+ canAdmin: false,
175
+ canAccessInternal: false
176
+ };
177
+ }
178
+ }
179
+
180
+ // src/verify.ts
181
+ var DEFAULT_CONFIG = {
182
+ apiBaseUrl: "https://api.astrasync.ai",
183
+ defaultAccessLevel: "guidance",
184
+ minTrustScore: 40,
185
+ minTrustScoreForFull: 70,
186
+ cacheTtl: 300,
187
+ // 5 minutes
188
+ debug: false
189
+ };
190
+ var verificationCache = /* @__PURE__ */ new Map();
191
+ function getCacheKey(credentials) {
192
+ return `${credentials.astraId || ""}-${credentials.apiKey || ""}-${credentials.jwt || ""}`;
193
+ }
194
+ function getCachedResult(credentials) {
195
+ const key = getCacheKey(credentials);
196
+ const cached = verificationCache.get(key);
197
+ if (cached && cached.expiresAt > Date.now()) {
198
+ return cached.result;
199
+ }
200
+ if (cached) {
201
+ verificationCache.delete(key);
202
+ }
203
+ return null;
204
+ }
205
+ function cacheResult(credentials, result, ttlSeconds) {
206
+ const key = getCacheKey(credentials);
207
+ verificationCache.set(key, {
208
+ result,
209
+ expiresAt: Date.now() + ttlSeconds * 1e3
210
+ });
211
+ }
212
+ function clearCache() {
213
+ verificationCache.clear();
214
+ }
215
+ function extractCredentials(headers, query) {
216
+ const credentials = {};
217
+ const astraIdHeader = headers["x-astra-id"] || headers["X-Astra-Id"] || headers["X-ASTRA-ID"];
218
+ if (astraIdHeader) {
219
+ credentials.astraId = Array.isArray(astraIdHeader) ? astraIdHeader[0] : astraIdHeader;
220
+ }
221
+ const apiKeyHeader = headers["x-api-key"] || headers["X-Api-Key"] || headers["X-API-KEY"];
222
+ if (apiKeyHeader) {
223
+ credentials.apiKey = Array.isArray(apiKeyHeader) ? apiKeyHeader[0] : apiKeyHeader;
224
+ }
225
+ const authHeader = headers["authorization"] || headers["Authorization"];
226
+ if (authHeader) {
227
+ const authValue = Array.isArray(authHeader) ? authHeader[0] : authHeader;
228
+ credentials.authorizationHeader = authValue;
229
+ if (authValue.startsWith("Bearer ")) {
230
+ credentials.jwt = authValue.slice(7);
231
+ }
232
+ }
233
+ if (query) {
234
+ if (query.astraId && !credentials.astraId) {
235
+ credentials.astraId = query.astraId;
236
+ }
237
+ if (query.apiKey && !credentials.apiKey) {
238
+ credentials.apiKey = query.apiKey;
239
+ }
240
+ }
241
+ return credentials;
242
+ }
243
+ function hasCredentials(credentials) {
244
+ return !!(credentials.astraId || credentials.apiKey || credentials.jwt);
245
+ }
246
+ function createGuidanceResponse(config, reason) {
247
+ const guidance = {
248
+ message: "This service verifies AI agents before granting access. Please register your agent with AstraSync.",
249
+ registrationUrl: `${config.apiBaseUrl.replace("/api", "")}/register`,
250
+ documentationUrl: `${config.apiBaseUrl.replace("/api", "")}/docs/agent-access`,
251
+ steps: [
252
+ "Register for an AstraSync account",
253
+ "Create and register your agent",
254
+ "Add your ASTRA-ID to request headers",
255
+ "Retry your request"
256
+ ]
257
+ };
258
+ return {
259
+ verified: false,
260
+ accessLevel: "guidance",
261
+ guidance,
262
+ denialReasons: reason ? [reason] : ["No valid agent credentials provided"],
263
+ verifiedAt: /* @__PURE__ */ new Date()
264
+ };
265
+ }
266
+ async function callVerifyAccessAPI(config, request) {
267
+ const { credentials, ...requestData } = request;
268
+ const body = {
269
+ agentId: credentials.astraId,
270
+ purpose: requestData.purpose || "general"
271
+ };
272
+ if (requestData.action) body.action = requestData.action;
273
+ if (requestData.resourceType) body.resourceType = requestData.resourceType;
274
+ if (requestData.resource) body.resource = requestData.resource;
275
+ if (requestData.jurisdiction) body.jurisdiction = requestData.jurisdiction;
276
+ if (requestData.transactionValue) body.transactionValue = requestData.transactionValue;
277
+ if (requestData.currency) body.currency = requestData.currency;
278
+ if (requestData.isSubAgentRequest) body.isSubAgentRequest = requestData.isSubAgentRequest;
279
+ if (requestData.parentAgentId) body.parentAgentId = requestData.parentAgentId;
280
+ if (requestData.subAgentDepth !== void 0) body.subAgentDepth = requestData.subAgentDepth;
281
+ if (requestData.enableRuntimeChallenge) body.enableRuntimeChallenge = requestData.enableRuntimeChallenge;
282
+ if (requestData.createSession) body.createSession = requestData.createSession;
283
+ if (requestData.counterpartyType) body.counterpartyType = requestData.counterpartyType;
284
+ if (requestData.runtimeChallengeOptions) body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;
285
+ const headers = {
286
+ "Content-Type": "application/json",
287
+ ...config.customHeaders
288
+ };
289
+ if (config.apiKey) {
290
+ headers["X-API-Key"] = config.apiKey;
291
+ }
292
+ if (credentials.authorizationHeader) {
293
+ headers["Authorization"] = credentials.authorizationHeader;
294
+ }
295
+ try {
296
+ const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
297
+ method: "POST",
298
+ headers,
299
+ body: JSON.stringify(body)
300
+ });
301
+ const data = await response.json();
302
+ if (!response.ok) {
303
+ return {
304
+ success: false,
305
+ error: data.message || data.error || `API returned ${response.status}`
306
+ };
307
+ }
308
+ return data;
309
+ } catch (error) {
310
+ const message = error instanceof Error ? error.message : "Unknown error";
311
+ return {
312
+ success: false,
313
+ error: `Failed to call verify-access API: ${message}`
314
+ };
315
+ }
316
+ }
317
+ async function verify(config, request) {
318
+ const mergedConfig = { ...DEFAULT_CONFIG, ...config };
319
+ if (!hasCredentials(request.credentials)) {
320
+ return createGuidanceResponse(mergedConfig, "No agent credentials provided");
321
+ }
322
+ if (mergedConfig.cacheTtl && mergedConfig.cacheTtl > 0) {
323
+ const cached = getCachedResult(request.credentials);
324
+ if (cached) {
325
+ if (mergedConfig.debug) {
326
+ console.log("[VerificationGateway] Returning cached result");
327
+ }
328
+ return cached;
329
+ }
330
+ }
331
+ if (mergedConfig.debug) {
332
+ console.log("[VerificationGateway] Calling verify-access API");
333
+ }
334
+ const apiResponse = await callVerifyAccessAPI(mergedConfig, request);
335
+ if (!apiResponse.success) {
336
+ return createGuidanceResponse(mergedConfig, apiResponse.error);
337
+ }
338
+ if (!apiResponse.access?.allowed) {
339
+ const result2 = {
340
+ verified: false,
341
+ accessLevel: "guidance",
342
+ denialReasons: apiResponse.access?.reason ? [apiResponse.access.reason] : ["Access denied"],
343
+ requiresStepUp: apiResponse.access?.requiresStepUp,
344
+ requiresApproval: apiResponse.access?.requiresApproval,
345
+ guidance: {
346
+ message: apiResponse.access?.reason || "Access denied by PDLSS policy",
347
+ registrationUrl: `${mergedConfig.apiBaseUrl?.replace("/api", "")}/register`,
348
+ documentationUrl: `${mergedConfig.apiBaseUrl?.replace("/api", "")}/docs/pdlss`
349
+ },
350
+ verifiedAt: /* @__PURE__ */ new Date()
351
+ };
352
+ return result2;
353
+ }
354
+ const agent = apiResponse.agent ? {
355
+ astraId: apiResponse.agent.astraId,
356
+ name: apiResponse.agent.name,
357
+ trustScore: apiResponse.agent.trustScore,
358
+ trustLevel: getTrustLevel(apiResponse.agent.trustScore),
359
+ blockchainVerified: apiResponse.agent.blockchainStatus === "verified",
360
+ status: apiResponse.agent.agentStatus
361
+ } : void 0;
362
+ const developer = apiResponse.developer ? {
363
+ astradId: apiResponse.developer.kyaOwnerId,
364
+ name: apiResponse.developer.fullName,
365
+ trustScore: apiResponse.developer.trustScore || 0,
366
+ verified: apiResponse.developer.identityVerified
367
+ } : void 0;
368
+ const organization = apiResponse.organization ? {
369
+ name: apiResponse.organization.name,
370
+ verified: apiResponse.organization.verified,
371
+ trustScore: apiResponse.organization.trustScore
372
+ } : void 0;
373
+ const pdlss = apiResponse.access?.pdlss ? {
374
+ purposeAllowed: apiResponse.access.pdlss.purposeAllowed,
375
+ withinDuration: apiResponse.access.pdlss.withinDuration,
376
+ withinLimits: apiResponse.access.pdlss.withinLimits,
377
+ scopeAllowed: apiResponse.access.pdlss.scopeAllowed,
378
+ selfInstantiationAllowed: apiResponse.access.pdlss.selfInstantiationAllowed,
379
+ appliedPolicy: apiResponse.access.appliedPolicy
380
+ } : void 0;
381
+ const trustScore = agent?.trustScore || 0;
382
+ const isOrgMember = false;
383
+ const accessLevel = determineAccessLevel(
384
+ true,
385
+ trustScore,
386
+ isOrgMember,
387
+ {
388
+ "read-only": 20,
389
+ standard: mergedConfig.minTrustScore || 40,
390
+ full: mergedConfig.minTrustScoreForFull || 70
391
+ }
392
+ );
393
+ const result = {
394
+ verified: true,
395
+ accessLevel,
396
+ agent,
397
+ developer,
398
+ organization,
399
+ pdlss,
400
+ requiresStepUp: apiResponse.access?.requiresStepUp,
401
+ requiresApproval: apiResponse.access?.requiresApproval,
402
+ verifiedAt: /* @__PURE__ */ new Date(),
403
+ cacheTtl: mergedConfig.cacheTtl,
404
+ // Handshake Protocol v10 enhanced fields (present when backend returns them)
405
+ sessionId: apiResponse.sessionId,
406
+ runtimeChallenge: apiResponse.runtimeChallenge,
407
+ tokenGuidance: apiResponse.tokenGuidance,
408
+ recommendation: apiResponse.recommendation,
409
+ recommendationReasons: apiResponse.recommendationReasons
410
+ };
411
+ if (result.recommendation === "deny") {
412
+ result.verified = false;
413
+ result.accessLevel = "none";
414
+ result.denialReasons = result.recommendationReasons || ["Access denied by AstraSync recommendation"];
415
+ if (result.runtimeChallenge) {
416
+ result.guidance = {
417
+ message: `Verification failed: ${result.runtimeChallenge.reason || "runtime challenge failed"}`,
418
+ registrationUrl: `${mergedConfig.apiBaseUrl?.replace("/api", "")}/register`,
419
+ documentationUrl: `${mergedConfig.apiBaseUrl?.replace("/api", "")}/docs/runtime-challenge`
420
+ };
421
+ }
422
+ } else if (result.recommendation === "step_up_required") {
423
+ result.requiresStepUp = true;
424
+ if (ACCESS_LEVEL_HIERARCHY[result.accessLevel] > ACCESS_LEVEL_HIERARCHY["read-only"]) {
425
+ result.accessLevel = "read-only";
426
+ }
427
+ result.denialReasons = result.recommendationReasons || ["Step-up verification required"];
428
+ }
429
+ if (mergedConfig.cacheTtl && mergedConfig.cacheTtl > 0 && result.recommendation !== "deny") {
430
+ cacheResult(request.credentials, result, mergedConfig.cacheTtl);
431
+ }
432
+ return result;
433
+ }
434
+ async function quickVerify(config, credentials) {
435
+ const result = await verify(config, {
436
+ credentials,
437
+ purpose: "verification"
438
+ });
439
+ return {
440
+ verified: result.verified,
441
+ accessLevel: result.accessLevel,
442
+ reason: result.denialReasons?.[0]
443
+ };
444
+ }
445
+
446
+ // src/adapters/express.ts
447
+ var express_exports = {};
448
+ __export(express_exports, {
449
+ createMiddleware: () => createMiddleware,
450
+ extractAstraSyncCredentials: () => extractAstraSyncCredentials,
451
+ requireAccess: () => requireAccess,
452
+ verifyOnly: () => verifyOnly
453
+ });
454
+
455
+ // src/transport/http.ts
456
+ var HEADER_PREFIX = "X-Astra-";
457
+ function setHttpHeaders(headers, credentials) {
458
+ const result = { ...headers };
459
+ result[`${HEADER_PREFIX}ID`] = credentials.agentId;
460
+ if (credentials.verifyUrl) {
461
+ result[`${HEADER_PREFIX}Verify`] = credentials.verifyUrl;
462
+ }
463
+ if (credentials.challengeUrl) {
464
+ result[`${HEADER_PREFIX}Challenge`] = credentials.challengeUrl;
465
+ }
466
+ if (credentials.pdlss?.purpose) {
467
+ const purposeValue = credentials.pdlss.purpose.action ? `${credentials.pdlss.purpose.category}:${credentials.pdlss.purpose.action}` : credentials.pdlss.purpose.category;
468
+ result[`${HEADER_PREFIX}Purpose`] = purposeValue;
469
+ }
470
+ if (credentials.pdlss?.duration?.maxSessionDuration) {
471
+ result[`${HEADER_PREFIX}Duration`] = String(credentials.pdlss.duration.maxSessionDuration);
472
+ }
473
+ if (credentials.pdlss?.scope?.jurisdiction) {
474
+ result[`${HEADER_PREFIX}Scope`] = credentials.pdlss.scope.jurisdiction;
475
+ }
476
+ return result;
477
+ }
478
+ function extractHttpCredentials(headers) {
479
+ const getValue = (key) => {
480
+ const v = headers[key] ?? headers[key.toLowerCase()];
481
+ return Array.isArray(v) ? v[0] : v;
482
+ };
483
+ const agentId = getValue(`${HEADER_PREFIX}ID`) ?? getValue("x-astra-id");
484
+ if (!agentId) return null;
485
+ const credentials = { agentId };
486
+ const verifyUrl = getValue(`${HEADER_PREFIX}Verify`) ?? getValue("x-astra-verify");
487
+ if (verifyUrl) credentials.verifyUrl = verifyUrl;
488
+ const challengeUrl = getValue(`${HEADER_PREFIX}Challenge`) ?? getValue("x-astra-challenge");
489
+ if (challengeUrl) credentials.challengeUrl = challengeUrl;
490
+ const purpose = getValue(`${HEADER_PREFIX}Purpose`) ?? getValue("x-astra-purpose");
491
+ if (purpose) {
492
+ const [category, action] = purpose.split(":");
493
+ credentials.pdlss = {
494
+ ...credentials.pdlss,
495
+ purpose: { category, action }
496
+ };
497
+ }
498
+ const duration = getValue(`${HEADER_PREFIX}Duration`) ?? getValue("x-astra-duration");
499
+ if (duration) {
500
+ credentials.pdlss = {
501
+ ...credentials.pdlss,
502
+ duration: { maxSessionDuration: parseInt(duration, 10) }
503
+ };
504
+ }
505
+ const scope = getValue(`${HEADER_PREFIX}Scope`) ?? getValue("x-astra-scope");
506
+ if (scope) {
507
+ credentials.pdlss = {
508
+ ...credentials.pdlss,
509
+ scope: { jurisdiction: scope }
510
+ };
511
+ }
512
+ return credentials;
513
+ }
514
+
515
+ // src/adapters/express.ts
516
+ function defaultExtractCredentials(req) {
517
+ return extractCredentials(
518
+ req.headers,
519
+ req.query
520
+ );
521
+ }
522
+ function extractAstraSyncCredentials(req) {
523
+ return extractHttpCredentials(req.headers);
524
+ }
525
+ function defaultExtractPurpose(req) {
526
+ const purposeHeader = req.headers["x-purpose"] || req.headers["X-Purpose"];
527
+ if (purposeHeader) {
528
+ return Array.isArray(purposeHeader) ? purposeHeader[0] : purposeHeader;
529
+ }
530
+ if (req.query.purpose && typeof req.query.purpose === "string") {
531
+ return req.query.purpose;
532
+ }
533
+ switch (req.method) {
534
+ case "GET":
535
+ return "read";
536
+ case "POST":
537
+ return "create";
538
+ case "PUT":
539
+ case "PATCH":
540
+ return "update";
541
+ case "DELETE":
542
+ return "delete";
543
+ default:
544
+ return "general";
545
+ }
546
+ }
547
+ function matchRoute(pattern, path) {
548
+ const regexPattern = pattern.replace(/\*/g, ".*").replace(/\//g, "\\/");
549
+ const regex = new RegExp(`^${regexPattern}$`);
550
+ return regex.test(path);
551
+ }
552
+ function findRouteConfig(routes, path, method) {
553
+ return routes.find((route) => {
554
+ const methodMatches = route.method === "*" || route.method.toUpperCase() === method.toUpperCase();
555
+ const pathMatches = matchRoute(route.pattern, path);
556
+ return methodMatches && pathMatches;
557
+ });
558
+ }
559
+ function defaultOnDenied(result, _req, res) {
560
+ const statusCode = result.verified ? 403 : 401;
561
+ res.status(statusCode).json({
562
+ success: false,
563
+ error: {
564
+ code: result.verified ? "INSUFFICIENT_ACCESS" : "UNAUTHORIZED",
565
+ message: result.denialReasons?.[0] || "Access denied",
566
+ accessLevel: result.accessLevel,
567
+ guidance: result.guidance
568
+ }
569
+ });
570
+ }
571
+ function createMiddleware(options) {
572
+ const {
573
+ routes = [],
574
+ extractCredentials: customExtractCredentials,
575
+ extractPurpose: customExtractPurpose,
576
+ skipPaths = [],
577
+ onDenied = defaultOnDenied,
578
+ ...config
579
+ } = options;
580
+ return async (req, res, next) => {
581
+ try {
582
+ const shouldSkip = skipPaths.some((pattern) => matchRoute(pattern, req.path));
583
+ if (shouldSkip) {
584
+ return next();
585
+ }
586
+ const routeConfig = findRouteConfig(routes, req.path, req.method);
587
+ if (!routeConfig) {
588
+ return next();
589
+ }
590
+ if (routeConfig.minAccessLevel === "none") {
591
+ return next();
592
+ }
593
+ const credentials = customExtractCredentials ? customExtractCredentials(req) : defaultExtractCredentials(req);
594
+ if (!hasCredentials(credentials) && routeConfig.minAccessLevel !== "guidance") {
595
+ const result2 = {
596
+ verified: false,
597
+ accessLevel: "none",
598
+ denialReasons: ["No agent credentials provided"],
599
+ guidance: {
600
+ message: "This endpoint requires agent verification. Please provide your ASTRA-ID.",
601
+ registrationUrl: `${config.apiBaseUrl?.replace("/api", "")}/register`,
602
+ documentationUrl: `${config.apiBaseUrl?.replace("/api", "")}/docs/agent-access`
603
+ },
604
+ verifiedAt: /* @__PURE__ */ new Date()
605
+ };
606
+ req.agentVerification = result2;
607
+ onDenied(result2, req, res);
608
+ return;
609
+ }
610
+ const purpose = customExtractPurpose ? customExtractPurpose(req) : defaultExtractPurpose(req);
611
+ const result = await verify(config, {
612
+ credentials,
613
+ purpose,
614
+ action: req.method.toLowerCase(),
615
+ resource: req.path,
616
+ clientIp: req.ip,
617
+ userAgent: req.headers["user-agent"]
618
+ });
619
+ req.agentVerification = result;
620
+ if (!hasMinimumAccess(result.accessLevel, routeConfig.minAccessLevel)) {
621
+ onDenied(result, req, res);
622
+ return;
623
+ }
624
+ if (routeConfig.minTrustScore && result.agent) {
625
+ if (result.agent.trustScore < routeConfig.minTrustScore) {
626
+ result.denialReasons = [
627
+ `Trust score ${result.agent.trustScore} is below required ${routeConfig.minTrustScore}`
628
+ ];
629
+ onDenied(result, req, res);
630
+ return;
631
+ }
632
+ }
633
+ next();
634
+ } catch (error) {
635
+ console.error("[VerificationGateway] Middleware error:", error);
636
+ next();
637
+ }
638
+ };
639
+ }
640
+ function requireAccess(minAccessLevel, options) {
641
+ return createMiddleware({
642
+ ...options,
643
+ routes: [
644
+ { pattern: "*", method: "*", minAccessLevel }
645
+ ]
646
+ });
647
+ }
648
+ function verifyOnly(options) {
649
+ return createMiddleware({
650
+ ...options,
651
+ routes: [
652
+ { pattern: "*", method: "*", minAccessLevel: "none" }
653
+ ]
654
+ });
655
+ }
656
+
657
+ // src/adapters/nextjs.ts
658
+ var nextjs_exports = {};
659
+ __export(nextjs_exports, {
660
+ createMatcherConfig: () => createMatcherConfig,
661
+ createMiddleware: () => createMiddleware2
662
+ });
663
+ function extractCredentialsFromNextRequest(request) {
664
+ const credentials = {};
665
+ const astraId = request.headers.get("x-astra-id") || request.headers.get("X-Astra-Id");
666
+ if (astraId) {
667
+ credentials.astraId = astraId;
668
+ }
669
+ const apiKey = request.headers.get("x-api-key") || request.headers.get("X-Api-Key");
670
+ if (apiKey) {
671
+ credentials.apiKey = apiKey;
672
+ }
673
+ const authHeader = request.headers.get("authorization");
674
+ if (authHeader) {
675
+ credentials.authorizationHeader = authHeader;
676
+ if (authHeader.startsWith("Bearer ")) {
677
+ credentials.jwt = authHeader.slice(7);
678
+ }
679
+ }
680
+ const url = new URL(request.url);
681
+ const astraIdParam = url.searchParams.get("astraId");
682
+ const apiKeyParam = url.searchParams.get("apiKey");
683
+ if (astraIdParam && !credentials.astraId) {
684
+ credentials.astraId = astraIdParam;
685
+ }
686
+ if (apiKeyParam && !credentials.apiKey) {
687
+ credentials.apiKey = apiKeyParam;
688
+ }
689
+ return credentials;
690
+ }
691
+ function matchRoute2(pattern, path) {
692
+ const regexPattern = pattern.replace(/\*/g, ".*").replace(/\//g, "\\/");
693
+ const regex = new RegExp(`^${regexPattern}$`);
694
+ return regex.test(path);
695
+ }
696
+ function findRouteConfig2(routes, path, method) {
697
+ return routes.find((route) => {
698
+ const methodMatches = route.method === "*" || route.method.toUpperCase() === method.toUpperCase();
699
+ const pathMatches = matchRoute2(route.pattern, path);
700
+ return methodMatches && pathMatches;
701
+ });
702
+ }
703
+ function inferPurpose(method) {
704
+ switch (method.toUpperCase()) {
705
+ case "GET":
706
+ return "read";
707
+ case "POST":
708
+ return "create";
709
+ case "PUT":
710
+ case "PATCH":
711
+ return "update";
712
+ case "DELETE":
713
+ return "delete";
714
+ default:
715
+ return "general";
716
+ }
717
+ }
718
+ function generateCommerceShieldHtml(result, options) {
719
+ const title = options.commerceShield?.title || "AstraSync Agent Verification";
720
+ const message = options.commerceShield?.message || result.guidance?.message || "This site verifies AI agents before granting access. We noticed you're visiting without AstraSync credentials.";
721
+ const registrationUrl = result.guidance?.registrationUrl || "https://astrasync.ai/register";
722
+ const docsUrl = result.guidance?.documentationUrl || "https://astrasync.ai/docs/agent-access";
723
+ const allowGuest = options.commerceShield?.allowGuestAccess ?? true;
724
+ return `
725
+ <!DOCTYPE html>
726
+ <html lang="en">
727
+ <head>
728
+ <meta charset="UTF-8">
729
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
730
+ <title>${title}</title>
731
+ <style>
732
+ * {
733
+ box-sizing: border-box;
734
+ margin: 0;
735
+ padding: 0;
736
+ }
737
+ body {
738
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
739
+ background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
740
+ min-height: 100vh;
741
+ display: flex;
742
+ align-items: center;
743
+ justify-content: center;
744
+ padding: 20px;
745
+ }
746
+ .shield-container {
747
+ background: rgba(255, 255, 255, 0.95);
748
+ border-radius: 16px;
749
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
750
+ max-width: 480px;
751
+ width: 100%;
752
+ padding: 40px;
753
+ text-align: center;
754
+ }
755
+ .shield-icon {
756
+ font-size: 48px;
757
+ margin-bottom: 20px;
758
+ }
759
+ .shield-title {
760
+ font-size: 24px;
761
+ font-weight: 700;
762
+ color: #1a1a2e;
763
+ margin-bottom: 16px;
764
+ }
765
+ .shield-message {
766
+ color: #4a5568;
767
+ line-height: 1.6;
768
+ margin-bottom: 24px;
769
+ }
770
+ .shield-steps {
771
+ text-align: left;
772
+ background: #f7fafc;
773
+ border-radius: 8px;
774
+ padding: 20px;
775
+ margin-bottom: 24px;
776
+ }
777
+ .shield-steps h3 {
778
+ font-size: 14px;
779
+ font-weight: 600;
780
+ color: #2d3748;
781
+ margin-bottom: 12px;
782
+ }
783
+ .shield-steps ol {
784
+ padding-left: 20px;
785
+ color: #4a5568;
786
+ }
787
+ .shield-steps li {
788
+ margin-bottom: 8px;
789
+ }
790
+ .shield-buttons {
791
+ display: flex;
792
+ flex-direction: column;
793
+ gap: 12px;
794
+ }
795
+ .btn {
796
+ display: inline-block;
797
+ padding: 14px 24px;
798
+ border-radius: 8px;
799
+ font-weight: 600;
800
+ text-decoration: none;
801
+ transition: all 0.2s;
802
+ cursor: pointer;
803
+ border: none;
804
+ font-size: 16px;
805
+ }
806
+ .btn-primary {
807
+ background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);
808
+ color: white;
809
+ }
810
+ .btn-primary:hover {
811
+ transform: translateY(-2px);
812
+ box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4);
813
+ }
814
+ .btn-secondary {
815
+ background: #e2e8f0;
816
+ color: #4a5568;
817
+ }
818
+ .btn-secondary:hover {
819
+ background: #cbd5e0;
820
+ }
821
+ .shield-footer {
822
+ margin-top: 24px;
823
+ font-size: 14px;
824
+ color: #718096;
825
+ }
826
+ .shield-footer a {
827
+ color: #6366f1;
828
+ text-decoration: none;
829
+ }
830
+ .shield-footer a:hover {
831
+ text-decoration: underline;
832
+ }
833
+ </style>
834
+ </head>
835
+ <body>
836
+ <div class="shield-container">
837
+ <div class="shield-icon">\u{1F6E1}\uFE0F</div>
838
+ <h1 class="shield-title">${title}</h1>
839
+ <p class="shield-message">${message}</p>
840
+
841
+ <div class="shield-steps">
842
+ <h3>To get verified access:</h3>
843
+ <ol>
844
+ <li>Register at <a href="${registrationUrl}">astrasync.ai/register</a></li>
845
+ <li>Create and register your agent</li>
846
+ <li>Add your ASTRA-ID to request headers</li>
847
+ <li>Refresh this page</li>
848
+ </ol>
849
+ </div>
850
+
851
+ <div class="shield-buttons">
852
+ <a href="${registrationUrl}" class="btn btn-primary">Register Now</a>
853
+ ${allowGuest ? '<button onclick="window.location.reload()" class="btn btn-secondary">Continue as Guest (Limited)</button>' : ""}
854
+ </div>
855
+
856
+ <p class="shield-footer">
857
+ Learn more: <a href="${docsUrl}">Agent Access Documentation</a>
858
+ </p>
859
+ </div>
860
+ </body>
861
+ </html>
862
+ `.trim();
863
+ }
864
+ function createMiddleware2(options) {
865
+ const {
866
+ routes = [],
867
+ skipPaths = [],
868
+ showCommerceShield = true,
869
+ ...config
870
+ } = options;
871
+ return async function middleware(request) {
872
+ const { NextResponse } = await import("next/server");
873
+ const pathname = request.nextUrl.pathname;
874
+ const shouldSkip = skipPaths.some((pattern) => matchRoute2(pattern, pathname));
875
+ if (shouldSkip) {
876
+ return NextResponse.next();
877
+ }
878
+ const routeConfig = findRouteConfig2(routes, pathname, request.method);
879
+ if (!routeConfig) {
880
+ return NextResponse.next();
881
+ }
882
+ if (routeConfig.minAccessLevel === "none") {
883
+ return NextResponse.next();
884
+ }
885
+ const credentials = extractCredentialsFromNextRequest(request);
886
+ if (!hasCredentials(credentials) && routeConfig.minAccessLevel !== "guidance") {
887
+ const result2 = {
888
+ verified: false,
889
+ accessLevel: "none",
890
+ denialReasons: ["No agent credentials provided"],
891
+ guidance: {
892
+ message: "This page requires agent verification.",
893
+ registrationUrl: `${config.apiBaseUrl?.replace("/api", "")}/register`,
894
+ documentationUrl: `${config.apiBaseUrl?.replace("/api", "")}/docs/agent-access`
895
+ },
896
+ verifiedAt: /* @__PURE__ */ new Date()
897
+ };
898
+ if (pathname.startsWith("/api/")) {
899
+ return NextResponse.json(
900
+ {
901
+ success: false,
902
+ error: {
903
+ code: "UNAUTHORIZED",
904
+ message: "No agent credentials provided",
905
+ guidance: result2.guidance
906
+ }
907
+ },
908
+ { status: 401 }
909
+ );
910
+ }
911
+ if (showCommerceShield) {
912
+ return new NextResponse(generateCommerceShieldHtml(result2, options), {
913
+ status: 200,
914
+ headers: {
915
+ "Content-Type": "text/html",
916
+ "X-AstraSync-Verification": "commerce-shield"
917
+ }
918
+ });
919
+ }
920
+ const registerUrl = result2.guidance?.registrationUrl || "/register";
921
+ return NextResponse.redirect(new URL(registerUrl, request.url));
922
+ }
923
+ const purpose = request.headers.get("x-purpose") || inferPurpose(request.method);
924
+ const result = await verify(config, {
925
+ credentials,
926
+ purpose,
927
+ action: request.method.toLowerCase(),
928
+ resource: pathname,
929
+ clientIp: request.headers.get("x-forwarded-for")?.split(",")[0]?.trim() || void 0,
930
+ userAgent: request.headers.get("user-agent") || void 0
931
+ });
932
+ if (!hasMinimumAccess(result.accessLevel, routeConfig.minAccessLevel)) {
933
+ if (pathname.startsWith("/api/")) {
934
+ return NextResponse.json(
935
+ {
936
+ success: false,
937
+ error: {
938
+ code: result.verified ? "INSUFFICIENT_ACCESS" : "UNAUTHORIZED",
939
+ message: result.denialReasons?.[0] || "Access denied",
940
+ accessLevel: result.accessLevel,
941
+ required: routeConfig.minAccessLevel,
942
+ guidance: result.guidance
943
+ }
944
+ },
945
+ { status: result.verified ? 403 : 401 }
946
+ );
947
+ }
948
+ if (showCommerceShield) {
949
+ return new NextResponse(generateCommerceShieldHtml(result, options), {
950
+ status: 200,
951
+ headers: {
952
+ "Content-Type": "text/html",
953
+ "X-AstraSync-Verification": "commerce-shield"
954
+ }
955
+ });
956
+ }
957
+ return NextResponse.redirect(new URL("/unauthorized", request.url));
958
+ }
959
+ const response = NextResponse.next();
960
+ response.headers.set("X-AstraSync-Verified", result.verified.toString());
961
+ response.headers.set("X-AstraSync-Access-Level", result.accessLevel);
962
+ if (result.agent) {
963
+ response.headers.set("X-AstraSync-Agent-Id", result.agent.astraId);
964
+ response.headers.set("X-AstraSync-Trust-Score", result.agent.trustScore.toString());
965
+ }
966
+ return response;
967
+ };
968
+ }
969
+ function createMatcherConfig(paths) {
970
+ return { matcher: paths };
971
+ }
972
+
973
+ // src/adapters/sdk.ts
974
+ var sdk_exports = {};
975
+ __export(sdk_exports, {
976
+ VerificationGatewayClient: () => VerificationGatewayClient,
977
+ createClient: () => createClient,
978
+ getCapabilities: () => getCapabilities,
979
+ getTrustLevel: () => getTrustLevel,
980
+ hasMinimumAccess: () => hasMinimumAccess,
981
+ verifyOnce: () => verifyOnce
982
+ });
983
+ var VerificationGatewayClient = class {
984
+ constructor(options) {
985
+ this.config = {
986
+ apiBaseUrl: options.apiBaseUrl,
987
+ apiKey: options.apiKey,
988
+ defaultAccessLevel: options.defaultAccessLevel,
989
+ minTrustScore: options.minTrustScore,
990
+ minTrustScoreForFull: options.minTrustScoreForFull,
991
+ cacheTtl: options.cacheTtl,
992
+ debug: options.debug,
993
+ customHeaders: options.customHeaders
994
+ };
995
+ this.timeout = options.timeout || 1e4;
996
+ this.retryConfig = options.retry || { maxRetries: 3, backoffMs: 1e3 };
997
+ }
998
+ /**
999
+ * Full verification with all details
1000
+ */
1001
+ async verify(options) {
1002
+ const credentials = {
1003
+ astraId: options.astraId,
1004
+ apiKey: options.apiKey,
1005
+ jwt: options.jwt
1006
+ };
1007
+ return this.executeWithRetry(
1008
+ () => verify(this.config, {
1009
+ credentials,
1010
+ purpose: options.purpose,
1011
+ action: options.action,
1012
+ resourceType: options.resourceType,
1013
+ resource: options.resource,
1014
+ jurisdiction: options.jurisdiction,
1015
+ transactionValue: options.transactionValue,
1016
+ currency: options.currency,
1017
+ isSubAgentRequest: options.isSubAgentRequest,
1018
+ parentAgentId: options.parentAgentId,
1019
+ subAgentDepth: options.subAgentDepth
1020
+ })
1021
+ );
1022
+ }
1023
+ /**
1024
+ * Quick verification - just check if credentials are valid
1025
+ */
1026
+ async quickVerify(credentials) {
1027
+ return this.executeWithRetry(() => quickVerify(this.config, credentials));
1028
+ }
1029
+ /**
1030
+ * Check if an agent has a specific access level
1031
+ */
1032
+ async hasAccess(credentials, requiredLevel) {
1033
+ const result = await this.quickVerify(credentials);
1034
+ return hasMinimumAccess(result.accessLevel, requiredLevel);
1035
+ }
1036
+ /**
1037
+ * Get capabilities for a verified agent
1038
+ */
1039
+ async getCapabilities(credentials) {
1040
+ const result = await this.quickVerify(credentials);
1041
+ return getCapabilities(result.accessLevel);
1042
+ }
1043
+ /**
1044
+ * Verify a specific ASTRA-ID
1045
+ */
1046
+ async verifyAstraId(astraId, options) {
1047
+ return this.verify({
1048
+ astraId,
1049
+ purpose: options?.purpose,
1050
+ action: options?.action
1051
+ });
1052
+ }
1053
+ /**
1054
+ * Verify using an API key
1055
+ */
1056
+ async verifyApiKey(apiKey, options) {
1057
+ return this.verify({
1058
+ apiKey,
1059
+ purpose: options?.purpose,
1060
+ action: options?.action
1061
+ });
1062
+ }
1063
+ /**
1064
+ * Clear the verification cache
1065
+ */
1066
+ clearCache() {
1067
+ clearCache();
1068
+ }
1069
+ /**
1070
+ * Execute a function with retry logic
1071
+ */
1072
+ async executeWithRetry(fn) {
1073
+ let lastError = null;
1074
+ for (let attempt = 0; attempt <= this.retryConfig.maxRetries; attempt++) {
1075
+ try {
1076
+ const result = await Promise.race([
1077
+ fn(),
1078
+ new Promise(
1079
+ (_, reject) => setTimeout(() => reject(new Error("Request timeout")), this.timeout)
1080
+ )
1081
+ ]);
1082
+ return result;
1083
+ } catch (error) {
1084
+ lastError = error instanceof Error ? error : new Error(String(error));
1085
+ if (attempt < this.retryConfig.maxRetries) {
1086
+ const backoff = this.retryConfig.backoffMs * Math.pow(2, attempt);
1087
+ await new Promise((resolve) => setTimeout(resolve, backoff));
1088
+ }
1089
+ }
1090
+ }
1091
+ throw lastError || new Error("Verification failed after retries");
1092
+ }
1093
+ };
1094
+ function createClient(options) {
1095
+ return new VerificationGatewayClient(options);
1096
+ }
1097
+ async function verifyOnce(options) {
1098
+ const client = createClient(options);
1099
+ return client.verify(options);
1100
+ }
1101
+
1102
+ // src/transport/index.ts
1103
+ var transport_exports = {};
1104
+ __export(transport_exports, {
1105
+ applyCredentials: () => applyCredentials,
1106
+ detectProtocol: () => detectProtocol,
1107
+ extractA2ACredentials: () => extractA2ACredentials,
1108
+ extractCredentialsFromProtocol: () => extractCredentialsFromProtocol,
1109
+ extractHttpCredentials: () => extractHttpCredentials,
1110
+ extractMcpCredentials: () => extractMcpCredentials,
1111
+ setA2AMetadata: () => setA2AMetadata,
1112
+ setHttpHeaders: () => setHttpHeaders,
1113
+ setMcpMeta: () => setMcpMeta
1114
+ });
1115
+
1116
+ // src/transport/a2a.ts
1117
+ function setA2AMetadata(task, credentials) {
1118
+ const astrasync = {
1119
+ agentId: credentials.agentId
1120
+ };
1121
+ if (credentials.verifyUrl) astrasync.verifyUrl = credentials.verifyUrl;
1122
+ if (credentials.challengeUrl) astrasync.challengeUrl = credentials.challengeUrl;
1123
+ if (credentials.pdlss?.purpose) astrasync.purpose = credentials.pdlss.purpose;
1124
+ if (credentials.pdlss?.duration) astrasync.duration = credentials.pdlss.duration;
1125
+ if (credentials.pdlss?.scope) astrasync.scope = credentials.pdlss.scope;
1126
+ return {
1127
+ ...task,
1128
+ metadata: {
1129
+ ...task.metadata,
1130
+ astrasync
1131
+ }
1132
+ };
1133
+ }
1134
+ function extractA2ACredentials(task) {
1135
+ const meta = task.metadata?.astrasync;
1136
+ if (!meta?.agentId) return null;
1137
+ const credentials = {
1138
+ agentId: meta.agentId
1139
+ };
1140
+ if (meta.verifyUrl) credentials.verifyUrl = meta.verifyUrl;
1141
+ if (meta.challengeUrl) credentials.challengeUrl = meta.challengeUrl;
1142
+ if (meta.purpose || meta.duration || meta.scope) {
1143
+ credentials.pdlss = {};
1144
+ if (meta.purpose) credentials.pdlss.purpose = meta.purpose;
1145
+ if (meta.duration) credentials.pdlss.duration = meta.duration;
1146
+ if (meta.scope) credentials.pdlss.scope = meta.scope;
1147
+ }
1148
+ return credentials;
1149
+ }
1150
+
1151
+ // src/transport/mcp.ts
1152
+ function setMcpMeta(params, credentials) {
1153
+ const astrasync = {
1154
+ agentId: credentials.agentId
1155
+ };
1156
+ if (credentials.verifyUrl) astrasync.verifyUrl = credentials.verifyUrl;
1157
+ if (credentials.challengeUrl) astrasync.challengeUrl = credentials.challengeUrl;
1158
+ if (credentials.pdlss?.purpose) astrasync.purpose = credentials.pdlss.purpose;
1159
+ if (credentials.pdlss?.duration) astrasync.duration = credentials.pdlss.duration;
1160
+ if (credentials.pdlss?.scope) astrasync.scope = credentials.pdlss.scope;
1161
+ return {
1162
+ ...params,
1163
+ _meta: {
1164
+ ...params._meta,
1165
+ astrasync
1166
+ }
1167
+ };
1168
+ }
1169
+ function extractMcpCredentials(params) {
1170
+ const meta = params._meta?.astrasync;
1171
+ if (!meta?.agentId) return null;
1172
+ const credentials = {
1173
+ agentId: meta.agentId
1174
+ };
1175
+ if (meta.verifyUrl) credentials.verifyUrl = meta.verifyUrl;
1176
+ if (meta.challengeUrl) credentials.challengeUrl = meta.challengeUrl;
1177
+ if (meta.purpose || meta.duration || meta.scope) {
1178
+ credentials.pdlss = {};
1179
+ if (meta.purpose) credentials.pdlss.purpose = meta.purpose;
1180
+ if (meta.duration) credentials.pdlss.duration = meta.duration;
1181
+ if (meta.scope) credentials.pdlss.scope = meta.scope;
1182
+ }
1183
+ return credentials;
1184
+ }
1185
+
1186
+ // src/transport/index.ts
1187
+ function detectProtocol(context) {
1188
+ if (context.metadata && typeof context.metadata === "object") {
1189
+ return "a2a";
1190
+ }
1191
+ if (context._meta && typeof context._meta === "object") {
1192
+ return "mcp";
1193
+ }
1194
+ return "http";
1195
+ }
1196
+ function applyCredentials(protocol, target, credentials) {
1197
+ switch (protocol) {
1198
+ case "http":
1199
+ return setHttpHeaders(target, credentials);
1200
+ case "a2a":
1201
+ return setA2AMetadata(target, credentials);
1202
+ case "mcp":
1203
+ return setMcpMeta(target, credentials);
1204
+ default:
1205
+ return target;
1206
+ }
1207
+ }
1208
+ function extractCredentialsFromProtocol(protocol, context) {
1209
+ switch (protocol) {
1210
+ case "http":
1211
+ return extractHttpCredentials(context);
1212
+ case "a2a":
1213
+ return extractA2ACredentials(context);
1214
+ case "mcp":
1215
+ return extractMcpCredentials(context);
1216
+ default:
1217
+ return null;
1218
+ }
1219
+ }
1220
+
1221
+ // src/agent/index.ts
1222
+ var agent_exports = {};
1223
+ __export(agent_exports, {
1224
+ AgentClient: () => AgentClient,
1225
+ ChallengeHandler: () => ChallengeHandler,
1226
+ formatPDLSSForTransport: () => formatPDLSSForTransport,
1227
+ parsePDLSSFromTransport: () => parsePDLSSFromTransport,
1228
+ recordDecision: () => recordDecision
1229
+ });
1230
+
1231
+ // src/agent/client.ts
1232
+ var AgentClient = class {
1233
+ constructor(config) {
1234
+ this.credentials = {
1235
+ agentId: config.agentId,
1236
+ verifyUrl: config.verifyUrl ?? "https://api.astrasync.ai/agents/verify-access",
1237
+ challengeUrl: config.challengeUrl,
1238
+ pdlss: config.pdlss
1239
+ };
1240
+ }
1241
+ /**
1242
+ * Make an HTTP request with AstraSync headers automatically injected.
1243
+ */
1244
+ async fetch(url, options) {
1245
+ const { purpose, action, ...fetchOptions } = options ?? {};
1246
+ const creds = { ...this.credentials };
1247
+ if (purpose) {
1248
+ creds.pdlss = {
1249
+ ...creds.pdlss,
1250
+ purpose: { category: purpose, action }
1251
+ };
1252
+ }
1253
+ const existingHeaders = {};
1254
+ if (fetchOptions.headers) {
1255
+ if (fetchOptions.headers instanceof Headers) {
1256
+ fetchOptions.headers.forEach((value, key) => {
1257
+ existingHeaders[key] = value;
1258
+ });
1259
+ } else if (Array.isArray(fetchOptions.headers)) {
1260
+ for (const [key, value] of fetchOptions.headers) {
1261
+ existingHeaders[key] = value;
1262
+ }
1263
+ } else {
1264
+ Object.assign(existingHeaders, fetchOptions.headers);
1265
+ }
1266
+ }
1267
+ const enrichedHeaders = setHttpHeaders(existingHeaders, creds);
1268
+ return fetch(url, {
1269
+ ...fetchOptions,
1270
+ headers: enrichedHeaders
1271
+ });
1272
+ }
1273
+ /**
1274
+ * Prepare A2A task metadata with AstraSync credentials.
1275
+ */
1276
+ prepareA2AMetadata(task, overrides) {
1277
+ const creds = this.buildCredentials(overrides);
1278
+ return setA2AMetadata(task, creds);
1279
+ }
1280
+ /**
1281
+ * Prepare MCP params with AstraSync _meta.
1282
+ */
1283
+ prepareMcpMeta(params, overrides) {
1284
+ const creds = this.buildCredentials(overrides);
1285
+ return setMcpMeta(params, creds);
1286
+ }
1287
+ /**
1288
+ * Generic: apply credentials to any protocol.
1289
+ */
1290
+ applyCredentials(protocol, target, overrides) {
1291
+ const creds = this.buildCredentials(overrides);
1292
+ return applyCredentials(protocol, target, creds);
1293
+ }
1294
+ buildCredentials(overrides) {
1295
+ if (!overrides?.purpose) return this.credentials;
1296
+ return {
1297
+ ...this.credentials,
1298
+ pdlss: {
1299
+ ...this.credentials.pdlss,
1300
+ purpose: { category: overrides.purpose, action: overrides.action }
1301
+ }
1302
+ };
1303
+ }
1304
+ };
1305
+
1306
+ // src/agent/challenge-handler.ts
1307
+ var ChallengeHandler = class {
1308
+ constructor(config) {
1309
+ this.pendingCounterparties = /* @__PURE__ */ new Set();
1310
+ this.agentId = config.agentId;
1311
+ }
1312
+ /**
1313
+ * Register a counterparty as pending (before initiating contact).
1314
+ */
1315
+ registerPending(counterpartyId) {
1316
+ this.pendingCounterparties.add(counterpartyId);
1317
+ }
1318
+ /**
1319
+ * Remove a counterparty from pending list (after interaction complete).
1320
+ */
1321
+ removePending(counterpartyId) {
1322
+ this.pendingCounterparties.delete(counterpartyId);
1323
+ }
1324
+ /**
1325
+ * Get current pending counterparties list.
1326
+ */
1327
+ getPendingList() {
1328
+ return [...this.pendingCounterparties];
1329
+ }
1330
+ /**
1331
+ * Express middleware for the challenge endpoint.
1332
+ * Mount at: app.post('/astrasync/challenge', handler.expressMiddleware())
1333
+ */
1334
+ expressMiddleware() {
1335
+ return (req, res) => {
1336
+ const result = this.handleChallenge(req.body);
1337
+ res.status(result.status).json(result.body);
1338
+ };
1339
+ }
1340
+ /**
1341
+ * Generic handler (framework-agnostic).
1342
+ * Returns { status, body } for the caller to send.
1343
+ */
1344
+ handleChallenge(body) {
1345
+ if (!body || typeof body !== "object") {
1346
+ return {
1347
+ status: 400,
1348
+ body: {
1349
+ challengeId: "",
1350
+ acknowledged: false,
1351
+ pendingCounterparties: [],
1352
+ respondedAt: (/* @__PURE__ */ new Date()).toISOString(),
1353
+ error: "Invalid challenge payload"
1354
+ }
1355
+ };
1356
+ }
1357
+ const payload = body;
1358
+ if (!payload.challengeId || !payload.issuedAt || !payload.expiresAt) {
1359
+ return {
1360
+ status: 400,
1361
+ body: {
1362
+ challengeId: payload.challengeId ?? "",
1363
+ acknowledged: false,
1364
+ pendingCounterparties: [],
1365
+ respondedAt: (/* @__PURE__ */ new Date()).toISOString(),
1366
+ error: "Missing required challenge fields"
1367
+ }
1368
+ };
1369
+ }
1370
+ const now = /* @__PURE__ */ new Date();
1371
+ const expiresAt = new Date(payload.expiresAt);
1372
+ if (now > expiresAt) {
1373
+ return {
1374
+ status: 410,
1375
+ body: {
1376
+ challengeId: payload.challengeId,
1377
+ acknowledged: false,
1378
+ pendingCounterparties: [],
1379
+ respondedAt: now.toISOString(),
1380
+ error: "Challenge has expired"
1381
+ }
1382
+ };
1383
+ }
1384
+ return {
1385
+ status: 200,
1386
+ body: {
1387
+ challengeId: payload.challengeId,
1388
+ acknowledged: true,
1389
+ pendingCounterparties: this.getPendingList(),
1390
+ respondedAt: now.toISOString()
1391
+ }
1392
+ };
1393
+ }
1394
+ };
1395
+
1396
+ // src/agent/pdlss-formatter.ts
1397
+ function formatPDLSSForTransport(pdlss) {
1398
+ const transport = {};
1399
+ if (pdlss.purpose?.categories?.length) {
1400
+ transport.purpose = {
1401
+ category: pdlss.purpose.categories[0],
1402
+ action: pdlss.purpose.allowedActions?.[0]
1403
+ };
1404
+ }
1405
+ if (pdlss.duration) {
1406
+ const candidates = [];
1407
+ if (pdlss.duration.maxSessionDuration) candidates.push(pdlss.duration.maxSessionDuration);
1408
+ if (pdlss.duration.ttl) candidates.push(pdlss.duration.ttl);
1409
+ if (candidates.length > 0) {
1410
+ transport.duration = { maxSessionDuration: Math.min(...candidates) };
1411
+ }
1412
+ }
1413
+ if (pdlss.scope?.jurisdictions?.length) {
1414
+ transport.scope = { jurisdiction: pdlss.scope.jurisdictions[0] };
1415
+ }
1416
+ return transport;
1417
+ }
1418
+ function parsePDLSSFromTransport(transport) {
1419
+ const pdlss = {};
1420
+ if (transport.purpose) {
1421
+ pdlss.purpose = {
1422
+ categories: [transport.purpose.category],
1423
+ allowedActions: transport.purpose.action ? [transport.purpose.action] : void 0
1424
+ };
1425
+ }
1426
+ if (transport.duration) {
1427
+ pdlss.duration = {
1428
+ maxSessionDuration: transport.duration.maxSessionDuration
1429
+ };
1430
+ }
1431
+ if (transport.scope) {
1432
+ pdlss.scope = {
1433
+ jurisdictions: transport.scope.jurisdiction ? [transport.scope.jurisdiction] : void 0
1434
+ };
1435
+ }
1436
+ return pdlss;
1437
+ }
1438
+
1439
+ // src/agent/decision-client.ts
1440
+ async function recordDecision(config, params) {
1441
+ const { sessionId, ...body } = params;
1442
+ const baseUrl = config.apiBaseUrl.replace(/\/$/, "");
1443
+ const url = `${baseUrl}/agents/verify-access/${encodeURIComponent(sessionId)}/decision`;
1444
+ const headers = {
1445
+ "Content-Type": "application/json"
1446
+ };
1447
+ if (config.apiKey) {
1448
+ headers["Authorization"] = `Bearer ${config.apiKey}`;
1449
+ }
1450
+ if (config.customHeaders) {
1451
+ Object.assign(headers, config.customHeaders);
1452
+ }
1453
+ const response = await fetch(url, {
1454
+ method: "POST",
1455
+ headers,
1456
+ body: JSON.stringify(body)
1457
+ });
1458
+ if (!response.ok) {
1459
+ const errorText = await response.text().catch(() => "Unknown error");
1460
+ throw new Error(
1461
+ `Failed to record decision for session ${sessionId}: ${response.status} ${errorText}`
1462
+ );
1463
+ }
1464
+ const result = await response.json();
1465
+ return {
1466
+ recorded: result.recorded ?? true,
1467
+ blockchainTxHash: result.blockchainTxHash
1468
+ };
1469
+ }
1470
+
1471
+ // src/index.ts
1472
+ var VERSION = "2.0.0";
1473
+ // Annotate the CommonJS export names for ESM import in node:
1474
+ 0 && (module.exports = {
1475
+ ACCESS_LEVEL_DESCRIPTIONS,
1476
+ ACCESS_LEVEL_HIERARCHY,
1477
+ AgentClient,
1478
+ ChallengeHandler,
1479
+ DEFAULT_TRUST_THRESHOLDS,
1480
+ TRUST_LEVEL_RANGES,
1481
+ VERSION,
1482
+ agent,
1483
+ clearCache,
1484
+ determineAccessLevel,
1485
+ express,
1486
+ extractCredentials,
1487
+ getAccessLevelForScore,
1488
+ getCapabilities,
1489
+ getTrustLevel,
1490
+ hasCredentials,
1491
+ hasMinimumAccess,
1492
+ nextjs,
1493
+ quickVerify,
1494
+ recordDecision,
1495
+ sdk,
1496
+ transport,
1497
+ verify
1498
+ });
1499
+ //# sourceMappingURL=index.js.map