@astrasyncai/verification-gateway 2.3.4 → 2.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter-interface/interface.d.mts +2 -2
- package/dist/adapter-interface/interface.d.ts +2 -2
- package/dist/adapters/express.d.mts +2 -2
- package/dist/adapters/express.d.ts +2 -2
- package/dist/adapters/express.js +59 -21
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +58 -18
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.d.mts +245 -0
- package/dist/adapters/mcp.d.ts +245 -0
- package/dist/adapters/mcp.js +589 -0
- package/dist/adapters/mcp.js.map +1 -0
- package/dist/adapters/mcp.mjs +555 -0
- package/dist/adapters/mcp.mjs.map +1 -0
- package/dist/adapters/nextjs.d.mts +2 -2
- package/dist/adapters/nextjs.d.ts +2 -2
- package/dist/adapters/nextjs.js +57 -3
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +57 -3
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.d.mts +2 -2
- package/dist/adapters/sdk.d.ts +2 -2
- package/dist/adapters/sdk.js +3 -1
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +3 -1
- package/dist/adapters/sdk.mjs.map +1 -1
- package/dist/agent/index.d.mts +2 -2
- package/dist/agent/index.d.ts +2 -2
- package/dist/browser/background.js +9 -1
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +9 -1
- package/dist/browser/background.mjs.map +1 -1
- package/dist/browser/browser-adapter.d.mts +2 -2
- package/dist/browser/browser-adapter.d.ts +2 -2
- package/dist/cli/index.d.mts +2 -2
- package/dist/cli/index.d.ts +2 -2
- package/dist/cursor/cursor-adapter.d.mts +2 -2
- package/dist/cursor/cursor-adapter.d.ts +2 -2
- package/dist/cursor/extension.d.mts +2 -2
- package/dist/cursor/extension.d.ts +2 -2
- package/dist/cursor/extension.js +9 -1
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +9 -1
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/{express-DtvJ6BGt.d.mts → express-D9oRsseg.d.mts} +17 -14
- package/dist/{express-CraCA8_t.d.ts → express-DMSIl20m.d.ts} +17 -14
- package/dist/gateway/gateway.d.mts +2 -2
- package/dist/gateway/gateway.d.ts +2 -2
- package/dist/gateway/gateway.js +9 -1
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +9 -1
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/git-trigger/git-hooks.d.mts +2 -2
- package/dist/git-trigger/git-hooks.d.ts +2 -2
- package/dist/{index-BZ85CeEr.d.mts → index-Bn_7eGjb.d.mts} +1 -1
- package/dist/{index--KzVRa32.d.ts → index-BtU9yFda.d.ts} +1 -1
- package/dist/{index-BzAFmemy.d.ts → index-EwUWXC5T.d.ts} +1 -1
- package/dist/{index-SEgnWzkf.d.mts → index-YNPs800Z.d.mts} +1 -1
- package/dist/index.d.mts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +93 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +93 -20
- package/dist/index.mjs.map +1 -1
- package/dist/local-evaluator/evaluator.d.mts +2 -2
- package/dist/local-evaluator/evaluator.d.ts +2 -2
- package/dist/{nextjs-B8o9C0t6.d.ts → nextjs-B5ZBpHra.d.ts} +8 -2
- package/dist/{nextjs-DZHAn9j-.d.mts → nextjs-BLtjRbc-.d.mts} +8 -2
- package/dist/{sdk-CRSUFQH2.d.mts → sdk-BhkxvqnK.d.mts} +1 -1
- package/dist/{sdk-BQ3olp3v.d.ts → sdk-YmE3RG8n.d.ts} +1 -1
- package/dist/transport/index.d.mts +2 -2
- package/dist/transport/index.d.ts +2 -2
- package/dist/{types-osMd_dpT.d.ts → types-BecRpozv.d.ts} +1 -1
- package/dist/{types-JMgPake9.d.mts → types-Bxqj1sKY.d.mts} +48 -6
- package/dist/{types-JMgPake9.d.ts → types-Bxqj1sKY.d.ts} +48 -6
- package/dist/{types-aN1UHhyy.d.mts → types-DxY5zt4z.d.mts} +1 -1
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/package.json +6 -1
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { Request, Response, RequestHandler } from 'express';
|
|
2
|
+
import { a as AccessLevel, G as GatewayConfig, V as VerificationResult } from '../types-Bxqj1sKY.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* MCP server-side helpers — companion to `transport/mcp.ts` (which handles the
|
|
6
|
+
* agent-side `_meta.astrasync` block).
|
|
7
|
+
*
|
|
8
|
+
* Surfaces a body-aware policy hook the existing `createMiddleware` couldn't
|
|
9
|
+
* provide — MCP traffic is JSON-RPC over a single endpoint (`/mcp`), so the
|
|
10
|
+
* default route-pattern gating is too coarse: every request looks the same
|
|
11
|
+
* URL-wise, but `initialize` is low-risk handshake while `tools/call` of a
|
|
12
|
+
* payment tool is high-risk. Cohort-3 beta merchants flagged this 🟡 in the
|
|
13
|
+
* v2.9.5 round.
|
|
14
|
+
*
|
|
15
|
+
* What lives here:
|
|
16
|
+
* - `parseMcpJsonRpc(body)` — peels JSON-RPC method + tool name + agent
|
|
17
|
+
* id without committing to a particular MCP
|
|
18
|
+
* server framework.
|
|
19
|
+
* - `mcpToPdlss(parsed)` — canonical mapping JSON-RPC method → PDLSS
|
|
20
|
+
* purpose / action / resource. Doc-stable
|
|
21
|
+
* so audits can correlate.
|
|
22
|
+
* - `mcpRiskTier(parsed)` — recommended `minAccessLevel` per method
|
|
23
|
+
* so a single MCP middleware can split
|
|
24
|
+
* `initialize` / `tools/list` (low gate)
|
|
25
|
+
* from `tools/call` (high gate).
|
|
26
|
+
* - `MCP_VERIFIED_HOP_HEADER` — header convention for the dedupe pattern
|
|
27
|
+
* when an MCP tool calls an inner REST hop.
|
|
28
|
+
* - `serialize/parseVerifiedHop` helpers.
|
|
29
|
+
*
|
|
30
|
+
* The Express MCP adapter is in `adapters/mcp.ts` and consumes these.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Header carrying upstream verify-access proof so an inner-hop REST endpoint
|
|
35
|
+
* can dedupe (skip verify-access when the same ASTRA-id was already verified
|
|
36
|
+
* a few ms earlier). Value format:
|
|
37
|
+
*
|
|
38
|
+
* {astraId};{sessionId};{checkedAt-ms}
|
|
39
|
+
*
|
|
40
|
+
* Receivers MUST validate that `checkedAt` is recent (≤ 60s window
|
|
41
|
+
* recommended) and that `astraId` matches the agent identity claimed on the
|
|
42
|
+
* inner hop. The header alone is NOT proof-of-identity — it's a dedupe
|
|
43
|
+
* advisory. Pair with the existing X-Astra-Id auth.
|
|
44
|
+
*/
|
|
45
|
+
declare const MCP_VERIFIED_HOP_HEADER = "X-Astra-Verified-Hop";
|
|
46
|
+
interface VerifiedHopMarker {
|
|
47
|
+
astraId: string;
|
|
48
|
+
sessionId?: string;
|
|
49
|
+
checkedAt: number;
|
|
50
|
+
}
|
|
51
|
+
declare function serializeVerifiedHop(marker: VerifiedHopMarker): string;
|
|
52
|
+
declare function parseVerifiedHop(value: string | undefined | null): VerifiedHopMarker | null;
|
|
53
|
+
/**
|
|
54
|
+
* Returns true when `marker.astraId` matches the inner-hop's claimed
|
|
55
|
+
* ASTRA-id AND the marker is recent enough. Inner-hop middleware uses this
|
|
56
|
+
* to skip a duplicate verify-access call.
|
|
57
|
+
*/
|
|
58
|
+
declare function isVerifiedHopValidFor(marker: VerifiedHopMarker | null, expectedAstraId: string, opts?: {
|
|
59
|
+
maxAgeMs?: number;
|
|
60
|
+
now?: number;
|
|
61
|
+
}): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Output of `parseMcpJsonRpc`. Self-describing so the middleware doesn't have
|
|
64
|
+
* to re-introspect the body to figure out gating.
|
|
65
|
+
*/
|
|
66
|
+
interface ParsedMcpRequest {
|
|
67
|
+
/** JSON-RPC method (e.g. `tools/call`, `initialize`, `tools/list`). */
|
|
68
|
+
method: string;
|
|
69
|
+
/** Set when method === 'tools/call'; the tool name from `params.name`. */
|
|
70
|
+
toolName?: string;
|
|
71
|
+
/** Initialize-specific protocolVersion handshake info, when present. */
|
|
72
|
+
protocolVersion?: string;
|
|
73
|
+
/**
|
|
74
|
+
* Agent id read from the body, in priority order:
|
|
75
|
+
* 1. `params._meta.astrasync.agentId` (the canonical SDK location, see
|
|
76
|
+
* `transport/mcp.ts → setMcpMeta`)
|
|
77
|
+
* 2. `params.arguments.agent_id` (legacy / hand-written tool callers)
|
|
78
|
+
* Header-supplied id (X-Astra-Id) is read separately by the adapter and
|
|
79
|
+
* compared to this for the mismatch check.
|
|
80
|
+
*/
|
|
81
|
+
agentIdFromBody?: string;
|
|
82
|
+
/** True for handshake methods that must succeed before any tool call. */
|
|
83
|
+
isInitialize: boolean;
|
|
84
|
+
/** True for `tools/call`. */
|
|
85
|
+
isToolCall: boolean;
|
|
86
|
+
/** True for low-risk introspection (`tools/list`, `prompts/list`, etc.). */
|
|
87
|
+
isIntrospection: boolean;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Peel the JSON-RPC envelope. Returns `null` if the body isn't a JSON-RPC
|
|
91
|
+
* request (callers can short-circuit with a 400 or treat as untyped traffic).
|
|
92
|
+
*
|
|
93
|
+
* Accepts both single-request and notification shapes. Batch requests are
|
|
94
|
+
* NOT supported here — the verify-access contract is single-agent-per-call;
|
|
95
|
+
* a batch body should be split before policy gating.
|
|
96
|
+
*/
|
|
97
|
+
declare function parseMcpJsonRpc(body: unknown): ParsedMcpRequest | null;
|
|
98
|
+
/**
|
|
99
|
+
* PDLSS mapping for an MCP request. The platform's PDLSS taxonomy is
|
|
100
|
+
* `purpose / action / resource`; for MCP traffic the audit-useful dimensions
|
|
101
|
+
* are the JSON-RPC method and (for `tools/call`) the tool name. Doc-stable so
|
|
102
|
+
* dashboards and audits can correlate consistently across cohort-3 partners.
|
|
103
|
+
*
|
|
104
|
+
* Rules:
|
|
105
|
+
* - `purpose` is always `mcp_invoke` for MCP traffic — sets the high-level
|
|
106
|
+
* PDLSS bucket.
|
|
107
|
+
* - `action` is the JSON-RPC method, optionally `:tool_name` suffixed for
|
|
108
|
+
* `tools/call`. Lets PDLSS allowlist specific tools.
|
|
109
|
+
* - `resource` is `mcp:tool/<name>` for `tools/call`, `mcp:method/<method>`
|
|
110
|
+
* otherwise. Lets PDLSS scope on tool identity.
|
|
111
|
+
*/
|
|
112
|
+
interface McpPdlssMapping {
|
|
113
|
+
purpose: string;
|
|
114
|
+
action: string;
|
|
115
|
+
resource: string;
|
|
116
|
+
}
|
|
117
|
+
declare function mcpToPdlss(parsed: ParsedMcpRequest): McpPdlssMapping;
|
|
118
|
+
/**
|
|
119
|
+
* Recommended minimum access level per method type. The MCP middleware uses
|
|
120
|
+
* this to split low-risk handshake / introspection traffic from high-risk
|
|
121
|
+
* tool execution — defect (a) from the cohort-3 review.
|
|
122
|
+
*
|
|
123
|
+
* - `initialize` / `notifications/initialized` → `none` (handshake must work for unregistered probes)
|
|
124
|
+
* - `tools/list` / `prompts/list` / `resources/list` → `none` (introspection is public-surface)
|
|
125
|
+
* - `ping` → `none`
|
|
126
|
+
* - `resources/read` → `read-only`
|
|
127
|
+
* - `tools/call` → `standard` (default — overridable per-tool)
|
|
128
|
+
* - everything else → `standard` (least-privilege fallback)
|
|
129
|
+
*/
|
|
130
|
+
declare function mcpRiskTier(parsed: ParsedMcpRequest): AccessLevel;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* AstraSync Universal Verification Gateway — MCP middleware
|
|
134
|
+
*
|
|
135
|
+
* Express-shaped middleware tailored to the JSON-RPC body of an MCP
|
|
136
|
+
* (Model Context Protocol) endpoint. Closes the cohort-3 gaps the default
|
|
137
|
+
* `createMiddleware` couldn't:
|
|
138
|
+
*
|
|
139
|
+
* (a) **Body-aware gating**. All MCP traffic targets the same `/mcp` URL.
|
|
140
|
+
* The default route-pattern matcher can't tell `initialize` (low risk)
|
|
141
|
+
* from `tools/call start_checkout` (high risk). This middleware peels
|
|
142
|
+
* the JSON-RPC body and applies a per-method risk tier.
|
|
143
|
+
*
|
|
144
|
+
* (b) **PDLSS mapping**. Forwards `purpose=mcp_invoke`,
|
|
145
|
+
* `action=method[:tool]`, `resource=mcp:tool/<name>` so audit traces
|
|
146
|
+
* are stable across cohort-3 partners. See `transport/mcp-server.ts`
|
|
147
|
+
* for the exact mapping.
|
|
148
|
+
*
|
|
149
|
+
* (c) **Inner-hop dedupe**. Outbound responses set
|
|
150
|
+
* `X-Astra-Verified-Hop` so a downstream REST endpoint that the tool
|
|
151
|
+
* calls can skip a duplicate verify-access. The receiving REST
|
|
152
|
+
* middleware checks `parseVerifiedHop` and skips when valid.
|
|
153
|
+
*
|
|
154
|
+
* (d) **Header-vs-body identity precedence**. Reads ASTRA-id from
|
|
155
|
+
* `X-Astra-Id` first, body second. If both are present and disagree,
|
|
156
|
+
* returns a structured 400 by default (configurable). Pre-fix,
|
|
157
|
+
* integrators had to re-discover this on their own.
|
|
158
|
+
*
|
|
159
|
+
* Usage:
|
|
160
|
+
*
|
|
161
|
+
* ```typescript
|
|
162
|
+
* import express from 'express';
|
|
163
|
+
* import { createMcpMiddleware } from '@astrasyncai/verification-gateway/mcp';
|
|
164
|
+
*
|
|
165
|
+
* const app = express();
|
|
166
|
+
* app.use(express.json());
|
|
167
|
+
*
|
|
168
|
+
* app.post(
|
|
169
|
+
* '/mcp',
|
|
170
|
+
* createMcpMiddleware({
|
|
171
|
+
* apiBaseUrl: 'https://astrasync.ai/api',
|
|
172
|
+
* apiKey: process.env.ASTRASYNC_API_KEY,
|
|
173
|
+
* // Optional per-tool overrides — tools not listed get the default tier
|
|
174
|
+
* // from `mcpRiskTier` (`tools/call` → 'standard').
|
|
175
|
+
* toolGates: {
|
|
176
|
+
* start_checkout: 'standard',
|
|
177
|
+
* confirm_purchase: 'full',
|
|
178
|
+
* browse_catalog: 'read-only',
|
|
179
|
+
* },
|
|
180
|
+
* }),
|
|
181
|
+
* yourMcpServerHandler,
|
|
182
|
+
* );
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
|
|
186
|
+
declare global {
|
|
187
|
+
namespace Express {
|
|
188
|
+
interface Request {
|
|
189
|
+
mcpRequest?: ParsedMcpRequest;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
interface McpMiddlewareOptions extends GatewayConfig {
|
|
194
|
+
/**
|
|
195
|
+
* Per-tool override for the minimum access level. Tools not listed inherit
|
|
196
|
+
* the default tier from `mcpRiskTier` (`tools/call` → `'standard'`). Use
|
|
197
|
+
* for high-risk tools that demand `'full'` or low-risk read-only tools.
|
|
198
|
+
*/
|
|
199
|
+
toolGates?: Record<string, AccessLevel>;
|
|
200
|
+
/**
|
|
201
|
+
* Per-method override (e.g. tighten `tools/list` to `'read-only'` if you
|
|
202
|
+
* don't want unregistered probes seeing your tool catalogue). Matches by
|
|
203
|
+
* exact JSON-RPC method string.
|
|
204
|
+
*/
|
|
205
|
+
methodGates?: Record<string, AccessLevel>;
|
|
206
|
+
/**
|
|
207
|
+
* What to do when the agent id supplied in the X-Astra-Id header
|
|
208
|
+
* disagrees with the agent id in the JSON-RPC body
|
|
209
|
+
* (`params._meta.astrasync.agentId` or `params.arguments.agent_id`).
|
|
210
|
+
*
|
|
211
|
+
* - `'reject'` (default) — return 400 `AGENT_ID_MISMATCH`. Safest.
|
|
212
|
+
* - `'prefer-header'` — log + verify against the header value. Keeps
|
|
213
|
+
* bodies that were authored before X-Astra-Id was the canonical
|
|
214
|
+
* identity slot working.
|
|
215
|
+
* - `'prefer-body'` — log + verify against the body value. Useful in
|
|
216
|
+
* reverse-proxy setups that strip auth headers.
|
|
217
|
+
*/
|
|
218
|
+
onAgentIdMismatch?: 'reject' | 'prefer-header' | 'prefer-body';
|
|
219
|
+
/** Skip verification + dedupe entirely. For testing. */
|
|
220
|
+
skip?: boolean;
|
|
221
|
+
/** Custom denied handler. Defaults to a structured JSON-RPC error response. */
|
|
222
|
+
onDenied?: (result: VerificationResult, req: Request, res: Response) => void;
|
|
223
|
+
/**
|
|
224
|
+
* If `false`, don't trust an inbound `X-Astra-Verified-Hop` header (always
|
|
225
|
+
* call verify-access). Default `true` — recommended for inner-hop endpoints
|
|
226
|
+
* called by your own MCP tools.
|
|
227
|
+
*/
|
|
228
|
+
trustVerifiedHop?: boolean;
|
|
229
|
+
/** Window for accepting an upstream verified-hop marker. Default 60_000ms. */
|
|
230
|
+
verifiedHopMaxAgeMs?: number;
|
|
231
|
+
/**
|
|
232
|
+
* Automatically record grant/deny decisions for every MCP call. Default
|
|
233
|
+
* `true` — matches the express adapter.
|
|
234
|
+
*/
|
|
235
|
+
recordDecisions?: boolean;
|
|
236
|
+
/** Forward runtime challenge (default `true`). */
|
|
237
|
+
enableRuntimeChallenge?: boolean;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Create the MCP middleware. Attach AFTER `express.json()` — the body must
|
|
241
|
+
* already be a parsed object.
|
|
242
|
+
*/
|
|
243
|
+
declare function createMcpMiddleware(options: McpMiddlewareOptions): RequestHandler;
|
|
244
|
+
|
|
245
|
+
export { MCP_VERIFIED_HOP_HEADER, type McpMiddlewareOptions, type ParsedMcpRequest, createMcpMiddleware, isVerifiedHopValidFor, mcpRiskTier, mcpToPdlss, parseMcpJsonRpc, parseVerifiedHop, serializeVerifiedHop };
|