@astrasyncai/verification-gateway 2.4.3 → 2.4.5

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 (87) hide show
  1. package/README.md +90 -0
  2. package/dist/adapter-interface/interface.d.mts +2 -2
  3. package/dist/adapter-interface/interface.d.ts +2 -2
  4. package/dist/adapters/express.d.mts +2 -2
  5. package/dist/adapters/express.d.ts +2 -2
  6. package/dist/adapters/express.js +35 -7
  7. package/dist/adapters/express.js.map +1 -1
  8. package/dist/adapters/express.mjs +35 -7
  9. package/dist/adapters/express.mjs.map +1 -1
  10. package/dist/adapters/mcp.d.mts +61 -2
  11. package/dist/adapters/mcp.d.ts +61 -2
  12. package/dist/adapters/mcp.js +95 -18
  13. package/dist/adapters/mcp.js.map +1 -1
  14. package/dist/adapters/mcp.mjs +95 -18
  15. package/dist/adapters/mcp.mjs.map +1 -1
  16. package/dist/adapters/nextjs.d.mts +2 -2
  17. package/dist/adapters/nextjs.d.ts +2 -2
  18. package/dist/adapters/nextjs.js +5 -0
  19. package/dist/adapters/nextjs.js.map +1 -1
  20. package/dist/adapters/nextjs.mjs +5 -0
  21. package/dist/adapters/nextjs.mjs.map +1 -1
  22. package/dist/adapters/sdk.d.mts +2 -2
  23. package/dist/adapters/sdk.d.ts +2 -2
  24. package/dist/adapters/sdk.js +5 -0
  25. package/dist/adapters/sdk.js.map +1 -1
  26. package/dist/adapters/sdk.mjs +5 -0
  27. package/dist/adapters/sdk.mjs.map +1 -1
  28. package/dist/agent/index.d.mts +2 -2
  29. package/dist/agent/index.d.ts +2 -2
  30. package/dist/bin/astrasync.js +10 -2
  31. package/dist/browser/background.js +5 -0
  32. package/dist/browser/background.js.map +1 -1
  33. package/dist/browser/background.mjs +5 -0
  34. package/dist/browser/background.mjs.map +1 -1
  35. package/dist/browser/browser-adapter.d.mts +2 -2
  36. package/dist/browser/browser-adapter.d.ts +2 -2
  37. package/dist/cli/index.d.mts +2 -2
  38. package/dist/cli/index.d.ts +2 -2
  39. package/dist/cursor/cursor-adapter.d.mts +2 -2
  40. package/dist/cursor/cursor-adapter.d.ts +2 -2
  41. package/dist/cursor/extension.d.mts +2 -2
  42. package/dist/cursor/extension.d.ts +2 -2
  43. package/dist/cursor/extension.js +5 -0
  44. package/dist/cursor/extension.js.map +1 -1
  45. package/dist/cursor/extension.mjs +5 -0
  46. package/dist/cursor/extension.mjs.map +1 -1
  47. package/dist/{express-DneHiMhu.d.mts → express-D5hAJ2Gv.d.mts} +1 -1
  48. package/dist/{express-DsiaQRFt.d.ts → express-XCkk7BsJ.d.ts} +1 -1
  49. package/dist/gateway/gateway.d.mts +2 -2
  50. package/dist/gateway/gateway.d.ts +2 -2
  51. package/dist/gateway/gateway.js +5 -0
  52. package/dist/gateway/gateway.js.map +1 -1
  53. package/dist/gateway/gateway.mjs +5 -0
  54. package/dist/gateway/gateway.mjs.map +1 -1
  55. package/dist/git-trigger/git-hooks.d.mts +2 -2
  56. package/dist/git-trigger/git-hooks.d.ts +2 -2
  57. package/dist/{index-NZiKvrtE.d.ts → index-Bstl43HI.d.ts} +1 -1
  58. package/dist/{index-Dd4alF0l.d.ts → index-CH4TfcbL.d.ts} +1 -1
  59. package/dist/{index-C9yWlQ2Y.d.mts → index-TS4SGvf4.d.mts} +1 -1
  60. package/dist/{index-DAGm-Sgf.d.mts → index-u08qcXq9.d.mts} +1 -1
  61. package/dist/index.d.mts +7 -7
  62. package/dist/index.d.ts +7 -7
  63. package/dist/index.js +35 -7
  64. package/dist/index.js.map +1 -1
  65. package/dist/index.mjs +35 -7
  66. package/dist/index.mjs.map +1 -1
  67. package/dist/local-evaluator/evaluator.d.mts +2 -2
  68. package/dist/local-evaluator/evaluator.d.ts +2 -2
  69. package/dist/{nextjs-vUuVCaBP.d.mts → nextjs-CFA0J_4x.d.mts} +1 -1
  70. package/dist/{nextjs-B4WmoiVm.d.ts → nextjs-DP2EpI-4.d.ts} +1 -1
  71. package/dist/registration/index.d.mts +25 -0
  72. package/dist/registration/index.d.ts +25 -0
  73. package/dist/registration/index.js +10 -2
  74. package/dist/registration/index.js.map +1 -1
  75. package/dist/registration/index.mjs +10 -2
  76. package/dist/registration/index.mjs.map +1 -1
  77. package/dist/{sdk-Cixo6pTV.d.mts → sdk-C8W54WZS.d.mts} +1 -1
  78. package/dist/{sdk-BvWp4q2q.d.ts → sdk-CwwCGDzK.d.ts} +1 -1
  79. package/dist/transport/index.d.mts +2 -2
  80. package/dist/transport/index.d.ts +2 -2
  81. package/dist/{types-DLai3jly.d.mts → types-CbZOkIr-.d.mts} +29 -0
  82. package/dist/{types-DLai3jly.d.ts → types-CbZOkIr-.d.ts} +29 -0
  83. package/dist/{types-IUzu-A4u.d.ts → types-DXNkr61h.d.ts} +1 -1
  84. package/dist/{types-C_e1IZdU.d.mts → types-tBNFSbw_.d.mts} +1 -1
  85. package/dist/ui/index.d.mts +1 -1
  86. package/dist/ui/index.d.ts +1 -1
  87. package/package.json +1 -1
package/README.md CHANGED
@@ -494,6 +494,96 @@ Pre-v2.4.2 used the value `pass-through` — renamed in v2.4.2 to disambiguate "
494
494
 
495
495
  ## Changelog
496
496
 
497
+ ### v2.4.5 — Round-13 partner integration testing
498
+
499
+ **⚠️ BREAKING CHANGE — `pdlss_immutable` → `agent_immutable`**
500
+
501
+ The 409 response from `PUT /api/agents/:id` (post-mint mutation attempt)
502
+ now returns `error: 'agent_immutable'` instead of `error: 'pdlss_immutable'`.
503
+ The scope also widened: round-12 rejected only the subset
504
+ `{ pdlss, model, framework, agentType, apiEndpoint }`; round-13 rejects
505
+ ANY field except `agentStatus` (the only allowed lifecycle transition
506
+ post-mint).
507
+
508
+ **Migration**: if your code catches `pdlss_immutable`, update to
509
+ `agent_immutable`. No legacy alias is shipped — clean break prevents
510
+ permanent shim cruft. The new shape:
511
+
512
+ ```json
513
+ {
514
+ "success": false,
515
+ "error": "agent_immutable",
516
+ "message": "Agents are immutable post-approval. ... Attempted immutable fields: <list>. ...",
517
+ "immutableFields": ["name", "description", ...]
518
+ }
519
+ ```
520
+
521
+ **Why**: agents become immutable at approval + mint per the trust-chain
522
+ invariant. Pre-mint owner edits flow through
523
+ `POST /agents/request-registration/:requestId/approve` (dashboard-only,
524
+ accepts a full edit body). Post-mint, the only allowed transition is
525
+ `agentStatus` (e.g. dashboard retire button). For configuration changes,
526
+ use the upgrade flow (coming soon) or retire-and-re-register.
527
+
528
+ **Other round-13 items**:
529
+
530
+ - **R13-1 + R13-2 — MCP middleware: symmetric precedence chain for
531
+ `purpose` and `action`**. Canonical resolution (documented ONCE,
532
+ applies to both):
533
+ 1. `X-Astra-<concept>` HTTP header
534
+ 2. `params._meta.astrasync.<concept>` body field
535
+ 3. `params.arguments.<concept>` body field
536
+ 4. Transport-layer default:
537
+ - `purpose` → `'mcp_invoke'`
538
+ - `action` → `'<method>:<toolName>'` (or `'<method>'` alone)
539
+
540
+ Round-12 F19 shipped purpose with `header → _meta → default`; this
541
+ round closes the `params.arguments.purpose` fallback gap AND ships
542
+ action with the same full chain in one round (not staggered) to
543
+ pre-empt the parallel "I set action in arguments and it didn't take"
544
+ support tickets. Resource string stays `mcp:tool/<name>` regardless.
545
+
546
+ `mcpToPdlss(parsed, headerPurpose, headerAction)` signature.
547
+ `McpPdlssMapping.purposeSource` now `'header' | 'meta' | 'tool_argument' | 'default_mcp_invoke'`
548
+ (round-12 narrower `'header' | 'tool_argument' | 'default_mcp_invoke'`
549
+ widened to split `meta` from `tool_argument`). New companion
550
+ `actionSource: 'header' | 'meta' | 'tool_argument' | 'transport_layer'`.
551
+
552
+ - **R13-5 — MCP `evaluateAlwaysIfCredentialed` parity with F9**. Flag
553
+ moved from `ExpressMiddlewareOptions` to `GatewayConfig` so both
554
+ adapters inherit. MCP middleware now mirrors the express F9 pattern:
555
+ route-none + flag-on + credentialed → run verify-access for the audit
556
+ trail, populate `req.agentVerification`, then proceed without gates
557
+ (`X-Astra-Gateway-Mode: enforced`, `Reason: evaluated-not-enforced`).
558
+ Closes the round-12 deferral.
559
+
560
+ - **F14 closure — `sdkVersion` body field on verify-access**. Replaces
561
+ round-12's User-Agent regex extraction which silently failed because
562
+ Node's undici fetch doesn't ship a usable User-Agent header. The SDK
563
+ now sets `body.sdkVersion = SDK_VERSION` (sourced from
564
+ `packages/verification-gateway/src/version.ts`, bumped alongside
565
+ `package.json` on every release). Backend reads from the body field
566
+ and runs the same forward-only auto-pop into
567
+ `kya_counterparty.sdk_version`. Works in Node, browser, and behind
568
+ CDNs uniformly.
569
+
570
+ - **R13-4 — Branded TypeScript types** (compile-time protection against
571
+ the recurring UUID / public-id string-confusion bug class —
572
+ round-7 #46, round-11 F1, round-12 F15). New `CounterpartyUuid`,
573
+ `AgentUuid`, `OwnerUuid`, `CounterpartyAstraeId`, `AgentAstraId`,
574
+ `OwnerAstradId` branded types in the backend at
575
+ `apps/backend/src/types/branded-ids.ts`. Zero runtime cost; affects
576
+ only compile-time assignment compatibility. Scope intentionally
577
+ narrow — only the conversion-point function signatures.
578
+
579
+ ### v2.4.4 — Round-12 partner integration testing
580
+
581
+ - **F9** — `ExpressMiddlewareOptions.evaluateAlwaysIfCredentialed`: when true + credentials present + route-none, the middleware calls verify-access for the audit trail + `req.agentVerification` population, then proceeds without enforcement. Default false preserves existing behaviour. Use for tiered-response rendering on routes that grant public access but want caller identity visible to the handler.
582
+ - **F12** — `defaultOnDenied` / `defaultMcpDenied` synthesise `access_level.insufficient` failure entry on accessLevel-below-route + trust-score-below-route denials. Guidance text references the step-up verification flow ("coming soon — ships this month") only. Prior denials carried `INSUFFICIENT_ACCESS` with empty `failures[]` / `denialReasons[]` arrays.
583
+ - **F16** — `register()` now passes the API response's `warnings[]` through verbatim on both 201 (sync) and 202 (pending-approval) paths. Pre-fix the SDK silently dropped backend advisories like `no_callback_endpoint`. `RegisterResult` + `PendingRegistrationResponse` + `RegistrationResponse` types extended.
584
+ - **F19** — MCP middleware purpose pass-through. The hardcoded `purpose: 'mcp_invoke'` is now a fallback; resolution precedence is `X-Astra-Purpose` header → `params._meta.astrasync.purpose` → `'mcp_invoke'` default. Adds `invocationProtocol: 'mcp'` to the verify-access body so transport is marked separately from intent. Debug-level `purpose_source` log line per call for adoption tracking + support triage.
585
+ - **`mcpToPdlss`** signature extended to accept optional `headerPurpose` + `toolArgumentPurpose` args; return type gains `purposeSource: 'header' | 'tool_argument' | 'default_mcp_invoke'`.
586
+
497
587
  ### v2.4.3 — Round-11 partner integration testing
498
588
 
499
589
  - **`PollRegistrationResult.astraId`** — the polling response now surfaces the canonical `ASTRA-*` id once the registration request is approved. Pre-fix partners only got the owner-private UUID from the register flow and had no programmatic path to the canonical id (had to go to the dashboard). Backend changes that drive this: the `GET /api/agents/request-registration/{requestId}` handler looks up `kyaAgent.astrasyncIdLevel1` on approval and includes it in the response body.
@@ -1,6 +1,6 @@
1
1
  import { AstraSyncGateway } from '../gateway/gateway.mjs';
2
- import { A as AgentAction, I as InterceptResult, P as PDLSSContext, V as VerificationDecision } from '../types-C_e1IZdU.mjs';
3
- import '../types-DLai3jly.mjs';
2
+ import { A as AgentAction, I as InterceptResult, P as PDLSSContext, V as VerificationDecision } from '../types-tBNFSbw_.mjs';
3
+ import '../types-CbZOkIr-.mjs';
4
4
 
5
5
  /**
6
6
  * PlatformAdapter Interface
@@ -1,6 +1,6 @@
1
1
  import { AstraSyncGateway } from '../gateway/gateway.js';
2
- import { A as AgentAction, I as InterceptResult, P as PDLSSContext, V as VerificationDecision } from '../types-IUzu-A4u.js';
3
- import '../types-DLai3jly.js';
2
+ import { A as AgentAction, I as InterceptResult, P as PDLSSContext, V as VerificationDecision } from '../types-DXNkr61h.js';
3
+ import '../types-CbZOkIr-.js';
4
4
 
5
5
  /**
6
6
  * PlatformAdapter Interface
@@ -1,3 +1,3 @@
1
1
  import 'express';
2
- import '../types-DLai3jly.mjs';
3
- export { c as createMiddleware, a as extractAstraSyncCredentials } from '../express-DneHiMhu.mjs';
2
+ import '../types-CbZOkIr-.mjs';
3
+ export { c as createMiddleware, a as extractAstraSyncCredentials } from '../express-D5hAJ2Gv.mjs';
@@ -1,3 +1,3 @@
1
1
  import 'express';
2
- import '../types-DLai3jly.js';
3
- export { c as createMiddleware, a as extractAstraSyncCredentials } from '../express-DsiaQRFt.js';
2
+ import '../types-CbZOkIr-.js';
3
+ export { c as createMiddleware, a as extractAstraSyncCredentials } from '../express-XCkk7BsJ.js';
@@ -44,6 +44,9 @@ function hasMinimumAccess(actual, required) {
44
44
  return ACCESS_LEVEL_HIERARCHY[actual] >= ACCESS_LEVEL_HIERARCHY[required];
45
45
  }
46
46
 
47
+ // src/version.ts
48
+ var SDK_VERSION = "2.4.5";
49
+
47
50
  // src/verify.ts
48
51
  var DEFAULT_CONFIG = {
49
52
  apiBaseUrl: "https://astrasync.ai/api",
@@ -201,6 +204,8 @@ async function callVerifyAccessAPI(config, request) {
201
204
  if (config.counterpartyId) body.counterpartyId = config.counterpartyId;
202
205
  if (requestData.runtimeChallengeOptions)
203
206
  body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;
207
+ if (requestData.invocationProtocol) body.invocationProtocol = requestData.invocationProtocol;
208
+ body.sdkVersion = SDK_VERSION;
204
209
  if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {
205
210
  const meta = {
206
211
  ...requestData.clientIp && { sourceIp: requestData.clientIp },
@@ -672,14 +677,15 @@ function createMiddleware(options) {
672
677
  }
673
678
  return next();
674
679
  }
675
- if (routeConfig.minAccessLevel === "none") {
680
+ const credentials = customExtractCredentials ? customExtractCredentials(req) : defaultExtractCredentials(req);
681
+ const shouldEnforce = routeConfig.minAccessLevel !== "none";
682
+ if (routeConfig.minAccessLevel === "none" && (!config.evaluateAlwaysIfCredentialed || !credentials.astraId)) {
676
683
  if (config.setPassThroughHeader) {
677
684
  res.setHeader("X-Astra-Gateway-Mode", "unenforced");
678
685
  res.setHeader("X-Astra-Gateway-Reason", "route-none");
679
686
  }
680
687
  return next();
681
688
  }
682
- const credentials = customExtractCredentials ? customExtractCredentials(req) : defaultExtractCredentials(req);
683
689
  const purpose = customExtractPurpose ? customExtractPurpose(req) : defaultExtractPurpose(req);
684
690
  const astraCreds = extractAstraSyncCredentials(req);
685
691
  const counterpartyUrl = config.counterpartyUrl || `${req.protocol}://${req.get("host")}`;
@@ -743,9 +749,27 @@ function createMiddleware(options) {
743
749
  onDenied(result, req, res);
744
750
  return;
745
751
  }
752
+ if (!shouldEnforce) {
753
+ if (config.setPassThroughHeader) {
754
+ res.setHeader("X-Astra-Gateway-Mode", "enforced");
755
+ res.setHeader("X-Astra-Gateway-Reason", "evaluated-not-enforced");
756
+ }
757
+ if (shouldRecordDecisions && sessionId) {
758
+ recordDecision(config, sessionId, "granted").catch(() => {
759
+ });
760
+ }
761
+ return next();
762
+ }
746
763
  if (!hasMinimumAccess(result.accessLevel, routeConfig.minAccessLevel)) {
764
+ const insufficientFailure = {
765
+ dimension: "access_level.insufficient",
766
+ message: `Endpoint requires accessLevel '${routeConfig.minAccessLevel}'; agent has '${result.accessLevel}'.`,
767
+ guidance: "Request elevated access via step-up verification (coming soon \u2014 ships this month). Step-up lets the agent owner approve a one-time elevation for this specific counterparty + purpose without changing the agent's baseline trust score."
768
+ };
769
+ result.failures = [...result.failures ?? [], insufficientFailure];
770
+ result.denialReasons = [...result.denialReasons ?? [], insufficientFailure.message];
747
771
  if (shouldRecordDecisions && sessionId) {
748
- recordDecision(config, sessionId, "denied", result.denialReasons?.[0]).catch(() => {
772
+ recordDecision(config, sessionId, "denied", insufficientFailure.message).catch(() => {
749
773
  });
750
774
  }
751
775
  onDenied(result, req, res);
@@ -753,11 +777,15 @@ function createMiddleware(options) {
753
777
  }
754
778
  if (routeConfig.minTrustScore && result.agent) {
755
779
  if (result.agent.trustScore < routeConfig.minTrustScore) {
756
- result.denialReasons = [
757
- `Trust score ${result.agent.trustScore} is below required ${routeConfig.minTrustScore}`
758
- ];
780
+ const trustFailure = {
781
+ dimension: "access_level.insufficient",
782
+ message: `Trust score ${result.agent.trustScore} is below required ${routeConfig.minTrustScore} for this route.`,
783
+ guidance: "Request elevated access via step-up verification (coming soon \u2014 ships this month). Step-up lets the agent owner approve a one-time elevation for this specific counterparty + purpose without changing the agent's baseline trust score."
784
+ };
785
+ result.failures = [...result.failures ?? [], trustFailure];
786
+ result.denialReasons = [trustFailure.message];
759
787
  if (shouldRecordDecisions && sessionId) {
760
- recordDecision(config, sessionId, "denied", result.denialReasons[0]).catch(() => {
788
+ recordDecision(config, sessionId, "denied", trustFailure.message).catch(() => {
761
789
  });
762
790
  }
763
791
  onDenied(result, req, res);