@astrasyncai/verification-gateway 2.4.0 → 2.4.2

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 +137 -22
  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 +37 -7
  7. package/dist/adapters/express.js.map +1 -1
  8. package/dist/adapters/express.mjs +37 -7
  9. package/dist/adapters/express.mjs.map +1 -1
  10. package/dist/adapters/mcp.d.mts +1 -1
  11. package/dist/adapters/mcp.d.ts +1 -1
  12. package/dist/adapters/mcp.js +37 -7
  13. package/dist/adapters/mcp.js.map +1 -1
  14. package/dist/adapters/mcp.mjs +37 -7
  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 +30 -4
  19. package/dist/adapters/nextjs.js.map +1 -1
  20. package/dist/adapters/nextjs.mjs +30 -4
  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 +30 -4
  25. package/dist/adapters/sdk.js.map +1 -1
  26. package/dist/adapters/sdk.mjs +30 -4
  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 +163 -4
  31. package/dist/browser/background.js +30 -4
  32. package/dist/browser/background.js.map +1 -1
  33. package/dist/browser/background.mjs +30 -4
  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 +30 -4
  44. package/dist/cursor/extension.js.map +1 -1
  45. package/dist/cursor/extension.mjs +30 -4
  46. package/dist/cursor/extension.mjs.map +1 -1
  47. package/dist/{express-4Vau6x6X.d.mts → express-DneHiMhu.d.mts} +1 -1
  48. package/dist/{express-Nq-wWICa.d.ts → express-DsiaQRFt.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 +30 -4
  52. package/dist/gateway/gateway.js.map +1 -1
  53. package/dist/gateway/gateway.mjs +30 -4
  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-DkyPV14Y.d.mts → index-C9yWlQ2Y.d.mts} +1 -1
  58. package/dist/{index-DiToN8gh.d.mts → index-DAGm-Sgf.d.mts} +1 -1
  59. package/dist/{index-B-EovXnY.d.ts → index-Dd4alF0l.d.ts} +1 -1
  60. package/dist/{index-CxwCN7AC.d.ts → index-NZiKvrtE.d.ts} +1 -1
  61. package/dist/index.d.mts +7 -7
  62. package/dist/index.d.ts +7 -7
  63. package/dist/index.js +37 -7
  64. package/dist/index.js.map +1 -1
  65. package/dist/index.mjs +37 -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-DO_4crcp.d.ts → nextjs-B4WmoiVm.d.ts} +1 -1
  70. package/dist/{nextjs-BTR7Oix-.d.mts → nextjs-vUuVCaBP.d.mts} +1 -1
  71. package/dist/registration/index.d.mts +174 -7
  72. package/dist/registration/index.d.ts +174 -7
  73. package/dist/registration/index.js +171 -6
  74. package/dist/registration/index.js.map +1 -1
  75. package/dist/registration/index.mjs +167 -5
  76. package/dist/registration/index.mjs.map +1 -1
  77. package/dist/{sdk-TnHXD-Oh.d.ts → sdk-BvWp4q2q.d.ts} +1 -1
  78. package/dist/{sdk-DSLCyXIX.d.mts → sdk-Cixo6pTV.d.mts} +1 -1
  79. package/dist/transport/index.d.mts +2 -2
  80. package/dist/transport/index.d.ts +2 -2
  81. package/dist/{types-pU2O0BFq.d.mts → types-C_e1IZdU.d.mts} +1 -1
  82. package/dist/{types-BVp22KkN.d.mts → types-DLai3jly.d.mts} +16 -13
  83. package/dist/{types-BVp22KkN.d.ts → types-DLai3jly.d.ts} +16 -13
  84. package/dist/{types-DVCWReEN.d.ts → types-IUzu-A4u.d.ts} +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
@@ -105,35 +105,109 @@ if (result.verified && result.accessLevel !== 'none') {
105
105
 
106
106
  ### Agent Registration
107
107
 
108
- Register an AI agent with the KYA backend in code (the `astrasync` CLI does the same thing from a shell).
108
+ **Use the SDK for all agent registration**, whether you're a developer firing off a one-shot CLI call or an autonomous agent self-registering on first run. The SDK handles auth-mode routing for you: signature-authenticated callers get synchronous registration; API-key-only callers get an owner-approval handshake (server-side rule, not negotiable).
109
+
110
+ #### `apiEndpoint` — runtime-challenge URL
111
+
112
+ `apiEndpoint` is the URL where your agent's verification-gateway SDK is mounted to receive runtime challenges from counterparties. Optional but recommended — if you omit it, your agent declares no runtime-challenge support, which is included in the verification payload and may cause some counterparties to decline access requests.
113
+
114
+ #### Two registration response modes
115
+
116
+ The same `register()` call returns one of two shapes depending on auth context:
117
+
118
+ - **201 active** — synchronous: returned when the request is signed with a crypto keypair (`privateKey` configured) or when authenticated via email+password. Result: `{ status: 'active', agent }`.
119
+ - **202 pending_approval** — API-key only: the SDK was authenticated with an API key but the request was not signed. The backend emails the account owner a "Sign In to Accept" link, fires a dashboard alert, and returns a tracking token. Result: `{ status: 'pending_approval', requestId, pollUrl, expiresAt }`. The agent becomes active only after the owner approves.
120
+
121
+ This split enforces the platform rule that **API-key registrations always require owner step-up** — registering an agent autonomously with just an API key is not a sufficient authority signal on its own.
122
+
123
+ #### Pattern A — developer / long-running agent (block until approved)
124
+
125
+ Best for CLI tools, dev-machine first-run, and long-running services:
109
126
 
110
127
  ```typescript
111
- import { AstraSync } from '@astrasyncai/verification-gateway/registration';
128
+ import {
129
+ AstraSync,
130
+ RegistrationDeniedError,
131
+ RegistrationTimeoutError,
132
+ } from '@astrasyncai/verification-gateway/registration';
112
133
 
113
- const astrasync = new AstraSync({
114
- apiKey: process.env.ASTRASYNC_API_KEY, // or { email, password }
115
- // Optional: privateKey for secp256k1 request signing
116
- privateKey: process.env.ASTRASYNC_PRIVATE_KEY,
134
+ const sdk = new AstraSync({
135
+ apiKey: process.env.ASTRASYNC_API_KEY,
136
+ privateKey: process.env.ASTRASYNC_PRIVATE_KEY, // optional when set, 201 sync path
117
137
  });
118
138
 
119
- const result = await astrasync.register({
139
+ try {
140
+ const agent = await sdk.register({
141
+ name: 'invoice-bot',
142
+ description: 'Reconciles AP/AR across accounting systems.',
143
+ agentType: 'autonomous',
144
+ apiEndpoint: 'https://invoice-bot.example.com', // runtime-challenge URL
145
+ model: { modelProvider: 'anthropic', modelName: 'claude-sonnet-4-5' },
146
+ framework: { frameworkName: 'langchain', frameworkVersion: '0.3.0' },
147
+ protocols: ['a2a', 'mcp'],
148
+ pdlss: {
149
+ purpose: {
150
+ categories: ['accounting'],
151
+ allowedActions: ['accounting.read', 'accounting.write'],
152
+ },
153
+ limits: { stepUpThreshold: 1_000, approvalThreshold: 10_000, currency: 'USD' },
154
+ scope: { resources: ['xero.invoices', 'quickbooks.bills'] },
155
+ selfInstantiation: { allowed: false },
156
+ },
157
+ // Blocking mode: poll until the request resolves.
158
+ waitForApproval: true,
159
+ timeoutMs: 10 * 60 * 1000, // 10 minutes default
160
+ onPending: ({ ageMs }) =>
161
+ console.log(`Awaiting owner approval (${(ageMs / 1000).toFixed(0)}s)…`),
162
+ });
163
+ console.log(`Agent registered: ${agent.astrasyncIdLevel1}`);
164
+ } catch (err) {
165
+ if (err instanceof RegistrationDeniedError) {
166
+ console.error('Owner denied:', err.reason);
167
+ } else if (err instanceof RegistrationTimeoutError) {
168
+ console.error(
169
+ 'Timed out — request is still active server-side; poll later via sdk.waitForApproval(requestId)'
170
+ );
171
+ } else {
172
+ throw err;
173
+ }
174
+ }
175
+ ```
176
+
177
+ #### Pattern B — serverless / scheduled agent (non-blocking, exit and resume)
178
+
179
+ Best for Lambda / Cloud Functions / cron-driven self-registration where you can't hold the runtime open for minutes:
180
+
181
+ ```typescript
182
+ const sdk = new AstraSync({ apiKey: process.env.ASTRASYNC_API_KEY });
183
+
184
+ const result = await sdk.register({
120
185
  name: 'invoice-bot',
121
- description: 'Reconciles AP/AR across accounting systems.',
122
- agentType: 'autonomous',
123
- model: { modelProvider: 'anthropic', modelName: 'claude-sonnet-4-5' },
124
- framework: { frameworkName: 'langchain', frameworkVersion: '0.3.0' },
125
- protocols: ['a2a', 'mcp'],
126
- pdlss: {
127
- purpose: { allowed: ['accounting.read', 'accounting.write'] },
128
- duration: { requested: 'P30D' },
129
- limits: { transactionValue: 5000, currency: 'USD' },
130
- scope: { resources: ['xero.invoices', 'quickbooks.bills'] },
131
- selfInstantiation: { allowed: false },
132
- },
186
+ apiEndpoint: 'https://invoice-bot.example.com',
187
+ pdlss: { purpose: { categories: ['accounting'], allowedActions: ['accounting.read'] } },
133
188
  });
134
189
 
135
- console.log(`Agent registered: ${result.agent.astraId}`);
136
- console.log(`Trust score: ${result.agent.trustScore}`); // dynamic; recomputed on every verify-access call
190
+ if (result.status === 'pending_approval') {
191
+ // Store the requestId in your durable storage (DynamoDB, KV, etc.)
192
+ await store.set('astrasync.pendingRequestId', result.requestId);
193
+ console.log(`Awaiting owner approval at ${result.pollUrl}; will resume on next scheduled run.`);
194
+ return; // function exits — owner has time to approve
195
+ }
196
+
197
+ console.log(`Agent registered as ${result.agent.astrasyncIdLevel1}`);
198
+ ```
199
+
200
+ On the next scheduled run, resume by polling:
201
+
202
+ ```typescript
203
+ const requestId = await store.get('astrasync.pendingRequestId');
204
+ const status = await sdk.pollRegistration(requestId);
205
+ if (status.state === 'approved') {
206
+ await store.set('astrasync.agentId', status.agent.kyaAgentId);
207
+ await store.delete('astrasync.pendingRequestId');
208
+ } else if (status.state === 'denied' || status.state === 'expired') {
209
+ console.error(`Registration terminated: ${status.state}`);
210
+ }
137
211
  ```
138
212
 
139
213
  CLI equivalent — same surface from a shell, also via `npx`:
@@ -143,9 +217,12 @@ npx astrasync register --name invoice-bot --agent-type autonomous \
143
217
  --model-provider anthropic --model-name claude-sonnet-4-5 \
144
218
  --framework-name langchain --framework-version 0.3.0 \
145
219
  --protocols a2a,mcp \
146
- --pdlss '{"purpose":{"allowed":["accounting.read","accounting.write"]}, ...}'
220
+ --api-endpoint https://invoice-bot.example.com \
221
+ --pdlss '{"purpose":{"categories":["accounting"],"allowedActions":["accounting.read"]}}'
147
222
  ```
148
223
 
224
+ The CLI uses the same response logic — it will print a "Sign in to approve" message and a poll URL when the response is 202 pending, and exit non-zero on deny/expire.
225
+
149
226
  > `/registration` is for **one-shot onboarding** — register an agent, look up its public profile, check API health. For **per-request credential injection** (attaching ASTRA-id, sessionId, PDLSS to outgoing HTTP / A2A / MCP calls from an already-registered agent), use `/agent` (`AgentClient`). The two roles are deliberately separate concerns: registration is identity, `/agent` is runtime.
150
227
 
151
228
  > A `PDLSSConfig` type exists in both `/registration` and `/agent`, with **different shapes**. `/registration`'s `PDLSSConfig` is the boundary declaration submitted at register time; `/agent`'s `PDLSSConfig` is the per-request runtime request shape. Disambiguate via the import path — the root export deliberately does not re-export either.
@@ -380,6 +457,44 @@ When an unverified agent visits a protected page, the Commerce Shield overlay di
380
457
 
381
458
  This creates a smooth experience for agents while maintaining security.
382
459
 
460
+ ## Two `baseUrl` conventions — same package, different clients
461
+
462
+ This package ships two clients. They use slightly different URL conventions; this is intentional but worth pinning down:
463
+
464
+ | Client | Field | Expected value | Example |
465
+ | ---------------------------------------------------------------------------- | -------------------------- | ----------------------- | -------------------------- |
466
+ | Verification gateway (`createMiddleware`, `createMcpMiddleware`, `verify()`) | `GatewayConfig.apiBaseUrl` | Origin + `/api` | `https://astrasync.ai/api` |
467
+ | Registration SDK (`new AstraSync(...)`) | `AstraSyncConfig.baseUrl` | Bare origin (no `/api`) | `https://astrasync.ai` |
468
+
469
+ Why the split: the gateway derives multiple endpoints from `apiBaseUrl` (verify-access, fetchRoutes, recordDecision, etc.), all under `/api/*`. The registration SDK prepends `/api/agents/...` per call and would double the path if `baseUrl` already ended with `/api`.
470
+
471
+ As of **v2.4.2**, the registration SDK tolerates a trailing `/api` on `baseUrl` — it strips the suffix and emits a one-time console warning so you can fix the source. Pass `silent: true` in `AstraSyncConfig` to suppress the warning (e.g. in tests).
472
+
473
+ ## Header semantics — `X-Astra-Gateway-Mode`
474
+
475
+ The SDK sets `X-Astra-Gateway-Mode` on every response that's been through the gateway middleware. The value describes the GATE state — not whether the request succeeded end-to-end.
476
+
477
+ | Value | Meaning |
478
+ | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
479
+ | `enforced` | The gateway evaluated policy on this request. Set on denial responses (`defaultOnDenied`, `defaultMcpDenied`). |
480
+ | `unenforced` | The gateway skipped policy evaluation for this request. The `X-Astra-Gateway-Reason` header explains why (`mcp-tier-none`, `non-jsonrpc-body`, `no-policy`, `no-match`, `route-none`). The downstream handler may still return any status. |
481
+
482
+ Pre-v2.4.2 used the value `pass-through` — renamed in v2.4.2 to disambiguate "gate skipped" from "request allowed".
483
+
484
+ ## Changelog
485
+
486
+ ### v2.4.2 — Round-10 partner re-test alignment
487
+
488
+ - **baseUrl normalization** (`AstraSyncConfig`): trailing `/api` is stripped + warned. Removes a class of NOT_FOUND bugs when partners pass the verify-gateway-style URL to the registration client.
489
+ - **Denial responses surface `failures[]` + `correlationId`** (`defaultOnDenied`, `defaultMcpDenied`): partners can now render per-dimension UX and tie a denial back to a server log line. Previously only the first denialReason was surfaced.
490
+ - **API-error fallback** (`createGuidanceResponse`): synthesised stubs for transient 5xx / network failures now carry `verify_access.api_error` in `failures[]` instead of the misleading "register your agent" template.
491
+ - **`X-Astra-Gateway-Mode` rename**: `pass-through` → `unenforced`. The new `enforced` value lands on denial paths. See the header semantics table above.
492
+ - **`silent` config flag** (`AstraSyncConfig`): suppresses one-time SDK warnings (baseUrl strip, deprecation notices).
493
+
494
+ ### v2.4.1 — Round-9 docs/SDK alignment
495
+
496
+ See git log for details.
497
+
383
498
  ## License
384
499
 
385
500
  MIT
@@ -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-pU2O0BFq.mjs';
3
- import '../types-BVp22KkN.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';
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-DVCWReEN.js';
3
- import '../types-BVp22KkN.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';
4
4
 
5
5
  /**
6
6
  * PlatformAdapter Interface
@@ -1,3 +1,3 @@
1
1
  import 'express';
2
- import '../types-BVp22KkN.mjs';
3
- export { c as createMiddleware, a as extractAstraSyncCredentials } from '../express-4Vau6x6X.mjs';
2
+ import '../types-DLai3jly.mjs';
3
+ export { c as createMiddleware, a as extractAstraSyncCredentials } from '../express-DneHiMhu.mjs';
@@ -1,3 +1,3 @@
1
1
  import 'express';
2
- import '../types-BVp22KkN.js';
3
- export { c as createMiddleware, a as extractAstraSyncCredentials } from '../express-Nq-wWICa.js';
2
+ import '../types-DLai3jly.js';
3
+ export { c as createMiddleware, a as extractAstraSyncCredentials } from '../express-DsiaQRFt.js';
@@ -130,8 +130,18 @@ function extractCredentials(headers, query) {
130
130
  }
131
131
  return credentials;
132
132
  }
133
- function createGuidanceResponse(config, reason) {
134
- const guidance = {
133
+ function createGuidanceResponse(config, reason, options = {}) {
134
+ const source = options.source ?? "no_credentials";
135
+ const isApiError = source === "api_error";
136
+ const guidance = isApiError ? {
137
+ message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
138
+ registrationUrl: `${config.apiBaseUrl.replace("/api", "")}/register`,
139
+ documentationUrl: `${config.apiBaseUrl.replace("/api", "")}/docs/agent-access`,
140
+ steps: [
141
+ "Retry the request with exponential backoff",
142
+ "If failures persist, share the correlationId with support"
143
+ ]
144
+ } : {
135
145
  message: "This service verifies AI agents before granting access. Please register your agent with AstraSync.",
136
146
  registrationUrl: `${config.apiBaseUrl.replace("/api", "")}/register`,
137
147
  documentationUrl: `${config.apiBaseUrl.replace("/api", "")}/docs/agent-access`,
@@ -152,6 +162,18 @@ function createGuidanceResponse(config, reason) {
152
162
  accessLevel: "none",
153
163
  guidance,
154
164
  denialReasons: reason ? [reason] : ["No valid agent credentials provided"],
165
+ // Round-10 (#47, O5): on API-error fallback, surface a typed failure so
166
+ // partners (and their custom onDenied handlers) can branch on
167
+ // dimension. Without this, the synthesised stub was indistinguishable
168
+ // from a real policy deny.
169
+ failures: isApiError ? [
170
+ {
171
+ dimension: "verify_access.api_error",
172
+ message: reason ?? "Verification temporarily unavailable",
173
+ guidance: guidance.message
174
+ }
175
+ ] : void 0,
176
+ correlationId: options.correlationId,
155
177
  verifiedAt: /* @__PURE__ */ new Date()
156
178
  };
157
179
  }
@@ -226,7 +248,8 @@ async function callVerifyAccessAPI(config, request) {
226
248
  if (!response.ok) {
227
249
  return {
228
250
  success: false,
229
- error: data.message || data.error || `API returned ${response.status}`
251
+ error: data.message || data.error || `API returned ${response.status}`,
252
+ correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0
230
253
  };
231
254
  }
232
255
  return data;
@@ -270,7 +293,10 @@ async function verify(config, request) {
270
293
  }
271
294
  const apiResponse = await callVerifyAccessAPI(mergedConfig, enrichedRequest);
272
295
  if (!apiResponse.success) {
273
- return createGuidanceResponse(mergedConfig, apiResponse.error);
296
+ return createGuidanceResponse(mergedConfig, apiResponse.error, {
297
+ source: "api_error",
298
+ correlationId: apiResponse.correlationId
299
+ });
274
300
  }
275
301
  if (!apiResponse.access?.allowed) {
276
302
  const aggregatedFailures = apiResponse.access?.failures;
@@ -563,13 +589,17 @@ function findRouteConfig(routes, path, method) {
563
589
  }
564
590
  function defaultOnDenied(result, _req, res) {
565
591
  const statusCode = result.verified ? 403 : 401;
592
+ res.setHeader("X-Astra-Gateway-Mode", "enforced");
566
593
  res.status(statusCode).json({
567
594
  success: false,
568
595
  error: {
569
596
  code: result.verified ? "INSUFFICIENT_ACCESS" : "UNAUTHORIZED",
570
597
  message: result.denialReasons?.[0] || "Access denied",
571
598
  accessLevel: result.accessLevel,
572
- guidance: result.guidance
599
+ guidance: result.guidance,
600
+ // Round-10: aggregated per-dimension detail + correlation handle.
601
+ failures: result.failures,
602
+ correlationId: result.correlationId
573
603
  }
574
604
  });
575
605
  }
@@ -634,7 +664,7 @@ function createMiddleware(options) {
634
664
  const routeConfig = findRouteConfig(cachedRoutes, req.path, req.method);
635
665
  if (!routeConfig) {
636
666
  if (config.setPassThroughHeader) {
637
- res.setHeader("X-Astra-Gateway-Mode", "pass-through");
667
+ res.setHeader("X-Astra-Gateway-Mode", "unenforced");
638
668
  res.setHeader(
639
669
  "X-Astra-Gateway-Reason",
640
670
  cachedRoutes.length === 0 ? "no-policy" : "no-match"
@@ -644,7 +674,7 @@ function createMiddleware(options) {
644
674
  }
645
675
  if (routeConfig.minAccessLevel === "none") {
646
676
  if (config.setPassThroughHeader) {
647
- res.setHeader("X-Astra-Gateway-Mode", "pass-through");
677
+ res.setHeader("X-Astra-Gateway-Mode", "unenforced");
648
678
  res.setHeader("X-Astra-Gateway-Reason", "route-none");
649
679
  }
650
680
  return next();