@kya-os/checkpoint-nextjs 1.1.4 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +190 -0
  2. package/dist/composed-policy.d.mts +108 -0
  3. package/dist/composed-policy.d.ts +108 -0
  4. package/dist/composed-policy.js +91 -0
  5. package/dist/composed-policy.mjs +85 -0
  6. package/dist/config-_nfPN3E3.d.mts +205 -0
  7. package/dist/config-kxFihzR_.d.ts +205 -0
  8. package/dist/create-middleware.js +0 -2
  9. package/dist/create-middleware.mjs +0 -2
  10. package/dist/edge-runtime-loader.js +3 -1
  11. package/dist/edge-runtime-loader.mjs +3 -1
  12. package/dist/edge-wasm-middleware.d.mts +6 -6
  13. package/dist/edge-wasm-middleware.d.ts +6 -6
  14. package/dist/index.d.mts +6 -14
  15. package/dist/index.d.ts +6 -14
  16. package/dist/index.js +162 -9
  17. package/dist/index.mjs +163 -10
  18. package/dist/middleware-edge.d.mts +7 -3
  19. package/dist/middleware-edge.d.ts +7 -3
  20. package/dist/middleware-edge.js +159 -4
  21. package/dist/middleware-edge.mjs +156 -4
  22. package/dist/middleware-node.d.mts +39 -101
  23. package/dist/middleware-node.d.ts +39 -101
  24. package/dist/middleware-node.js +166 -4
  25. package/dist/middleware-node.mjs +163 -5
  26. package/dist/middleware.d.mts +10 -1
  27. package/dist/middleware.d.ts +10 -1
  28. package/dist/middleware.js +6 -0
  29. package/dist/middleware.mjs +6 -1
  30. package/dist/nodejs-wasm-loader.d.mts +3 -4
  31. package/dist/nodejs-wasm-loader.d.ts +3 -4
  32. package/dist/nodejs-wasm-loader.js +1 -1
  33. package/dist/nodejs-wasm-loader.mjs +1 -1
  34. package/dist/signature-verifier.js +2 -2
  35. package/dist/signature-verifier.mjs +2 -2
  36. package/dist/wasm-setup.js +1 -1
  37. package/dist/wasm-setup.mjs +1 -1
  38. package/package.json +8 -11
  39. package/dist/wasm-middleware.d.mts +0 -98
  40. package/dist/wasm-middleware.d.ts +0 -98
  41. package/dist/wasm-middleware.js +0 -125
  42. package/dist/wasm-middleware.mjs +0 -121
  43. package/templates/middleware-wasm-100.ts +0 -161
@@ -1,10 +1,13 @@
1
1
  'use strict';
2
2
 
3
3
  var edge = require('@kya-os/checkpoint-wasm-runtime/orchestrator/edge');
4
- var server = require('next/server');
4
+ var policyEdge = require('@kya-os/checkpoint-wasm-runtime/policy-edge');
5
5
  var checkpointShared = require('@kya-os/checkpoint-shared');
6
+ var server = require('next/server');
7
+ var composedPolicy = require('@kya-os/checkpoint-wasm-runtime/composed-policy');
6
8
  require('@kya-os/checkpoint-wasm-runtime/orchestrator');
7
9
  var adapters = require('@kya-os/checkpoint-wasm-runtime/adapters');
10
+ var reporter = require('@kya-os/checkpoint-wasm-runtime/reporter');
8
11
 
9
12
  // src/middleware-edge.ts
10
13
  function adaptToNextResponse(rendered, req) {
@@ -55,6 +58,85 @@ function applyHeaders(res, headers) {
55
58
  res.headers.set(key, value);
56
59
  }
57
60
  }
61
+ var DEFAULT_DASHBOARD_URL = "https://kya.vouched.id";
62
+ var NOOP_LOGGER = {
63
+ shadowDivergence: () => {
64
+ },
65
+ evaluationError: () => {
66
+ }
67
+ };
68
+ function makeComposedPolicyContext(opts) {
69
+ const { projectId, fetcher } = opts;
70
+ const cache = composedPolicy.makeComposedPolicyCache({ compile: opts.compile, cacheMax: opts.cacheMax });
71
+ const logger = opts.logger ?? NOOP_LOGGER;
72
+ return {
73
+ async apply(result, path) {
74
+ const structured = { decision: result.decision, acted: false };
75
+ const policy = await fetcher.getPolicy(projectId);
76
+ const outcome = await composedPolicy.evaluateComposedPolicy({
77
+ cache,
78
+ projectId,
79
+ flags: {
80
+ policyLanguage: policy.policyLanguage,
81
+ policySourceText: policy.policySourceText,
82
+ engineEnforcementEnabled: policy.engineEnforcementEnabled,
83
+ enabled: policy.enabled
84
+ },
85
+ authorizeInput: composedPolicy.verifyResultToAuthorizeInput(result, { tenantId: projectId, path }),
86
+ baselineDecisionKind: result.decision.kind
87
+ });
88
+ if ((outcome.status === "acting" || outcome.status === "shadow") && outcome.diverged) {
89
+ logger.shadowDivergence({
90
+ projectId,
91
+ path,
92
+ engineDecision: outcome.engineDecision.kind,
93
+ structuredDecision: result.decision.kind,
94
+ detectionClass: result.detectionDetail.detectionClass.type,
95
+ verificationMethod: result.detectionDetail.verificationMethod,
96
+ confidence: result.detectionDetail.confidence,
97
+ agentName: result.detectionDetail.detectedAgent?.name
98
+ });
99
+ }
100
+ if (outcome.status === "error") {
101
+ logger.evaluationError(projectId, outcome.error);
102
+ return structured;
103
+ }
104
+ if (outcome.status === "acting") {
105
+ return { decision: outcome.engineDecision, acted: true };
106
+ }
107
+ return structured;
108
+ },
109
+ async trustedDelegationRoots() {
110
+ const policy = await fetcher.getPolicy(projectId);
111
+ return policy.trustedDelegationRoots ?? [];
112
+ }
113
+ };
114
+ }
115
+ async function resolveTrustedDelegationRootsForRequest(resolver, headers) {
116
+ if (!resolver) return void 0;
117
+ if (!checkpointShared.requestCarriesDelegationProof(headers)) return void 0;
118
+ const roots = await resolver();
119
+ return roots.length > 0 ? roots : void 0;
120
+ }
121
+ async function applyComposedPolicy(context, result, path) {
122
+ if (!context) return;
123
+ try {
124
+ const outcome = await context.apply(result, path);
125
+ if (outcome.acted) result.decision = outcome.decision;
126
+ } catch {
127
+ }
128
+ }
129
+ var consoleComposedPolicyLogger = {
130
+ shadowDivergence(info) {
131
+ console.warn("[checkpoint/composed-policy] shadow-divergence", info);
132
+ },
133
+ evaluationError(projectId, error) {
134
+ console.error(
135
+ `[checkpoint/composed-policy] evaluation failed for ${projectId}; using structured decision:`,
136
+ error
137
+ );
138
+ }
139
+ };
58
140
 
59
141
  // src/translate.ts
60
142
  async function nextRequestToHttpLike(req, opts = {}) {
@@ -97,6 +179,42 @@ function extractRemoteAddress(req) {
97
179
  }
98
180
 
99
181
  // src/middleware-node.ts
182
+ var SDK_NAME = "@kya-os/checkpoint-nextjs";
183
+ var VERSION = "1.7.0";
184
+ function buildReporter(config, runtime = "node") {
185
+ if (!config.apiKey) return null;
186
+ return reporter.makeDetectionReporter({
187
+ apiKey: config.apiKey,
188
+ baseUrl: config.baseUrl,
189
+ debug: config.debug,
190
+ // Self-identify (incl. node-vs-edge) so the dashboard can version-gate
191
+ // enforcement. Next.js EDGE composed enforcement is opt-in (needs
192
+ // `cedarWasmModule`), so the dashboard shows it as opt-in, never "Enforcing".
193
+ sdk: { name: SDK_NAME, version: VERSION, runtime }
194
+ });
195
+ }
196
+ function buildTrustedRootsResolver(config, composed) {
197
+ if (composed?.trustedDelegationRoots) {
198
+ return () => composed.trustedDelegationRoots();
199
+ }
200
+ if (!config.projectId) return null;
201
+ const fetcher = new checkpointShared.PolicyFetcher({
202
+ apiBaseUrl: config.dashboardUrl ?? config.baseUrl ?? DEFAULT_DASHBOARD_URL,
203
+ apiKey: config.apiKey,
204
+ cacheTtlSeconds: config.policyCacheTtlSeconds
205
+ });
206
+ const projectId = config.projectId;
207
+ return async () => (await fetcher.getPolicy(projectId)).trustedDelegationRoots ?? [];
208
+ }
209
+ function extractReporterContext(req) {
210
+ return {
211
+ userAgent: req.headers.get("user-agent") ?? void 0,
212
+ ipAddress: req.headers.get("x-forwarded-for")?.split(",")[0]?.trim() ?? req.headers.get("x-real-ip") ?? void 0,
213
+ path: req.nextUrl.pathname,
214
+ url: req.nextUrl.href,
215
+ method: req.method
216
+ };
217
+ }
100
218
  function buildVerifyOpts(config) {
101
219
  const overrides = config.adapters ?? {};
102
220
  return {
@@ -109,7 +227,8 @@ function buildVerifyOpts(config) {
109
227
  enforcementMode: config.enforcementMode ?? "enforce",
110
228
  reputationBaseline: config.reputationBaseline,
111
229
  argusUrl: config.argusUrl,
112
- legacyEnvelopeFallback: config.legacyEnvelopeFallback ?? false
230
+ legacyEnvelopeFallback: config.legacyEnvelopeFallback ?? false,
231
+ engineConfig: config.engineConfig
113
232
  };
114
233
  }
115
234
 
@@ -117,10 +236,27 @@ function buildVerifyOpts(config) {
117
236
  function withCheckpoint(config) {
118
237
  void edge.initEngineEdge();
119
238
  const opts = buildVerifyOpts(config);
239
+ const reporter = buildReporter(config, "edge");
240
+ const composed = buildComposedContext(config);
241
+ const trustedRootsResolver = buildTrustedRootsResolver(config, composed);
120
242
  const translateOpts = { drainJsonBody: config.drainJsonBody };
121
- return async function checkpointMiddlewareEdge(req) {
243
+ return async function checkpointMiddlewareEdge(req, event) {
122
244
  const httpLike = await nextRequestToHttpLike(req, translateOpts);
123
- const result = await edge.verifyRequestEdge(httpLike, opts);
245
+ const trustedDelegationRoots = await resolveTrustedDelegationRootsForRequest(
246
+ trustedRootsResolver,
247
+ req.headers
248
+ );
249
+ const result = await edge.verifyRequestEdge(
250
+ httpLike,
251
+ trustedDelegationRoots ? { ...opts, trustedDelegationRoots } : opts
252
+ );
253
+ await applyComposedPolicy(composed, result, req.nextUrl.pathname);
254
+ if (reporter) {
255
+ const reportPromise = reporter(result, extractReporterContext(req));
256
+ if (event) {
257
+ event.waitUntil(reportPromise);
258
+ }
259
+ }
124
260
  await dispatchOnResult(config, result, req);
125
261
  const rendered = edge.renderDecisionAsResponse(result);
126
262
  return adaptToNextResponse(rendered, req);
@@ -133,9 +269,28 @@ async function dispatchOnResult(config, result, req) {
133
269
  } catch {
134
270
  }
135
271
  }
272
+ function buildComposedContext(config) {
273
+ if (config.composedPolicyEnforcer) return config.composedPolicyEnforcer;
274
+ if (!config.projectId || !config.cedarWasmModule) return null;
275
+ policyEdge.initPolicyEvaluatorEdge(config.cedarWasmModule);
276
+ return makeComposedPolicyContext({
277
+ projectId: config.projectId,
278
+ fetcher: new checkpointShared.PolicyFetcher({
279
+ apiBaseUrl: config.dashboardUrl ?? config.baseUrl ?? DEFAULT_DASHBOARD_URL,
280
+ apiKey: config.apiKey,
281
+ cacheTtlSeconds: config.policyCacheTtlSeconds
282
+ }),
283
+ compile: (language, source) => policyEdge.evaluatePolicy(language, source),
284
+ logger: config.debug ? consoleComposedPolicyLogger : void 0
285
+ });
286
+ }
136
287
 
137
288
  Object.defineProperty(exports, "initEngineEdge", {
138
289
  enumerable: true,
139
290
  get: function () { return edge.initEngineEdge; }
140
291
  });
292
+ Object.defineProperty(exports, "initPolicyEvaluatorEdge", {
293
+ enumerable: true,
294
+ get: function () { return policyEdge.initPolicyEvaluatorEdge; }
295
+ });
141
296
  exports.withCheckpoint = withCheckpoint;
@@ -1,9 +1,13 @@
1
1
  import { initEngineEdge, verifyRequestEdge, renderDecisionAsResponse } from '@kya-os/checkpoint-wasm-runtime/orchestrator/edge';
2
2
  export { initEngineEdge } from '@kya-os/checkpoint-wasm-runtime/orchestrator/edge';
3
+ import { initPolicyEvaluatorEdge, evaluatePolicy } from '@kya-os/checkpoint-wasm-runtime/policy-edge';
4
+ export { initPolicyEvaluatorEdge } from '@kya-os/checkpoint-wasm-runtime/policy-edge';
5
+ import { PolicyFetcher, requestCarriesDelegationProof, acceptsHtml, encodeVerdictCookie, classifyResponseShape, BLOCKED_PATH, VERDICT_COOKIE_NAME } from '@kya-os/checkpoint-shared';
3
6
  import { NextResponse } from 'next/server';
4
- import { acceptsHtml, encodeVerdictCookie, classifyResponseShape, BLOCKED_PATH, VERDICT_COOKIE_NAME } from '@kya-os/checkpoint-shared';
7
+ import { makeComposedPolicyCache, evaluateComposedPolicy, verifyResultToAuthorizeInput } from '@kya-os/checkpoint-wasm-runtime/composed-policy';
5
8
  import '@kya-os/checkpoint-wasm-runtime/orchestrator';
6
9
  import { makeSystemClock, makePolicyEvaluator, makeReputationOracle, makeStatusListCache, makeDidResolver } from '@kya-os/checkpoint-wasm-runtime/adapters';
10
+ import { makeDetectionReporter } from '@kya-os/checkpoint-wasm-runtime/reporter';
7
11
 
8
12
  // src/middleware-edge.ts
9
13
  function adaptToNextResponse(rendered, req) {
@@ -54,6 +58,85 @@ function applyHeaders(res, headers) {
54
58
  res.headers.set(key, value);
55
59
  }
56
60
  }
61
+ var DEFAULT_DASHBOARD_URL = "https://kya.vouched.id";
62
+ var NOOP_LOGGER = {
63
+ shadowDivergence: () => {
64
+ },
65
+ evaluationError: () => {
66
+ }
67
+ };
68
+ function makeComposedPolicyContext(opts) {
69
+ const { projectId, fetcher } = opts;
70
+ const cache = makeComposedPolicyCache({ compile: opts.compile, cacheMax: opts.cacheMax });
71
+ const logger = opts.logger ?? NOOP_LOGGER;
72
+ return {
73
+ async apply(result, path) {
74
+ const structured = { decision: result.decision, acted: false };
75
+ const policy = await fetcher.getPolicy(projectId);
76
+ const outcome = await evaluateComposedPolicy({
77
+ cache,
78
+ projectId,
79
+ flags: {
80
+ policyLanguage: policy.policyLanguage,
81
+ policySourceText: policy.policySourceText,
82
+ engineEnforcementEnabled: policy.engineEnforcementEnabled,
83
+ enabled: policy.enabled
84
+ },
85
+ authorizeInput: verifyResultToAuthorizeInput(result, { tenantId: projectId, path }),
86
+ baselineDecisionKind: result.decision.kind
87
+ });
88
+ if ((outcome.status === "acting" || outcome.status === "shadow") && outcome.diverged) {
89
+ logger.shadowDivergence({
90
+ projectId,
91
+ path,
92
+ engineDecision: outcome.engineDecision.kind,
93
+ structuredDecision: result.decision.kind,
94
+ detectionClass: result.detectionDetail.detectionClass.type,
95
+ verificationMethod: result.detectionDetail.verificationMethod,
96
+ confidence: result.detectionDetail.confidence,
97
+ agentName: result.detectionDetail.detectedAgent?.name
98
+ });
99
+ }
100
+ if (outcome.status === "error") {
101
+ logger.evaluationError(projectId, outcome.error);
102
+ return structured;
103
+ }
104
+ if (outcome.status === "acting") {
105
+ return { decision: outcome.engineDecision, acted: true };
106
+ }
107
+ return structured;
108
+ },
109
+ async trustedDelegationRoots() {
110
+ const policy = await fetcher.getPolicy(projectId);
111
+ return policy.trustedDelegationRoots ?? [];
112
+ }
113
+ };
114
+ }
115
+ async function resolveTrustedDelegationRootsForRequest(resolver, headers) {
116
+ if (!resolver) return void 0;
117
+ if (!requestCarriesDelegationProof(headers)) return void 0;
118
+ const roots = await resolver();
119
+ return roots.length > 0 ? roots : void 0;
120
+ }
121
+ async function applyComposedPolicy(context, result, path) {
122
+ if (!context) return;
123
+ try {
124
+ const outcome = await context.apply(result, path);
125
+ if (outcome.acted) result.decision = outcome.decision;
126
+ } catch {
127
+ }
128
+ }
129
+ var consoleComposedPolicyLogger = {
130
+ shadowDivergence(info) {
131
+ console.warn("[checkpoint/composed-policy] shadow-divergence", info);
132
+ },
133
+ evaluationError(projectId, error) {
134
+ console.error(
135
+ `[checkpoint/composed-policy] evaluation failed for ${projectId}; using structured decision:`,
136
+ error
137
+ );
138
+ }
139
+ };
57
140
 
58
141
  // src/translate.ts
59
142
  async function nextRequestToHttpLike(req, opts = {}) {
@@ -96,6 +179,42 @@ function extractRemoteAddress(req) {
96
179
  }
97
180
 
98
181
  // src/middleware-node.ts
182
+ var SDK_NAME = "@kya-os/checkpoint-nextjs";
183
+ var VERSION = "1.7.0";
184
+ function buildReporter(config, runtime = "node") {
185
+ if (!config.apiKey) return null;
186
+ return makeDetectionReporter({
187
+ apiKey: config.apiKey,
188
+ baseUrl: config.baseUrl,
189
+ debug: config.debug,
190
+ // Self-identify (incl. node-vs-edge) so the dashboard can version-gate
191
+ // enforcement. Next.js EDGE composed enforcement is opt-in (needs
192
+ // `cedarWasmModule`), so the dashboard shows it as opt-in, never "Enforcing".
193
+ sdk: { name: SDK_NAME, version: VERSION, runtime }
194
+ });
195
+ }
196
+ function buildTrustedRootsResolver(config, composed) {
197
+ if (composed?.trustedDelegationRoots) {
198
+ return () => composed.trustedDelegationRoots();
199
+ }
200
+ if (!config.projectId) return null;
201
+ const fetcher = new PolicyFetcher({
202
+ apiBaseUrl: config.dashboardUrl ?? config.baseUrl ?? DEFAULT_DASHBOARD_URL,
203
+ apiKey: config.apiKey,
204
+ cacheTtlSeconds: config.policyCacheTtlSeconds
205
+ });
206
+ const projectId = config.projectId;
207
+ return async () => (await fetcher.getPolicy(projectId)).trustedDelegationRoots ?? [];
208
+ }
209
+ function extractReporterContext(req) {
210
+ return {
211
+ userAgent: req.headers.get("user-agent") ?? void 0,
212
+ ipAddress: req.headers.get("x-forwarded-for")?.split(",")[0]?.trim() ?? req.headers.get("x-real-ip") ?? void 0,
213
+ path: req.nextUrl.pathname,
214
+ url: req.nextUrl.href,
215
+ method: req.method
216
+ };
217
+ }
99
218
  function buildVerifyOpts(config) {
100
219
  const overrides = config.adapters ?? {};
101
220
  return {
@@ -108,7 +227,8 @@ function buildVerifyOpts(config) {
108
227
  enforcementMode: config.enforcementMode ?? "enforce",
109
228
  reputationBaseline: config.reputationBaseline,
110
229
  argusUrl: config.argusUrl,
111
- legacyEnvelopeFallback: config.legacyEnvelopeFallback ?? false
230
+ legacyEnvelopeFallback: config.legacyEnvelopeFallback ?? false,
231
+ engineConfig: config.engineConfig
112
232
  };
113
233
  }
114
234
 
@@ -116,10 +236,27 @@ function buildVerifyOpts(config) {
116
236
  function withCheckpoint(config) {
117
237
  void initEngineEdge();
118
238
  const opts = buildVerifyOpts(config);
239
+ const reporter = buildReporter(config, "edge");
240
+ const composed = buildComposedContext(config);
241
+ const trustedRootsResolver = buildTrustedRootsResolver(config, composed);
119
242
  const translateOpts = { drainJsonBody: config.drainJsonBody };
120
- return async function checkpointMiddlewareEdge(req) {
243
+ return async function checkpointMiddlewareEdge(req, event) {
121
244
  const httpLike = await nextRequestToHttpLike(req, translateOpts);
122
- const result = await verifyRequestEdge(httpLike, opts);
245
+ const trustedDelegationRoots = await resolveTrustedDelegationRootsForRequest(
246
+ trustedRootsResolver,
247
+ req.headers
248
+ );
249
+ const result = await verifyRequestEdge(
250
+ httpLike,
251
+ trustedDelegationRoots ? { ...opts, trustedDelegationRoots } : opts
252
+ );
253
+ await applyComposedPolicy(composed, result, req.nextUrl.pathname);
254
+ if (reporter) {
255
+ const reportPromise = reporter(result, extractReporterContext(req));
256
+ if (event) {
257
+ event.waitUntil(reportPromise);
258
+ }
259
+ }
123
260
  await dispatchOnResult(config, result, req);
124
261
  const rendered = renderDecisionAsResponse(result);
125
262
  return adaptToNextResponse(rendered, req);
@@ -132,5 +269,20 @@ async function dispatchOnResult(config, result, req) {
132
269
  } catch {
133
270
  }
134
271
  }
272
+ function buildComposedContext(config) {
273
+ if (config.composedPolicyEnforcer) return config.composedPolicyEnforcer;
274
+ if (!config.projectId || !config.cedarWasmModule) return null;
275
+ initPolicyEvaluatorEdge(config.cedarWasmModule);
276
+ return makeComposedPolicyContext({
277
+ projectId: config.projectId,
278
+ fetcher: new PolicyFetcher({
279
+ apiBaseUrl: config.dashboardUrl ?? config.baseUrl ?? DEFAULT_DASHBOARD_URL,
280
+ apiKey: config.apiKey,
281
+ cacheTtlSeconds: config.policyCacheTtlSeconds
282
+ }),
283
+ compile: (language, source) => evaluatePolicy(language, source),
284
+ logger: config.debug ? consoleComposedPolicyLogger : void 0
285
+ });
286
+ }
135
287
 
136
288
  export { withCheckpoint };
@@ -1,99 +1,12 @@
1
+ import * as _kya_os_checkpoint_wasm_runtime_engine from '@kya-os/checkpoint-wasm-runtime/engine';
1
2
  import * as _kya_os_checkpoint_wasm_runtime_adapters from '@kya-os/checkpoint-wasm-runtime/adapters';
2
- import { DidResolverAdapter, StatusListCacheAdapter, ReputationOracleAdapter, PolicyEvaluatorAdapter } from '@kya-os/checkpoint-wasm-runtime/adapters';
3
- import { NextRequest, NextResponse } from 'next/server';
4
- import { EnforcementMode, VerifyResult } from '@kya-os/checkpoint-wasm-runtime/engine';
3
+ import { NextRequest, NextFetchEvent, NextResponse } from 'next/server';
4
+ import { DetectionReporter, ReporterContext } from '@kya-os/checkpoint-wasm-runtime/reporter';
5
+ import { C as CheckpointConfig } from './config-_nfPN3E3.mjs';
6
+ import { ComposedPolicyContext, TrustedDelegationRootsResolver } from './composed-policy.mjs';
7
+ import '@kya-os/checkpoint-wasm-runtime/composed-policy';
8
+ import '@kya-os/checkpoint-shared';
5
9
 
6
- /**
7
- * Configuration for `withCheckpoint`.
8
- *
9
- * The new minimal shape Phase D's middleware needs. Legacy
10
- * `AgentShieldMiddlewareConfig` (from `./api-middleware`) remains
11
- * exported during the deprecation window — see D.4 cutover.
12
- */
13
- interface CheckpointConfig {
14
- /**
15
- * Tenant identifier — typically the customer's dashboard hostname
16
- * (e.g. `acme.checkpoint.example`). The PolicyEvaluator uses this
17
- * to look up tenant policy from the dashboard.
18
- */
19
- tenantHost: string;
20
- /**
21
- * `'enforce'` (default) blocks; `'observe'` passes everything
22
- * through with `X-Checkpoint-Would-Have-Been` headers. Per Phase 0.2.
23
- */
24
- enforcementMode?: EnforcementMode;
25
- /**
26
- * Argus reputation oracle base URL. Omit to use the trust-by-default
27
- * baseline (reputation defaults to 1.0; orchestrator logs a one-shot
28
- * warning at first request).
29
- */
30
- argusUrl?: string;
31
- /**
32
- * Dashboard base URL for the PolicyEvaluator to fetch tenant policy
33
- * from. Omit to use the open-by-default tenant policy.
34
- */
35
- dashboardUrl?: string;
36
- /**
37
- * Returned to the PolicyEvaluator for anonymous requests (no agent
38
- * DID). Default 1.0 (trust-by-default).
39
- */
40
- reputationBaseline?: number;
41
- /**
42
- * Pre-built adapter instances. Production deployments use the
43
- * factory-built defaults from `@kya-os/checkpoint-wasm-runtime/adapters`;
44
- * tests use stubs. The factory composes any provided overrides over
45
- * defaults — partial overrides are supported.
46
- */
47
- adapters?: Partial<{
48
- didResolver: DidResolverAdapter;
49
- statusListCache: StatusListCacheAdapter;
50
- reputationOracle: ReputationOracleAdapter;
51
- policyEvaluator: PolicyEvaluatorAdapter;
52
- }>;
53
- /**
54
- * Optional callback for the post-verdict path — fires after every
55
- * verification, regardless of permit/block, with the full
56
- * `VerifyResult`. Use for logging, dashboards, telemetry. Errors
57
- * thrown here are swallowed so user code can't break the middleware
58
- * response.
59
- */
60
- onResult?: (result: VerifyResult, req: NextRequest) => void | Promise<void>;
61
- /**
62
- * Accept legacy `KYA-Delegation`-header envelope form alongside the
63
- * canonical `_meta.proof.jws` body form. Default `false`.
64
- *
65
- * **When to enable** — customers whose agents pre-date Envelope-1
66
- * (#2537) and ship MCP-I proofs as `{protected,payload,signature}`
67
- * JSON in a `KYA-Delegation` HTTP header. Post-Envelope-1 agents
68
- * ship compact JWS in the request body's `_meta.proof.jws` field;
69
- * those don't need this flag.
70
- *
71
- * Forwarded to the orchestrator's `VerifyRequestOpts.legacyEnvelopeFallback`.
72
- * Both transports (header + body) are honored when this is `true`;
73
- * the orchestrator's detection order is body first, then header
74
- * (`packages/checkpoint-wasm-runtime/src/engine/orchestrator/build-agent-request.ts`).
75
- *
76
- * SDK-Envelope-Plumbing-1 (#2594). Added in `@kya-os/checkpoint-nextjs@1.1.0`.
77
- */
78
- legacyEnvelopeFallback?: boolean;
79
- /**
80
- * Read the request body when `content-type` is `application/json` so
81
- * the orchestrator can extract an MCP-I envelope from
82
- * `_meta.proof.jws`. Default `true`.
83
- *
84
- * **When to disable** — streaming middlewares that can't tolerate
85
- * the `req.clone()` memory overhead (one full-body copy is buffered
86
- * during the read). For those, set `false` and route MCP-I
87
- * envelopes through the `KYA-Delegation` header transport instead
88
- * (requires `legacyEnvelopeFallback: true`).
89
- *
90
- * The clone preserves `req.body` for downstream handlers — disabling
91
- * is a performance optimization, not a correctness fix.
92
- *
93
- * SDK-Envelope-Plumbing-1 (#2594). Added in `@kya-os/checkpoint-nextjs@1.1.0`.
94
- */
95
- drainJsonBody?: boolean;
96
- }
97
10
  /**
98
11
  * Build the Checkpoint middleware. Returns a function `(req) => NextResponse`
99
12
  * suitable for `export default withCheckpoint({...})` in `middleware.ts`.
@@ -103,23 +16,48 @@ interface CheckpointConfig {
103
16
  * `verifyRequest`, and translates the verdict to `NextResponse`. No
104
17
  * verification logic lives in this file.
105
18
  */
106
- declare function withCheckpoint(config: CheckpointConfig): (req: NextRequest) => Promise<NextResponse>;
19
+ declare function withCheckpoint(config: CheckpointConfig): (req: NextRequest, event?: NextFetchEvent) => Promise<NextResponse>;
20
+ /**
21
+ * Installed SDK version, self-reported to the detection reporter so the
22
+ * dashboard can version-gate "composed policy enforces here". MUST equal
23
+ * `package.json` version — pinned by a unit test (the old hardcoded `0.1.0` had
24
+ * drifted). Re-exported as `VERSION` from the package index.
25
+ */
26
+ declare const VERSION = "1.7.0";
27
+ declare function buildReporter(config: CheckpointConfig, runtime?: 'node' | 'edge'): DetectionReporter | null;
28
+ /**
29
+ * Build the per-factory trusted-delegation-roots resolver (P2 / DR-1). Root
30
+ * pinning is a security concern INDEPENDENT of composed Cedar enforcement, so it
31
+ * must resolve wherever a `projectId` exists — including Edge setups that never
32
+ * wire `cedarWasmModule` (where `buildComposedContext` returns null). Prefers the
33
+ * composed context's accessor (reuses its cached fetcher / honors an injected
34
+ * enforcer); otherwise falls back to a `projectId`-only policy fetch. Returns
35
+ * `null` when no source is configured (no roots → engine open default).
36
+ */
37
+ declare function buildTrustedRootsResolver(config: CheckpointConfig, composed: ComposedPolicyContext | null): TrustedDelegationRootsResolver | null;
38
+ /**
39
+ * Pull the request context the dashboard's `/api/v1/log-detection`
40
+ * endpoint expects out of a `NextRequest`. Works under both Node and
41
+ * Edge runtimes — no runtime-specific APIs.
42
+ */
43
+ declare function extractReporterContext(req: NextRequest): ReporterContext;
107
44
  /**
108
45
  * Compose adapter defaults with caller-supplied overrides. Factored
109
46
  * out so the Edge entry (which uses the same composition) can reuse
110
47
  * the shape.
111
48
  */
112
49
  declare function buildVerifyOpts(config: CheckpointConfig): {
113
- didResolver: DidResolverAdapter;
114
- statusListCache: StatusListCacheAdapter;
115
- reputationOracle: ReputationOracleAdapter;
116
- policyEvaluator: PolicyEvaluatorAdapter;
50
+ didResolver: _kya_os_checkpoint_wasm_runtime_adapters.DidResolverAdapter;
51
+ statusListCache: _kya_os_checkpoint_wasm_runtime_adapters.StatusListCacheAdapter;
52
+ reputationOracle: _kya_os_checkpoint_wasm_runtime_adapters.ReputationOracleAdapter;
53
+ policyEvaluator: _kya_os_checkpoint_wasm_runtime_adapters.PolicyEvaluatorAdapter;
117
54
  clock: _kya_os_checkpoint_wasm_runtime_adapters.ClockAdapter;
118
55
  tenantHost: string;
119
- enforcementMode: EnforcementMode;
56
+ enforcementMode: _kya_os_checkpoint_wasm_runtime_engine.EnforcementMode;
120
57
  reputationBaseline: number | undefined;
121
58
  argusUrl: string | undefined;
122
59
  legacyEnvelopeFallback: boolean;
60
+ engineConfig: _kya_os_checkpoint_wasm_runtime_engine.EngineConfig | undefined;
123
61
  };
124
62
 
125
- export { type CheckpointConfig, buildVerifyOpts as _buildVerifyOpts, withCheckpoint };
63
+ export { CheckpointConfig, VERSION, buildReporter as _buildReporter, buildTrustedRootsResolver as _buildTrustedRootsResolver, buildVerifyOpts as _buildVerifyOpts, extractReporterContext as _extractReporterContext, withCheckpoint };