@kya-os/checkpoint-wasm-runtime 1.1.1 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +116 -0
- package/dist/edge.d.mts +531 -4
- package/dist/edge.d.ts +531 -4
- package/dist/edge.js +1 -1
- package/dist/edge.mjs +2 -2
- package/dist/engine.js +11 -0
- package/dist/engine.mjs +22 -4
- package/dist/index.d.mts +72 -5
- package/dist/index.d.ts +72 -5
- package/dist/index.js +3 -1
- package/dist/index.mjs +5 -2
- package/dist/node.d.mts +2 -3
- package/dist/node.d.ts +2 -3
- package/dist/node.js +1 -1
- package/dist/node.mjs +5 -2
- package/dist/orchestrator-edge.d.mts +199 -5
- package/dist/orchestrator-edge.d.ts +199 -5
- package/dist/orchestrator-node.d.mts +313 -5
- package/dist/orchestrator-node.d.ts +313 -5
- package/dist/orchestrator-node.js +23 -0
- package/dist/orchestrator-node.mjs +34 -4
- package/dist/orchestrator.d.mts +86 -6
- package/dist/orchestrator.d.ts +86 -6
- package/dist/orchestrator.js +29 -2
- package/dist/orchestrator.mjs +36 -4
- package/dist/{rules-detector-DjbTJ1-Q.d.mts → rules-detector-ZIKHN-_y.d.mts} +63 -1
- package/dist/{rules-detector-DjbTJ1-Q.d.ts → rules-detector-ZIKHN-_y.d.ts} +63 -1
- package/package.json +1 -1
- package/dist/dynamic-loader-cS-pUisw.d.ts +0 -65
- package/dist/dynamic-loader-qGJacfEC.d.mts +0 -65
- package/dist/render-decision-C1a-iuiW.d.mts +0 -200
- package/dist/render-decision-Dsjwt96g.d.ts +0 -200
- package/dist/static-loader-C1hUlksK.d.ts +0 -72
- package/dist/static-loader-Ds4iNw7c.d.mts +0 -72
|
@@ -1,8 +1,203 @@
|
|
|
1
|
-
import { V as VerifyResult } from './types-D0j85fF0.js';
|
|
2
|
-
import { V as VerifyRequestOpts, I as IncomingHttpLike } from './render-decision-Dsjwt96g.js';
|
|
3
|
-
export { B as BuildAgentRequestOpts, R as RenderedResponse, b as buildAgentRequest, e as extractAgentDid, a as extractCredentialStatusUrl, c as extractIssuer, h as hasMalformedJwsBody, r as renderDecisionAsResponse } from './render-decision-Dsjwt96g.js';
|
|
1
|
+
import { d as DidDocument, D as Decision, E as EnforcementMode, V as VerifyResult, A as AgentRequest } from './types-D0j85fF0.js';
|
|
4
2
|
import '@kya-os/checkpoint-shared';
|
|
5
|
-
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* DidResolver adapter — sub-phase B.1.
|
|
6
|
+
*
|
|
7
|
+
* Resolves `did:key:*` (in-memory multibase decode) and `did:web:*`
|
|
8
|
+
* (HTTPS fetch of `.well-known/did.json`) into the engine's
|
|
9
|
+
* `DidDocument` shape. The async half does any required I/O; the
|
|
10
|
+
* adapter's output is plain data that the host wrapper bundles into
|
|
11
|
+
* `ContextSpec.didDocs` before calling `engineVerify`.
|
|
12
|
+
*
|
|
13
|
+
* Phase 1 supports only Ed25519 verification methods (the engine's
|
|
14
|
+
* `KeyType` is `#[non_exhaustive]` with `Ed25519` as its single
|
|
15
|
+
* variant). Non-Ed25519 methods on a resolved doc are silently
|
|
16
|
+
* filtered out — the engine wouldn't accept them as a valid Stage 2
|
|
17
|
+
* key match anyway.
|
|
18
|
+
*
|
|
19
|
+
* **`kid` for `did:key`**: the verification-method id is
|
|
20
|
+
* `<did>#<multibase>` per mcp-i-core PR #16. **NOT** `<did>#keys-1`.
|
|
21
|
+
* H-1's `stage2_did_key_fragment_resolution` test pins this.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
interface DidResolverAdapter {
|
|
25
|
+
resolve(did: string): Promise<DidDocument>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface StatusListCacheAdapter {
|
|
29
|
+
/**
|
|
30
|
+
* Fetch the status list at `url`, decode it, and return the sorted
|
|
31
|
+
* set of revoked credential indices.
|
|
32
|
+
*
|
|
33
|
+
* @throws {StatusListUnavailable} on transport / non-2xx response.
|
|
34
|
+
* @throws {StatusListTimeout} when the fetch budget is exceeded.
|
|
35
|
+
* @throws {MalformedStatusList} when the VC is unparseable.
|
|
36
|
+
*/
|
|
37
|
+
fetch(url: string): Promise<number[]>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* ReputationOracle adapter — sub-phase B.3.
|
|
42
|
+
*
|
|
43
|
+
* Resolves a per-DID reputation score in `[0.0, 1.0]`. Phase 1 wires
|
|
44
|
+
* an optional HTTP endpoint (Argus). Unavailable / misconfigured /
|
|
45
|
+
* out-of-range responses degrade to a baseline score so infrastructure
|
|
46
|
+
* blips can't silently DOS Adobe-class traffic. The engine's Stage 6
|
|
47
|
+
* compares the returned score against the tenant-configured threshold
|
|
48
|
+
* (Phase B.4 builds the threshold via `PolicyEvaluator`).
|
|
49
|
+
*
|
|
50
|
+
* **Degrade-to-trust** (Phase B § 4.5). Reputation is best-effort;
|
|
51
|
+
* Argus outages do not block traffic. The adapter returns the
|
|
52
|
+
* configured baseline (default 1.0 = "no signal, treat as trusted")
|
|
53
|
+
* and logs loudly. The engine's `LowReputation` block fires only
|
|
54
|
+
* when score < threshold from tenant policy; baseline-1.0 ensures
|
|
55
|
+
* no traffic is silently rejected just because Argus went down.
|
|
56
|
+
*/
|
|
57
|
+
interface ReputationOracleAdapter {
|
|
58
|
+
/**
|
|
59
|
+
* Return the agent's reputation in `[0.0, 1.0]`. Higher is better.
|
|
60
|
+
*
|
|
61
|
+
* **Does not throw.** Network / parse / range failures degrade to
|
|
62
|
+
* the baseline + log; the engine should never see a thrown error
|
|
63
|
+
* from this adapter.
|
|
64
|
+
*/
|
|
65
|
+
score(agentDid: string): Promise<number>;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* PolicyEvaluator adapter — sub-phase B.4.
|
|
70
|
+
*
|
|
71
|
+
* Computes the **tenant verdict** on the JS side and hands the engine
|
|
72
|
+
* a constant `Decision` for the WASM `WasmConstantPolicy` to echo as
|
|
73
|
+
* Stage 7's contribution. The engine's cross-stage priority order
|
|
74
|
+
* (locked in D-design § 6 row 4) handles how Stage 7 interacts with
|
|
75
|
+
* Stages 2 / 3 / 4 / 5.
|
|
76
|
+
*
|
|
77
|
+
* **Sync-engine / async-host invariant.** The JS adapter is async (it
|
|
78
|
+
* fetches tenant policy from the Checkpoint dashboard); the engine
|
|
79
|
+
* sees only the resolved `Decision`. Cedar-1 will replace this
|
|
80
|
+
* adapter's implementation without touching the surrounding orchestrator.
|
|
81
|
+
*
|
|
82
|
+
* **Cedar-1 forward-compat.** [`PolicyEvaluatorAdapter`] is the
|
|
83
|
+
* Cedar-swappable interface: `(input) → Decision`. The Phase 1 stub
|
|
84
|
+
* is a reputation-threshold check; Cedar-1 will replace the
|
|
85
|
+
* implementation, not the surface. Don't bake Cedar internals into
|
|
86
|
+
* this seam.
|
|
87
|
+
*
|
|
88
|
+
* **Degrade-to-permit.** Per Phase B § 4.5: when the dashboard policy
|
|
89
|
+
* endpoint is unreachable, fall back to `defaultPolicy` (caller-supplied)
|
|
90
|
+
* or `permit-by-default`. Loud log; no silent block.
|
|
91
|
+
*/
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Pre-fetched inputs the JS host knows before calling the engine.
|
|
95
|
+
* Phase 1's evaluator only consumes `reputation` + `tenantHost`; later
|
|
96
|
+
* implementations (Cedar-1) may extend.
|
|
97
|
+
*/
|
|
98
|
+
interface PolicyEvalInput {
|
|
99
|
+
tenantHost: string;
|
|
100
|
+
reputation: number;
|
|
101
|
+
}
|
|
102
|
+
interface PolicyEvaluatorAdapter {
|
|
103
|
+
evaluate(input: PolicyEvalInput): Promise<Decision>;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Clock adapter — sub-phase B.5.
|
|
108
|
+
*
|
|
109
|
+
* Provides the Unix-seconds timestamp the engine's `Clock` trait needs
|
|
110
|
+
* for Stage 4 expiration checks. Trivial; the trait shape exists so
|
|
111
|
+
* tests can inject a frozen clock (and so the engine's sync-trait
|
|
112
|
+
* surface is satisfied without a JS callback crossing the WASM
|
|
113
|
+
* boundary — `ContextSpec.nowUnix` carries the value).
|
|
114
|
+
*/
|
|
115
|
+
interface ClockAdapter {
|
|
116
|
+
nowUnix(): number;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Orchestrator-layer types — Phase C, host-side only.
|
|
121
|
+
*
|
|
122
|
+
* Nothing here crosses the WASM boundary. The engine ABI types live
|
|
123
|
+
* in `../types.ts`; the adapter interfaces live in
|
|
124
|
+
* `../adapters/index.ts`. This file is the host-wrapper-facing
|
|
125
|
+
* surface — what Phase D (Next.js) and Phase E (Express) import.
|
|
126
|
+
*/
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Framework-agnostic HTTP request shape.
|
|
130
|
+
*
|
|
131
|
+
* Next.js / Express / Cloudflare Workers / Hono adapters marshal
|
|
132
|
+
* their native request type into this shape before calling
|
|
133
|
+
* `verifyRequest`. The shape is intentionally minimal — only what
|
|
134
|
+
* the engine needs to make a verdict.
|
|
135
|
+
*/
|
|
136
|
+
interface IncomingHttpLike {
|
|
137
|
+
method: string;
|
|
138
|
+
/** Path + query string (no scheme + host). */
|
|
139
|
+
url: string;
|
|
140
|
+
headers: Record<string, string | string[] | undefined>;
|
|
141
|
+
/**
|
|
142
|
+
* Parsed body if the framework has already parsed it (Next.js
|
|
143
|
+
* with `await req.json()`, Express with `body-parser`). Falsy if
|
|
144
|
+
* the caller hasn't materialised the body — the orchestrator
|
|
145
|
+
* treats that as "no MCP-I envelope present" and routes to
|
|
146
|
+
* PlainHttp.
|
|
147
|
+
*/
|
|
148
|
+
body?: Buffer | string | object | null;
|
|
149
|
+
/** Client IP if the framework surfaces one (Express `req.ip`). */
|
|
150
|
+
remoteAddress?: string;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Options the host wrapper passes per-`verifyRequest`-construction.
|
|
154
|
+
* The five adapters + clock + tenant identifier + enforcement mode.
|
|
155
|
+
*/
|
|
156
|
+
interface VerifyRequestOpts {
|
|
157
|
+
didResolver: DidResolverAdapter;
|
|
158
|
+
statusListCache: StatusListCacheAdapter;
|
|
159
|
+
reputationOracle: ReputationOracleAdapter;
|
|
160
|
+
policyEvaluator: PolicyEvaluatorAdapter;
|
|
161
|
+
clock: ClockAdapter;
|
|
162
|
+
/** Tenant identifier — the host customer this request targets. */
|
|
163
|
+
tenantHost: string;
|
|
164
|
+
enforcementMode: EnforcementMode;
|
|
165
|
+
/** Returned to the PolicyEvaluator when the request has no agent DID. Default 1.0. */
|
|
166
|
+
reputationBaseline?: number;
|
|
167
|
+
/**
|
|
168
|
+
* **Envelope-1 (#2537) coordination flag.** Pre-Envelope-1 the TS
|
|
169
|
+
* bouncer ships MCP-I proofs as `{protected,payload,signature}` JSON
|
|
170
|
+
* in a `KYA-Delegation` header. Post-Envelope-1 they ship compact
|
|
171
|
+
* JWS in `_meta.proof.jws` of the body. When this flag is true the
|
|
172
|
+
* orchestrator also accepts the legacy header form. **Default off.**
|
|
173
|
+
* Delete this flag once Envelope-1 ships end-to-end.
|
|
174
|
+
*/
|
|
175
|
+
legacyEnvelopeFallback?: boolean;
|
|
176
|
+
/**
|
|
177
|
+
* Argus URL — passed only so the orchestrator can detect "Argus
|
|
178
|
+
* not configured" at construction time and log the one-shot
|
|
179
|
+
* warning. The actual reputation fetch goes through `reputationOracle`.
|
|
180
|
+
*/
|
|
181
|
+
argusUrl?: string;
|
|
182
|
+
/** Injectable for the once-only Argus configuration warning. */
|
|
183
|
+
logger?: (msg: string) => void;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Transport-agnostic response shape `renderDecisionAsResponse`
|
|
187
|
+
* produces. Host wrappers adapt this to their framework's response
|
|
188
|
+
* type (NextResponse / Express `res` / Cloudflare Response).
|
|
189
|
+
*
|
|
190
|
+
* `status === null` means "pass through" — the request continues to
|
|
191
|
+
* the next handler. Happens in two cases:
|
|
192
|
+
* 1. `Decision::Permit` (no block in Enforce mode).
|
|
193
|
+
* 2. **Any verdict in Observe mode** — Observe never blocks, but
|
|
194
|
+
* the response headers still carry the would-have-been verdict.
|
|
195
|
+
*/
|
|
196
|
+
interface RenderedResponse {
|
|
197
|
+
status: number | null;
|
|
198
|
+
headers: Record<string, string>;
|
|
199
|
+
body?: string | object;
|
|
200
|
+
}
|
|
6
201
|
|
|
7
202
|
/**
|
|
8
203
|
* `verifyRequest` async orchestrator — Phase C.2.
|
|
@@ -46,4 +241,117 @@ declare function makeVerifyRequest(opts: VerifyRequestOpts): (req: IncomingHttpL
|
|
|
46
241
|
*/
|
|
47
242
|
declare function verifyRequest(req: IncomingHttpLike, opts: VerifyRequestOpts): Promise<VerifyResult>;
|
|
48
243
|
|
|
49
|
-
|
|
244
|
+
/**
|
|
245
|
+
* HTTP-to-`AgentRequest` translator — Phase C.1.
|
|
246
|
+
*
|
|
247
|
+
* Detects which engine protocol the request belongs to and builds
|
|
248
|
+
* the typed `AgentRequest` the WASM consumes. Conservative
|
|
249
|
+
* detection: never escalates an ambiguous request into a higher
|
|
250
|
+
* verification tier. Anonymous PlainHttp is the default.
|
|
251
|
+
*
|
|
252
|
+
* **What this layer parses and what it doesn't.** It parses *only
|
|
253
|
+
* what's needed to drive conditional pre-fetch* — header presence,
|
|
254
|
+
* the MCP-I envelope's payload segment (to extract `iss` + `sub` +
|
|
255
|
+
* optional credentialStatus URL). It does **not** verify
|
|
256
|
+
* signatures, decode VC chains for revocation bits, or evaluate
|
|
257
|
+
* scope. Those live in the engine (H-1's parser + Stages 2-5).
|
|
258
|
+
*
|
|
259
|
+
* **Buffer-portability note.** This module uses `Buffer.from(...)` and
|
|
260
|
+
* `Buffer.isBuffer(...)` at multiple call sites (the JWS preflight
|
|
261
|
+
* `hasMalformedJwsBody`, both `tryBuildMcpIFromBody` variants, the
|
|
262
|
+
* legacy-header reconstitution path, and `bodyAsBytes`). All of these
|
|
263
|
+
* assume the Node `Buffer` global is available — provided natively by
|
|
264
|
+
* the Node runtime, polyfilled on Vercel Edge, and gated behind
|
|
265
|
+
* `nodejs_compat` on Cloudflare Workers. Bare-Edge and pure-browser
|
|
266
|
+
* embedders would need a `Buffer` polyfill or a refactor to
|
|
267
|
+
* `TextEncoder` / `Uint8Array.from`. Tracked as a follow-up since
|
|
268
|
+
* Phase D's Vercel Node + Vercel Edge targets are both covered today.
|
|
269
|
+
*/
|
|
270
|
+
|
|
271
|
+
interface BuildAgentRequestOpts {
|
|
272
|
+
/** See `VerifyRequestOpts.legacyEnvelopeFallback`. */
|
|
273
|
+
legacyEnvelopeFallback?: boolean;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Translate an HTTP-like request into the engine's `AgentRequest`.
|
|
277
|
+
*
|
|
278
|
+
* Detection order (conservative — never escalate ambiguous input):
|
|
279
|
+
* 1. MCP-I L2 detached proof in `_meta.proof.jws` (spec form).
|
|
280
|
+
* 2. (Legacy, opt-in) MCP-I in `KYA-Delegation` header
|
|
281
|
+
* (Envelope-1 #2537 transition window only).
|
|
282
|
+
* 3. RFC 9421 HTTP Message Signatures (`Signature-Input` header).
|
|
283
|
+
* 4. PlainHttp (default — anonymous traffic).
|
|
284
|
+
*/
|
|
285
|
+
declare function buildAgentRequest(req: IncomingHttpLike, opts?: BuildAgentRequestOpts): AgentRequest;
|
|
286
|
+
/**
|
|
287
|
+
* Preflight check — does the request body carry a `_meta.proof.jws`
|
|
288
|
+
* string that `parseJwsPayloadStruct` cannot project into a typed
|
|
289
|
+
* `McpIPayload`?
|
|
290
|
+
*
|
|
291
|
+
* The caller declared intent (an MCP-I envelope) by including the
|
|
292
|
+
* JWS field; structural failure to extract the payload means the
|
|
293
|
+
* envelope is malformed, not absent. Without this preflight, the
|
|
294
|
+
* orchestrator would silently fall through to PlainHttp — pre-#2560
|
|
295
|
+
* that happened to also Block (engine returned `Block(ParseError)`
|
|
296
|
+
* for every PlainHttp), so the regression was invisible; post-#2560
|
|
297
|
+
* the engine's Stage 1 + stub policy returns `Permit` for anonymous
|
|
298
|
+
* PlainHttp and tampered envelopes would be silently accepted.
|
|
299
|
+
*
|
|
300
|
+
* Returns `true` when the orchestrator should synthesize
|
|
301
|
+
* `Block(ParseError)` BEFORE calling `buildAgentRequest`.
|
|
302
|
+
*/
|
|
303
|
+
declare function hasMalformedJwsBody(req: IncomingHttpLike): boolean;
|
|
304
|
+
/**
|
|
305
|
+
* Issuer DID — Stage 1 (identity resolution) targets this. `null`
|
|
306
|
+
* for PlainHttp (anonymous → no DID to resolve).
|
|
307
|
+
*/
|
|
308
|
+
declare function extractIssuer(request: AgentRequest): string | null;
|
|
309
|
+
/**
|
|
310
|
+
* Agent DID — used by ReputationOracle. Defaults to `payload.sub`
|
|
311
|
+
* for MCP-I (subject = the agent the proof is *about*).
|
|
312
|
+
*/
|
|
313
|
+
declare function extractAgentDid(request: AgentRequest): string | null;
|
|
314
|
+
/**
|
|
315
|
+
* Status-list URL for revocation pre-fetch. Pulled from the JWS
|
|
316
|
+
* payload's `vc.credentialStatus.id` (W3C VC Data Model 1.1).
|
|
317
|
+
* `null` when the envelope is L1 (no VC chain) — Stage 3 will skip.
|
|
318
|
+
*/
|
|
319
|
+
declare function extractCredentialStatusUrl(request: AgentRequest): string | null;
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Transport-agnostic `Decision` → HTTP renderer — Phase C.3.
|
|
323
|
+
*
|
|
324
|
+
* Translates a `VerifyResult` into a framework-neutral
|
|
325
|
+
* `{ status, headers, body }` shape. Phase D (Next.js) adapts this
|
|
326
|
+
* to `NextResponse`; Phase E (Express) adapts it to `res.status().set().send()`.
|
|
327
|
+
* One source of truth for the verdict→HTTP mapping.
|
|
328
|
+
*
|
|
329
|
+
* Mapping table (§ 4.5 of Phase C kickoff):
|
|
330
|
+
*
|
|
331
|
+
* | Decision | HTTP | Notes |
|
|
332
|
+
* |-----------------------------------|------|-----------------------------------------|
|
|
333
|
+
* | Permit | null | Pass through to next handler |
|
|
334
|
+
* | Block(Unauthenticated) | 401 | WWW-Authenticate header |
|
|
335
|
+
* | Block(InvalidSignature) | 403 | |
|
|
336
|
+
* | Block(Revoked) | 403 | |
|
|
337
|
+
* | Block(Expired) | 401 | Refresh-the-credential semantics |
|
|
338
|
+
* | Block(OutOfScope) | 403 | Body carries requested + granted |
|
|
339
|
+
* | Block(LowReputation) | 403 | Body carries score + threshold |
|
|
340
|
+
* | Block(PolicyDenied) | 403 | Body carries detail |
|
|
341
|
+
* | Block(ParseError) | 400 | Body carries detail |
|
|
342
|
+
* | Challenge | 401 | Body carries ChallengeParams |
|
|
343
|
+
* | Redirect | 302 | Location header |
|
|
344
|
+
* | Instruct | 422 | application/problem+json body |
|
|
345
|
+
*
|
|
346
|
+
* Observe mode overrides: every verdict renders as `status: null`
|
|
347
|
+
* (pass through) with an `X-Checkpoint-Would-Have-Been` header
|
|
348
|
+
* carrying the verdict kind, plus the standard attribution headers.
|
|
349
|
+
*
|
|
350
|
+
* Every response carries the Phase 0.1 attribution headers:
|
|
351
|
+
* `X-Checkpoint-Engine`, `X-Checkpoint-Engine-Version`, and
|
|
352
|
+
* (when present) `X-Checkpoint-Ruleset-Hash`.
|
|
353
|
+
*/
|
|
354
|
+
|
|
355
|
+
declare function renderDecisionAsResponse(result: VerifyResult): RenderedResponse;
|
|
356
|
+
|
|
357
|
+
export { type BuildAgentRequestOpts, type IncomingHttpLike, type RenderedResponse, type VerifyRequestOpts, buildAgentRequest, extractAgentDid, extractCredentialStatusUrl, extractIssuer, hasMalformedJwsBody, makeVerifyRequest, renderDecisionAsResponse, verifyRequest };
|
|
@@ -12,6 +12,9 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
12
12
|
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
13
13
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
14
14
|
});
|
|
15
|
+
var __esm = (fn, res) => function __init() {
|
|
16
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
17
|
+
};
|
|
15
18
|
var __commonJS = (cb, mod) => function __require2() {
|
|
16
19
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
17
20
|
};
|
|
@@ -32,9 +35,16 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
32
35
|
mod
|
|
33
36
|
));
|
|
34
37
|
|
|
38
|
+
// ../../node_modules/.pnpm/tsup@8.5.0_@swc+core@1.15.32_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js
|
|
39
|
+
var init_cjs_shims = __esm({
|
|
40
|
+
"../../node_modules/.pnpm/tsup@8.5.0_@swc+core@1.15.32_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js"() {
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
35
44
|
// wasm/kya-os-engine/kya_os_engine.js
|
|
36
45
|
var require_kya_os_engine = __commonJS({
|
|
37
46
|
"wasm/kya-os-engine/kya_os_engine.js"(exports$1, module) {
|
|
47
|
+
init_cjs_shims();
|
|
38
48
|
var imports = {};
|
|
39
49
|
imports["__wbindgen_placeholder__"] = module.exports;
|
|
40
50
|
var cachedUint8ArrayMemory0 = null;
|
|
@@ -444,7 +454,14 @@ ${val.stack}`;
|
|
|
444
454
|
}
|
|
445
455
|
});
|
|
446
456
|
|
|
457
|
+
// src/engine/orchestrator/node.ts
|
|
458
|
+
init_cjs_shims();
|
|
459
|
+
|
|
460
|
+
// src/engine/orchestrator/verify-request.ts
|
|
461
|
+
init_cjs_shims();
|
|
462
|
+
|
|
447
463
|
// src/engine/adapters/outbound-url-policy.ts
|
|
464
|
+
init_cjs_shims();
|
|
448
465
|
var BLOCKED_HOSTNAMES = /* @__PURE__ */ new Set(["localhost", "metadata", "metadata.google.internal"]);
|
|
449
466
|
var UnsafeOutboundUrl = class extends Error {
|
|
450
467
|
kind = "UnsafeOutboundUrl";
|
|
@@ -520,13 +537,18 @@ function isBlockedIpv6(hostname) {
|
|
|
520
537
|
}
|
|
521
538
|
|
|
522
539
|
// src/engine/index.ts
|
|
540
|
+
init_cjs_shims();
|
|
523
541
|
var wasmModule = __toESM(require_kya_os_engine());
|
|
524
542
|
function engineVerify(input, ctx) {
|
|
525
543
|
const verify2 = wasmModule.verify;
|
|
526
544
|
return verify2(input, ctx);
|
|
527
545
|
}
|
|
528
546
|
|
|
547
|
+
// src/engine/orchestrator/build-agent-request.ts
|
|
548
|
+
init_cjs_shims();
|
|
549
|
+
|
|
529
550
|
// src/engine/adapters/util.ts
|
|
551
|
+
init_cjs_shims();
|
|
530
552
|
function base64UrlDecode(input) {
|
|
531
553
|
const padded = input.replace(/-/g, "+").replace(/_/g, "/");
|
|
532
554
|
const padding = padded.length % 4 === 0 ? "" : "=".repeat(4 - padded.length % 4);
|
|
@@ -821,6 +843,7 @@ function defaultLogger(msg) {
|
|
|
821
843
|
}
|
|
822
844
|
|
|
823
845
|
// src/engine/orchestrator/render-decision.ts
|
|
846
|
+
init_cjs_shims();
|
|
824
847
|
function renderDecisionAsResponse(result) {
|
|
825
848
|
const baseHeaders = buildBaseHeaders(result);
|
|
826
849
|
if (result.enforcementMode === "observe") {
|
|
@@ -1,15 +1,23 @@
|
|
|
1
|
+
import { createRequire } from 'module';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
const require$1 = createRequire(import.meta.url);
|
|
1
6
|
var __create = Object.create;
|
|
2
7
|
var __defProp = Object.defineProperty;
|
|
3
8
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
9
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
10
|
var __getProtoOf = Object.getPrototypeOf;
|
|
6
11
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
8
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
12
|
+
var __require = /* @__PURE__ */ ((x) => typeof require$1 !== "undefined" ? require$1 : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
13
|
+
get: (a, b) => (typeof require$1 !== "undefined" ? require$1 : a)[b]
|
|
9
14
|
}) : x)(function(x) {
|
|
10
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
15
|
+
if (typeof require$1 !== "undefined") return require$1.apply(this, arguments);
|
|
11
16
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
12
17
|
});
|
|
18
|
+
var __esm = (fn, res) => function __init() {
|
|
19
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
20
|
+
};
|
|
13
21
|
var __commonJS = (cb, mod) => function __require2() {
|
|
14
22
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
15
23
|
};
|
|
@@ -29,10 +37,19 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
29
37
|
!mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
30
38
|
mod
|
|
31
39
|
));
|
|
40
|
+
var getFilename, getDirname, __dirname$1;
|
|
41
|
+
var init_esm_shims = __esm({
|
|
42
|
+
"../../node_modules/.pnpm/tsup@8.5.0_@swc+core@1.15.32_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.3/node_modules/tsup/assets/esm_shims.js"() {
|
|
43
|
+
getFilename = () => fileURLToPath(import.meta.url);
|
|
44
|
+
getDirname = () => path.dirname(getFilename());
|
|
45
|
+
__dirname$1 = /* @__PURE__ */ getDirname();
|
|
46
|
+
}
|
|
47
|
+
});
|
|
32
48
|
|
|
33
49
|
// wasm/kya-os-engine/kya_os_engine.js
|
|
34
50
|
var require_kya_os_engine = __commonJS({
|
|
35
51
|
"wasm/kya-os-engine/kya_os_engine.js"(exports$1, module) {
|
|
52
|
+
init_esm_shims();
|
|
36
53
|
var imports = {};
|
|
37
54
|
imports["__wbindgen_placeholder__"] = module.exports;
|
|
38
55
|
var cachedUint8ArrayMemory0 = null;
|
|
@@ -435,14 +452,21 @@ ${val.stack}`;
|
|
|
435
452
|
exports$1.__wbindgen_object_drop_ref = function(arg0) {
|
|
436
453
|
takeObject(arg0);
|
|
437
454
|
};
|
|
438
|
-
var wasmPath = `${__dirname}/kya_os_engine_bg.wasm`;
|
|
455
|
+
var wasmPath = `${__dirname$1}/kya_os_engine_bg.wasm`;
|
|
439
456
|
var wasmBytes = __require("fs").readFileSync(wasmPath);
|
|
440
457
|
var wasmModule2 = new WebAssembly.Module(wasmBytes);
|
|
441
458
|
var wasm = exports$1.__wasm = new WebAssembly.Instance(wasmModule2, imports).exports;
|
|
442
459
|
}
|
|
443
460
|
});
|
|
444
461
|
|
|
462
|
+
// src/engine/orchestrator/node.ts
|
|
463
|
+
init_esm_shims();
|
|
464
|
+
|
|
465
|
+
// src/engine/orchestrator/verify-request.ts
|
|
466
|
+
init_esm_shims();
|
|
467
|
+
|
|
445
468
|
// src/engine/adapters/outbound-url-policy.ts
|
|
469
|
+
init_esm_shims();
|
|
446
470
|
var BLOCKED_HOSTNAMES = /* @__PURE__ */ new Set(["localhost", "metadata", "metadata.google.internal"]);
|
|
447
471
|
var UnsafeOutboundUrl = class extends Error {
|
|
448
472
|
kind = "UnsafeOutboundUrl";
|
|
@@ -518,13 +542,18 @@ function isBlockedIpv6(hostname) {
|
|
|
518
542
|
}
|
|
519
543
|
|
|
520
544
|
// src/engine/index.ts
|
|
545
|
+
init_esm_shims();
|
|
521
546
|
var wasmModule = __toESM(require_kya_os_engine());
|
|
522
547
|
function engineVerify(input, ctx) {
|
|
523
548
|
const verify2 = wasmModule.verify;
|
|
524
549
|
return verify2(input, ctx);
|
|
525
550
|
}
|
|
526
551
|
|
|
552
|
+
// src/engine/orchestrator/build-agent-request.ts
|
|
553
|
+
init_esm_shims();
|
|
554
|
+
|
|
527
555
|
// src/engine/adapters/util.ts
|
|
556
|
+
init_esm_shims();
|
|
528
557
|
function base64UrlDecode(input) {
|
|
529
558
|
const padded = input.replace(/-/g, "+").replace(/_/g, "/");
|
|
530
559
|
const padding = padded.length % 4 === 0 ? "" : "=".repeat(4 - padded.length % 4);
|
|
@@ -819,6 +848,7 @@ function defaultLogger(msg) {
|
|
|
819
848
|
}
|
|
820
849
|
|
|
821
850
|
// src/engine/orchestrator/render-decision.ts
|
|
851
|
+
init_esm_shims();
|
|
822
852
|
function renderDecisionAsResponse(result) {
|
|
823
853
|
const baseHeaders = buildBaseHeaders(result);
|
|
824
854
|
if (result.enforcementMode === "observe") {
|
package/dist/orchestrator.d.mts
CHANGED
|
@@ -1,7 +1,87 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
3
|
-
|
|
4
|
-
export { initEngineEdge } from './engine-edge.mjs';
|
|
5
|
-
import './types-D0j85fF0.mjs';
|
|
1
|
+
import { VerifyRequestOpts, IncomingHttpLike } from './orchestrator-node.mjs';
|
|
2
|
+
export { BuildAgentRequestOpts, RenderedResponse, buildAgentRequest, extractAgentDid, extractCredentialStatusUrl, extractIssuer, hasMalformedJwsBody, makeVerifyRequest, renderDecisionAsResponse, verifyRequest } from './orchestrator-node.mjs';
|
|
3
|
+
import { V as VerifyResult } from './types-D0j85fF0.mjs';
|
|
6
4
|
import '@kya-os/checkpoint-shared';
|
|
7
|
-
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* `kya-os-engine` WASM bridge for edge runtimes — Edge-WASM-1.
|
|
8
|
+
*
|
|
9
|
+
* The Node target (`./index.ts`) uses `fs.readFileSync` at module
|
|
10
|
+
* load and exposes a sync `engineVerify`. That's incompatible with
|
|
11
|
+
* Vercel Edge / Cloudflare Workers / browser embedding (no `fs`,
|
|
12
|
+
* no sync wasm load).
|
|
13
|
+
*
|
|
14
|
+
* This module loads the `wasm-pack --target web` artifact via the
|
|
15
|
+
* async `__wbg_init` default export, then exposes the same typed
|
|
16
|
+
* `engineVerifyEdge(input, ctx) → Promise<VerifyResult>` shape with
|
|
17
|
+
* a small lazy-init wrapper. First call awaits initialisation;
|
|
18
|
+
* subsequent calls resolve synchronously on the JS side (the
|
|
19
|
+
* underlying wasm `verify` is sync).
|
|
20
|
+
*
|
|
21
|
+
* **Why this matters for the consolidation narrative.** Phase A
|
|
22
|
+
* shipped Node-only. Without an edge build, the first Vercel-edge
|
|
23
|
+
* or Cloudflare-Workers deployment after Phase D would hit the
|
|
24
|
+
* same wasm-bindgen-on-edge wall the Sites-1 F3 workaround was
|
|
25
|
+
* created to dodge — and someone would re-introduce the
|
|
26
|
+
* inline-TS detector that Q10 ratified deleting. Shipping the
|
|
27
|
+
* edge target alongside the Node target keeps Phase D's
|
|
28
|
+
* deletion narrative durable.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Initialise the edge wasm module. Idempotent — subsequent calls
|
|
33
|
+
* return the same in-flight or resolved promise. Host wrappers can
|
|
34
|
+
* call this at startup to eagerly load the wasm and avoid first-
|
|
35
|
+
* request latency, but it's not required: `engineVerifyEdge`
|
|
36
|
+
* lazily initialises on first call.
|
|
37
|
+
*
|
|
38
|
+
* @param moduleOrPath Optional pre-fetched `WebAssembly.Module` or
|
|
39
|
+
* a URL / Request the wasm-bindgen loader will
|
|
40
|
+
* fetch. Defaults to the bundled artifact via
|
|
41
|
+
* `import.meta.url`. Cloudflare Workers / Vercel
|
|
42
|
+
* Edge typically pass a pre-bundled `Module`.
|
|
43
|
+
*/
|
|
44
|
+
declare function initEngineEdge(moduleOrPath?: WebAssembly.Module | URL | string | Request | BufferSource): Promise<void>;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* `verifyRequestEdge` async-init orchestrator — Edge-WASM-2 (folded into
|
|
48
|
+
* Phase D's PR).
|
|
49
|
+
*
|
|
50
|
+
* Mirror of [[./verify-request.ts]] for edge runtimes. Differs in only
|
|
51
|
+
* three places:
|
|
52
|
+
*
|
|
53
|
+
* 1. Imports `engineVerifyEdge` + `initEngineEdge` from `../edge`
|
|
54
|
+
* instead of `engineVerify` from `../index` (Node target).
|
|
55
|
+
* 2. Awaits `initEngineEdge()` before the engine call — async-init
|
|
56
|
+
* pattern required by the `--target web` wasm-bindgen build.
|
|
57
|
+
* 3. The final engine call is `await engineVerifyEdge(...)` rather
|
|
58
|
+
* than the synchronous `engineVerify(...)`.
|
|
59
|
+
*
|
|
60
|
+
* **The two files MUST stay in sync.** Any change to verify-request.ts
|
|
61
|
+
* (new adapter, new error-classification rule, new ContextSpec field)
|
|
62
|
+
* MUST be mirrored here. The cross-target parity test in
|
|
63
|
+
* [[__tests__/verify-request-parity.test.ts]] guards the verdict-shape
|
|
64
|
+
* invariant — both orchestrators must produce identical
|
|
65
|
+
* `VerifyResult.decision` / `engineInfo.name` on identical inputs.
|
|
66
|
+
*
|
|
67
|
+
* Cedar-1 forward-compat: same seam as the Node variant — step (5)
|
|
68
|
+
* (tenant policy eval) is the only place the PolicyEvaluator
|
|
69
|
+
* interface gets exercised. When Cedar-1 swaps implementations, this
|
|
70
|
+
* orchestrator does not change.
|
|
71
|
+
*/
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Factory — constructs a `verifyRequestEdge` closure that remembers the
|
|
75
|
+
* one-shot Argus-not-configured warning state. Use this when the
|
|
76
|
+
* host wrapper wants the startup log; call `verifyRequestEdge` directly
|
|
77
|
+
* (the loose function below) if you don't.
|
|
78
|
+
*/
|
|
79
|
+
declare function makeVerifyRequestEdge(opts: VerifyRequestOpts): (req: IncomingHttpLike) => Promise<VerifyResult>;
|
|
80
|
+
/**
|
|
81
|
+
* Single-shot async entry. Use [`makeVerifyRequestEdge`] in long-lived
|
|
82
|
+
* hosts (so the Argus warning is one-shot per process); use this
|
|
83
|
+
* loose form in tests + one-off invocations.
|
|
84
|
+
*/
|
|
85
|
+
declare function verifyRequestEdge(req: IncomingHttpLike, opts: VerifyRequestOpts): Promise<VerifyResult>;
|
|
86
|
+
|
|
87
|
+
export { IncomingHttpLike, VerifyRequestOpts, initEngineEdge, makeVerifyRequestEdge, verifyRequestEdge };
|
package/dist/orchestrator.d.ts
CHANGED
|
@@ -1,7 +1,87 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
3
|
-
|
|
4
|
-
export { initEngineEdge } from './engine-edge.js';
|
|
5
|
-
import './types-D0j85fF0.js';
|
|
1
|
+
import { VerifyRequestOpts, IncomingHttpLike } from './orchestrator-node.js';
|
|
2
|
+
export { BuildAgentRequestOpts, RenderedResponse, buildAgentRequest, extractAgentDid, extractCredentialStatusUrl, extractIssuer, hasMalformedJwsBody, makeVerifyRequest, renderDecisionAsResponse, verifyRequest } from './orchestrator-node.js';
|
|
3
|
+
import { V as VerifyResult } from './types-D0j85fF0.js';
|
|
6
4
|
import '@kya-os/checkpoint-shared';
|
|
7
|
-
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* `kya-os-engine` WASM bridge for edge runtimes — Edge-WASM-1.
|
|
8
|
+
*
|
|
9
|
+
* The Node target (`./index.ts`) uses `fs.readFileSync` at module
|
|
10
|
+
* load and exposes a sync `engineVerify`. That's incompatible with
|
|
11
|
+
* Vercel Edge / Cloudflare Workers / browser embedding (no `fs`,
|
|
12
|
+
* no sync wasm load).
|
|
13
|
+
*
|
|
14
|
+
* This module loads the `wasm-pack --target web` artifact via the
|
|
15
|
+
* async `__wbg_init` default export, then exposes the same typed
|
|
16
|
+
* `engineVerifyEdge(input, ctx) → Promise<VerifyResult>` shape with
|
|
17
|
+
* a small lazy-init wrapper. First call awaits initialisation;
|
|
18
|
+
* subsequent calls resolve synchronously on the JS side (the
|
|
19
|
+
* underlying wasm `verify` is sync).
|
|
20
|
+
*
|
|
21
|
+
* **Why this matters for the consolidation narrative.** Phase A
|
|
22
|
+
* shipped Node-only. Without an edge build, the first Vercel-edge
|
|
23
|
+
* or Cloudflare-Workers deployment after Phase D would hit the
|
|
24
|
+
* same wasm-bindgen-on-edge wall the Sites-1 F3 workaround was
|
|
25
|
+
* created to dodge — and someone would re-introduce the
|
|
26
|
+
* inline-TS detector that Q10 ratified deleting. Shipping the
|
|
27
|
+
* edge target alongside the Node target keeps Phase D's
|
|
28
|
+
* deletion narrative durable.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Initialise the edge wasm module. Idempotent — subsequent calls
|
|
33
|
+
* return the same in-flight or resolved promise. Host wrappers can
|
|
34
|
+
* call this at startup to eagerly load the wasm and avoid first-
|
|
35
|
+
* request latency, but it's not required: `engineVerifyEdge`
|
|
36
|
+
* lazily initialises on first call.
|
|
37
|
+
*
|
|
38
|
+
* @param moduleOrPath Optional pre-fetched `WebAssembly.Module` or
|
|
39
|
+
* a URL / Request the wasm-bindgen loader will
|
|
40
|
+
* fetch. Defaults to the bundled artifact via
|
|
41
|
+
* `import.meta.url`. Cloudflare Workers / Vercel
|
|
42
|
+
* Edge typically pass a pre-bundled `Module`.
|
|
43
|
+
*/
|
|
44
|
+
declare function initEngineEdge(moduleOrPath?: WebAssembly.Module | URL | string | Request | BufferSource): Promise<void>;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* `verifyRequestEdge` async-init orchestrator — Edge-WASM-2 (folded into
|
|
48
|
+
* Phase D's PR).
|
|
49
|
+
*
|
|
50
|
+
* Mirror of [[./verify-request.ts]] for edge runtimes. Differs in only
|
|
51
|
+
* three places:
|
|
52
|
+
*
|
|
53
|
+
* 1. Imports `engineVerifyEdge` + `initEngineEdge` from `../edge`
|
|
54
|
+
* instead of `engineVerify` from `../index` (Node target).
|
|
55
|
+
* 2. Awaits `initEngineEdge()` before the engine call — async-init
|
|
56
|
+
* pattern required by the `--target web` wasm-bindgen build.
|
|
57
|
+
* 3. The final engine call is `await engineVerifyEdge(...)` rather
|
|
58
|
+
* than the synchronous `engineVerify(...)`.
|
|
59
|
+
*
|
|
60
|
+
* **The two files MUST stay in sync.** Any change to verify-request.ts
|
|
61
|
+
* (new adapter, new error-classification rule, new ContextSpec field)
|
|
62
|
+
* MUST be mirrored here. The cross-target parity test in
|
|
63
|
+
* [[__tests__/verify-request-parity.test.ts]] guards the verdict-shape
|
|
64
|
+
* invariant — both orchestrators must produce identical
|
|
65
|
+
* `VerifyResult.decision` / `engineInfo.name` on identical inputs.
|
|
66
|
+
*
|
|
67
|
+
* Cedar-1 forward-compat: same seam as the Node variant — step (5)
|
|
68
|
+
* (tenant policy eval) is the only place the PolicyEvaluator
|
|
69
|
+
* interface gets exercised. When Cedar-1 swaps implementations, this
|
|
70
|
+
* orchestrator does not change.
|
|
71
|
+
*/
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Factory — constructs a `verifyRequestEdge` closure that remembers the
|
|
75
|
+
* one-shot Argus-not-configured warning state. Use this when the
|
|
76
|
+
* host wrapper wants the startup log; call `verifyRequestEdge` directly
|
|
77
|
+
* (the loose function below) if you don't.
|
|
78
|
+
*/
|
|
79
|
+
declare function makeVerifyRequestEdge(opts: VerifyRequestOpts): (req: IncomingHttpLike) => Promise<VerifyResult>;
|
|
80
|
+
/**
|
|
81
|
+
* Single-shot async entry. Use [`makeVerifyRequestEdge`] in long-lived
|
|
82
|
+
* hosts (so the Argus warning is one-shot per process); use this
|
|
83
|
+
* loose form in tests + one-off invocations.
|
|
84
|
+
*/
|
|
85
|
+
declare function verifyRequestEdge(req: IncomingHttpLike, opts: VerifyRequestOpts): Promise<VerifyResult>;
|
|
86
|
+
|
|
87
|
+
export { IncomingHttpLike, VerifyRequestOpts, initEngineEdge, makeVerifyRequestEdge, verifyRequestEdge };
|