@frontmcp/adapters 1.11.1-rc.1 → 1.11.1

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.
@@ -1,5 +1,6 @@
1
+ import { type ReplayNonceStore } from './replay-nonce-store';
1
2
  /** Why a check refused: also the `reason` label of `frontmcp_skills_replay_rejects_total`. */
2
- export type ReplayRejectCode = 'invalid_timestamp' | 'invalid_nonce' | 'outside_window' | 'nonce_replay';
3
+ export type ReplayRejectCode = 'invalid_timestamp' | 'invalid_nonce' | 'outside_window' | 'nonce_replay' | 'store_unavailable';
3
4
  export interface ReplayCheckResult {
4
5
  ok: boolean;
5
6
  reason?: string;
@@ -19,8 +20,13 @@ export interface ReplayGuardTelemetry {
19
20
  export interface WebhookReplayGuardOptions {
20
21
  /** Allowed clock skew window in ms (default 300_000 = 5min). */
21
22
  windowMs?: number;
22
- /** Max nonces tracked simultaneously (default 5_000). */
23
+ /** Max nonces the default in-memory store tracks simultaneously (default 5_000). */
23
24
  capacity?: number;
25
+ /**
26
+ * Where the accepted nonces are recorded. Default: this process's memory, which replicas and Worker isolates don't
27
+ * share. Give every instance that serves the server the same store.
28
+ */
29
+ store?: ReplayNonceStore;
24
30
  /**
25
31
  * Optional telemetry hook. When provided, every `check()` rejection is
26
32
  * recorded against `frontmcp_skills_replay_rejects_total` with a low-cardinality
@@ -30,8 +36,7 @@ export interface WebhookReplayGuardOptions {
30
36
  }
31
37
  export declare class WebhookReplayGuard {
32
38
  private readonly windowMs;
33
- private readonly capacity;
34
- private readonly seen;
39
+ private readonly store;
35
40
  private now;
36
41
  private readonly rejectsCounter;
37
42
  private readonly checksCounter;
@@ -39,17 +44,12 @@ export declare class WebhookReplayGuard {
39
44
  /** For tests: override the time source. */
40
45
  setNowProvider(fn: () => number): void;
41
46
  /**
42
- * Check that a (timestamp, nonce) pair is fresh and unseen. Returns ok=false
43
- * if the timestamp is outside the freshness window or the nonce has already
44
- * been observed within that window.
47
+ * Check that a (timestamp, nonce) pair is fresh and unseen, and record the nonce. Returns ok=false if the timestamp
48
+ * is outside the freshness window, the nonce was already recorded within that window, or the store failed.
45
49
  */
46
50
  check(args: {
47
51
  timestampMs: number;
48
52
  nonce: string;
49
- }): ReplayCheckResult;
50
- /** Test/maintenance helper: drop expired entries proactively. */
51
- prune(): number;
52
- /** Inspect: number of nonces currently tracked. */
53
- get size(): number;
53
+ }): Promise<ReplayCheckResult>;
54
54
  }
55
55
  //# sourceMappingURL=webhook-replay-guard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"webhook-replay-guard.d.ts","sourceRoot":"","sources":["../../../src/skills/security/webhook-replay-guard.ts"],"names":[],"mappings":"AAMA,8FAA8F;AAC9F,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,GAAG,eAAe,GAAG,gBAAgB,GAAG,cAAc,CAAC;AAEzG,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,gBAAgB,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CAC7D;AACD,MAAM,WAAW,oBAAoB;IACnC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAAC;CACvE;AAED,MAAM,WAAW,yBAAyB;IACxC,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,oBAAoB,CAAC;CAClC;AAKD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA6B;IAClD,OAAO,CAAC,GAAG,CAA0B;IACrC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiC;IAChE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiC;gBAEnD,OAAO,GAAE,yBAA8B;IAyBnD,2CAA2C;IAC3C,cAAc,CAAC,EAAE,EAAE,MAAM,MAAM,GAAG,IAAI;IAItC;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,iBAAiB;IA0DtE,iEAAiE;IACjE,KAAK,IAAI,MAAM;IAYf,mDAAmD;IACnD,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
1
+ {"version":3,"file":"webhook-replay-guard.d.ts","sourceRoot":"","sources":["../../../src/skills/security/webhook-replay-guard.ts"],"names":[],"mappings":"AAMA,OAAO,EAA0B,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAErF,8FAA8F;AAC9F,MAAM,MAAM,gBAAgB,GACxB,mBAAmB,GACnB,eAAe,GACf,gBAAgB,GAChB,cAAc,GACd,mBAAmB,CAAC;AAExB,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,gBAAgB,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CAC7D;AACD,MAAM,WAAW,oBAAoB;IACnC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAAC;CACvE;AAED,MAAM,WAAW,yBAAyB;IACxC,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB;;;;OAIG;IACH,SAAS,CAAC,EAAE,oBAAoB,CAAC;CAClC;AAID,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IACzC,OAAO,CAAC,GAAG,CAA0B;IACrC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiC;IAChE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiC;gBAEnD,OAAO,GAAE,yBAA8B;IAwBnD,2CAA2C;IAC3C,cAAc,CAAC,EAAE,EAAE,MAAM,MAAM,GAAG,IAAI;IAItC;;;OAGG;IACG,KAAK,CAAC,IAAI,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAiCtF"}
@@ -1,4 +1,5 @@
1
1
  import { z } from '@frontmcp/lazy-zod';
2
+ import type { StorageConfig } from '@frontmcp/utils';
2
3
  export declare const staticSourceSchema: import("@frontmcp/lazy-zod").ZodObject<{
3
4
  type: import("@frontmcp/lazy-zod").ZodLiteral<"static">;
4
5
  path: import("@frontmcp/lazy-zod").ZodString;
@@ -17,6 +18,9 @@ export declare const saasSourceSchema: import("@frontmcp/lazy-zod").ZodObject<{
17
18
  expectedAudience: import("@frontmcp/lazy-zod").ZodString;
18
19
  pollIntervalMs: import("@frontmcp/lazy-zod").ZodDefault<import("@frontmcp/lazy-zod").ZodNumber>;
19
20
  enableWebhook: import("@frontmcp/lazy-zod").ZodDefault<import("@frontmcp/lazy-zod").ZodBoolean>;
21
+ requirePushBodyDigest: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodBoolean>;
22
+ allowRollback: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodBoolean>;
23
+ pushReplayStorage: import("@frontmcp/lazy-zod").ZodOptional<import("zod").ZodCustom<StorageConfig, StorageConfig>>;
20
24
  jwksUrl: import("@frontmcp/lazy-zod").ZodString;
21
25
  expectedIssuer: import("@frontmcp/lazy-zod").ZodString;
22
26
  }, import("zod/v4/core").$strip>;
@@ -40,6 +44,9 @@ export declare const bundleSourceSchema: import("@frontmcp/lazy-zod").ZodDiscrim
40
44
  expectedAudience: import("@frontmcp/lazy-zod").ZodString;
41
45
  pollIntervalMs: import("@frontmcp/lazy-zod").ZodDefault<import("@frontmcp/lazy-zod").ZodNumber>;
42
46
  enableWebhook: import("@frontmcp/lazy-zod").ZodDefault<import("@frontmcp/lazy-zod").ZodBoolean>;
47
+ requirePushBodyDigest: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodBoolean>;
48
+ allowRollback: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodBoolean>;
49
+ pushReplayStorage: import("@frontmcp/lazy-zod").ZodOptional<import("zod").ZodCustom<StorageConfig, StorageConfig>>;
43
50
  jwksUrl: import("@frontmcp/lazy-zod").ZodString;
44
51
  expectedIssuer: import("@frontmcp/lazy-zod").ZodString;
45
52
  }, import("zod/v4/core").$strip>, import("@frontmcp/lazy-zod").ZodObject<{
@@ -1 +1 @@
1
- {"version":3,"file":"source-options.d.ts","sourceRoot":"","sources":["../../src/skills/source-options.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,CAAC,EAAE,MAAM,oBAAoB,CAAC;AAkBvC,eAAO,MAAM,kBAAkB;;;;gCAM7B,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;gCAiB1B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;gCA2B3B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;gCAS7B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;0CAK7B,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AACrE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAC/D,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AACjE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AACrE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAIrE,eAAO,MAAM,kBAAkB;;;;;;;gCAO7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
1
+ {"version":3,"file":"source-options.d.ts","sourceRoot":"","sources":["../../src/skills/source-options.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,CAAC,EAAE,MAAM,oBAAoB,CAAC;AACvC,OAAO,KAAK,EAAE,aAAa,EAAe,MAAM,iBAAiB,CAAC;AA0ClE,eAAO,MAAM,kBAAkB;;;;gCAM7B,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;gCAiB1B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;gCA4C3B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;gCAS7B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;0CAK7B,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AACrE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAC/D,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AACjE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AACrE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAIrE,eAAO,MAAM,kBAAkB;;;;;;;gCAO7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
@@ -2,10 +2,10 @@ import type { FrontMcpLogger } from '@frontmcp/sdk';
2
2
  import type { BundleSourceOptions } from '../source-options';
3
3
  import { InlineSource } from './inline.source';
4
4
  import { NpmSource } from './npm.source';
5
- import { SaasPullSource, SaasPushRefusedError } from './saas-pull.source';
5
+ import { PUSH_BODY_DIGEST_CLAIM, pushBodyDigest, SaasJwksUnavailableError, SaasPullSource, SaasPullTokenRejectedError, SaasPushRefusedError, tokenFailureOf } from './saas-pull.source';
6
6
  import type { BundleSourceDeps, SkillBundleSource } from './skill-bundle-source.interface';
7
7
  import { StaticSource } from './static.source';
8
- export { StaticSource, NpmSource, SaasPullSource, SaasPushRefusedError, InlineSource };
9
- export type { BundleCacheStore, BundlePushReceiver, BundleSourceDeps, BundleSourceListener, SkillBundleSource, } from './skill-bundle-source.interface';
8
+ export { StaticSource, NpmSource, SaasPullSource, SaasPullTokenRejectedError, SaasJwksUnavailableError, SaasPushRefusedError, tokenFailureOf, PUSH_BODY_DIGEST_CLAIM, pushBodyDigest, InlineSource, };
9
+ export type { BundleCacheStore, BundleOrigin, BundlePullFailureListener, BundlePushReceiver, BundleSourceDeps, BundleSourceListener, BundleTokenFailure, SkillBundleSource, } from './skill-bundle-source.interface';
10
10
  export declare function createBundleSource(source: BundleSourceOptions, cacheDir: string | undefined, logger: FrontMcpLogger, deps?: BundleSourceDeps): SkillBundleSource;
11
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/skills/sources/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,oBAAoB,EAAE,YAAY,EAAE,CAAC;AACvF,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,iCAAiC,CAAC;AAEzC,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,mBAAmB,EAC3B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,MAAM,EAAE,cAAc,EAGtB,IAAI,CAAC,EAAE,gBAAgB,GACtB,iBAAiB,CAWnB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/skills/sources/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,wBAAwB,EACxB,cAAc,EACd,0BAA0B,EAC1B,oBAAoB,EACpB,cAAc,EACf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EACL,YAAY,EACZ,SAAS,EACT,cAAc,EACd,0BAA0B,EAC1B,wBAAwB,EACxB,oBAAoB,EACpB,cAAc,EACd,sBAAsB,EACtB,cAAc,EACd,YAAY,GACb,CAAC;AACF,YAAY,EACV,gBAAgB,EAChB,YAAY,EACZ,yBAAyB,EACzB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,iCAAiC,CAAC;AAEzC,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,mBAAmB,EAC3B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,MAAM,EAAE,cAAc,EAGtB,IAAI,CAAC,EAAE,gBAAgB,GACtB,iBAAiB,CAWnB"}
@@ -1,40 +1,63 @@
1
1
  import type { FrontMcpLogger } from '@frontmcp/sdk';
2
2
  import type { ResolvedBundle } from '../bundle/bundle.types';
3
3
  import type { SaasSourceOptions } from '../source-options';
4
- import type { BundlePushReceiver, BundleSourceDeps, BundleSourceListener, SkillBundleSource } from './skill-bundle-source.interface';
4
+ import type { BundlePullFailureListener, BundlePushReceiver, BundleSourceDeps, BundleSourceListener, BundleTokenFailure, SkillBundleSource } from './skill-bundle-source.interface';
5
5
  /**
6
6
  * The pinned pull token failed verification against `jwksUrl`, `expectedIssuer`
7
7
  * or `expectedAudience`. Unlike an outage, this never falls back to a cached
8
8
  * bundle: the configured SaaS is not the one the server was set up to trust.
9
9
  */
10
10
  export declare class SaasPullTokenRejectedError extends Error {
11
- constructor(reason: string);
11
+ readonly tokenFailure: BundleTokenFailure;
12
+ constructor(reason: string, tokenFailure: BundleTokenFailure);
13
+ }
14
+ /** The issuer's JWKS could not be read, or holds no usable signing key: no token can be checked, an outage. */
15
+ export declare class SaasJwksUnavailableError extends Error {
16
+ readonly tokenFailure = "jwks_unavailable";
17
+ constructor(message: string, options?: ErrorOptions);
12
18
  }
13
19
  /**
14
- * The token of a pushed bundle was refused: it fails the checks the pull token passes (`invalid-token`), or a push
15
- * already used it (`replayed`). The pushed bundle is not applied.
20
+ * The token of a pushed bundle was refused: it fails the checks the pull token passes (`invalid-token`), a push
21
+ * already used it (`replayed`), or the replay store could not record its `jti` (`replay-unchecked`). The pushed
22
+ * bundle is not applied.
16
23
  */
17
24
  export declare class SaasPushRefusedError extends Error {
18
- readonly refusal: 'invalid-token' | 'replayed';
19
- constructor(refusal: 'invalid-token' | 'replayed', reason: string);
25
+ readonly refusal: 'invalid-token' | 'replayed' | 'replay-unchecked';
26
+ /** The check that refused the token, when the issuer's checks did rather than the replay guard. */
27
+ readonly tokenFailure?: BundleTokenFailure | undefined;
28
+ constructor(refusal: 'invalid-token' | 'replayed' | 'replay-unchecked', reason: string,
29
+ /** The check that refused the token, when the issuer's checks did rather than the replay guard. */
30
+ tokenFailure?: BundleTokenFailure | undefined);
20
31
  }
32
+ /** The token check a pull or push failed on, from the error it threw; undefined for any other failure. */
33
+ export declare function tokenFailureOf(error: unknown): BundleTokenFailure | undefined;
34
+ /** The push token claim that binds it to the body it came with: {@link pushBodyDigest} of that body. */
35
+ export declare const PUSH_BODY_DIGEST_CLAIM = "body_sha256";
36
+ /** The `body_sha256` claim a push token carries for `body`: the base64url SHA-256 of its exact bytes, unpadded. */
37
+ export declare function pushBodyDigest(body: string | Uint8Array): string;
21
38
  /**
22
39
  * Pulls bundles from a configured SaaS endpoint via authenticated HTTPS.
23
40
  *
24
41
  * Boot semantics:
25
42
  * - Always attempts a fresh pull on `start()`.
26
- * - If the pull fails AND a cached bundle exists on disk, falls back to it
27
- * and emits a warning. This prevents a SaaS outage at boot from killing
28
- * the customer's MCP server. The cache holds the last bundle the plugin
29
- * applied ({@link SaasPullSource.keepBundle}): a pulled bundle that fails
30
- * its signature or apply never replaces it.
43
+ * - If the pull fails AND a cached bundle exists on disk, falls back to it,
44
+ * emits a warning, and hands it to its listeners with why the pull failed.
45
+ * This prevents a SaaS outage at boot from killing the customer's MCP
46
+ * server. The cache holds the last bundle the plugin applied
47
+ * ({@link SaasPullSource.keepBundle}): a pulled bundle that fails its
48
+ * signature or apply never replaces it, and the plugin doesn't write back
49
+ * the cached bundle it serves. While no bundle serves, the plugin reads the
50
+ * cache ({@link SaasPullSource.keptBundle}), and serves it in place of a
51
+ * pulled bundle that is older or refused.
31
52
  * - If both pull and cache fail, `start()` throws. Polling still starts, so a
32
53
  * later pull that succeeds loads the bundle.
33
54
  *
34
55
  * Refresh: poll on `pollIntervalMs`. Single-flight per source — overlapping
35
- * polls are skipped, never queued. With `enableWebhook` the source also takes
36
- * pushed bundles ({@link SaasPullSource.verifyPushToken}): the plugin serves
37
- * them at `POST /__skilled_openapi/push`.
56
+ * polls are skipped, never queued. A poll that fails is logged and reported to
57
+ * the {@link SaasPullSource.onPullFailure} listeners. With `enableWebhook` the
58
+ * source also takes pushed bundles ({@link SaasPullSource.verifyPushToken}):
59
+ * the plugin serves them at `POST /__skilled_openapi/push`, and a push token
60
+ * with a `body_sha256` claim is good only for the body it was issued for.
38
61
  *
39
62
  * Before every pull the pinned `authToken` is verified: it must be a JWT signed
40
63
  * by a key in the issuer's JWKS (`jwksUrl`), with `iss` equal to
@@ -45,7 +68,8 @@ export declare class SaasPushRefusedError extends Error {
45
68
  * other pull failure (the cache fallback still applies).
46
69
  *
47
70
  * NOTE: Bundle signature verification is applied by the bundle-sync service
48
- * before the bundle becomes active.
71
+ * before the bundle becomes active, and so is the version order: the source is
72
+ * {@link SaasPullSource.forwardOnly}, so a bundle older than the served one is refused.
49
73
  */
50
74
  export declare class SaasPullSource implements SkillBundleSource, BundlePushReceiver {
51
75
  private readonly options;
@@ -54,6 +78,7 @@ export declare class SaasPullSource implements SkillBundleSource, BundlePushRece
54
78
  private readonly deps;
55
79
  readonly id: string;
56
80
  private listeners;
81
+ private pullFailureListeners;
57
82
  private pollHandle;
58
83
  /** The pull running now, from start, a poll or a refresh; only one runs at a time. */
59
84
  private inFlightPull;
@@ -62,22 +87,35 @@ export declare class SaasPullSource implements SkillBundleSource, BundlePushRece
62
87
  private readonly replayGuard?;
63
88
  private pushSigningKeys?;
64
89
  private pushSigningKeysLoading?;
90
+ private warnedOfUnboundPushToken;
65
91
  constructor(options: SaasSourceOptions, cacheDir: string | undefined, logger: FrontMcpLogger, deps?: BundleSourceDeps);
92
+ /** The store an injected `pushReplayStore` or the `pushReplayStorage` option names; none keeps the jtis in memory. */
93
+ private pushReplayStore;
66
94
  /** This source, when `enableWebhook` is on: it then takes bundles pushed to the server. */
67
95
  get push(): BundlePushReceiver | undefined;
96
+ /** A pulled or pushed bundle older than the one being served is not applied, unless `allowRollback` is on. */
97
+ get forwardOnly(): boolean;
68
98
  /**
69
99
  * Check the token of a pushed bundle: by the rules the pull token passes (a key in `jwksUrl`, `iss`, `aud`,
70
- * `resource`, expiry), then by the replay guard, so its `iat` must be within five minutes and its `jti` unused.
71
- * Throws {@link SaasPushRefusedError}, or a plain Error when the JWKS can't be read.
100
+ * `resource`, expiry), then against `body`, the exact bytes of the request body ({@link PUSH_BODY_DIGEST_CLAIM}),
101
+ * then by the replay guard, so its `iat` must be within five minutes and its `jti` unused by every instance sharing
102
+ * the replay store. A token refused for its body leaves its `jti` unused. Throws {@link SaasPushRefusedError}, or
103
+ * {@link SaasJwksUnavailableError} when the JWKS can't be read.
72
104
  */
73
- verifyPushToken(token: string): Promise<void>;
105
+ verifyPushToken(token: string, body: Uint8Array): Promise<void>;
106
+ /** Refuse a push whose body isn't the one its token was issued for, or, with `requirePushBodyDigest`, unbound. */
107
+ private checkPushBody;
74
108
  /** Keep a bundle the plugin applied, pulled or pushed, as the last good one a start falls back to. */
75
109
  keepBundle(bundle: ResolvedBundle): Promise<void>;
110
+ /** The last good bundle {@link keepBundle} kept, schema-checked as a pull is; undefined when there is none. */
111
+ keptBundle(): Promise<ResolvedBundle | undefined>;
76
112
  start(): Promise<void>;
77
113
  private pullAtStart;
78
114
  /** Run `pull` as the one pull in flight, so a start, a poll and a refresh never pull at once. */
79
115
  private exclusivePull;
80
116
  onChange(listener: BundleSourceListener): () => void;
117
+ /** Subscribe to the polls that fail, with why; a failed start or refresh throws to its caller instead. */
118
+ onPullFailure(listener: BundlePullFailureListener): () => void;
81
119
  stop(): Promise<void>;
82
120
  private schedulePoll;
83
121
  /**
@@ -96,9 +134,9 @@ export declare class SaasPullSource implements SkillBundleSource, BundlePushRece
96
134
  body: string;
97
135
  }>;
98
136
  /**
99
- * Verify the pinned pull token against the issuer's JWKS, issuer and audience.
100
- * Throws {@link SaasPullTokenRejectedError} when the token is refused, and a
101
- * plain Error when the JWKS can't be fetched (an outage).
137
+ * Verify the pinned pull token against the issuer's JWKS, issuer and audience, and log the check it fails on.
138
+ * Throws {@link SaasPullTokenRejectedError} when the token is refused, and {@link SaasJwksUnavailableError} when
139
+ * the JWKS can't be fetched (an outage).
102
140
  */
103
141
  private verifyPullToken;
104
142
  /**
@@ -116,5 +154,6 @@ export declare class SaasPullSource implements SkillBundleSource, BundlePushRece
116
154
  private persistCache;
117
155
  private loadCache;
118
156
  private notify;
157
+ private notifyPullFailure;
119
158
  }
120
159
  //# sourceMappingURL=saas-pull.source.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"saas-pull.source.d.ts","sourceRoot":"","sources":["../../../src/skills/sources/saas-pull.source.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAG7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EACV,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,iCAAiC,CAAC;AASzC;;;;GAIG;AACH,qBAAa,0BAA2B,SAAQ,KAAK;gBACvC,MAAM,EAAE,MAAM;CAI3B;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAE3C,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,UAAU;gBAArC,OAAO,EAAE,eAAe,GAAG,UAAU,EAC9C,MAAM,EAAE,MAAM;CAKjB;AAqCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,cAAe,YAAW,iBAAiB,EAAE,kBAAkB;IAcxE,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAhBvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,UAAU,CAA6B;IAC/C,sFAAsF;IACtF,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;IACnD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAqB;IAClD,OAAO,CAAC,eAAe,CAAC,CAAyC;IACjE,OAAO,CAAC,sBAAsB,CAAC,CAAqB;gBAGjC,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,MAAM,EAAE,cAAc,EACtB,IAAI,GAAE,gBAAqB;IAM9C,2FAA2F;IAC3F,IAAI,IAAI,IAAI,kBAAkB,GAAG,SAAS,CAEzC;IAED;;;;OAIG;IACG,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBnD,sGAAsG;IACtG,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAcd,WAAW;IAsBzB,iGAAiG;IACjG,OAAO,CAAC,aAAa;IAQrB,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,IAAI;IAO9C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B,OAAO,CAAC,YAAY;IAcpB;;;;;;;;OAQG;IACG,OAAO,IAAI,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;YAatC,QAAQ;cAwBN,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAoBhH;;;;OAIG;YACW,eAAe;IAK7B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;YAcZ,gBAAgB;IA0B9B,8EAA8E;YAChE,iBAAiB;YAuBjB,SAAS;IAkBvB,4GAA4G;IAC5G,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,SAAS;YAKH,YAAY;YAeZ,SAAS;YAkBT,MAAM;CASrB"}
1
+ {"version":3,"file":"saas-pull.source.d.ts","sourceRoot":"","sources":["../../../src/skills/sources/saas-pull.source.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,6 @@
1
+ import type { TokenVerifyFailure } from '@frontmcp/auth';
1
2
  import type { ResolvedBundle } from '../bundle/bundle.types';
3
+ import type { ReplayNonceStore } from '../security/replay-nonce-store';
2
4
  /**
3
5
  * Pluggable source of skill bundles. Static, npm-installed, and SaaS-pull
4
6
  * implementations all conform to this interface.
@@ -32,6 +34,11 @@ export interface SkillBundleSource {
32
34
  * notification fires on or shortly after `start()` resolves.
33
35
  */
34
36
  onChange(listener: BundleSourceListener): () => void;
37
+ /**
38
+ * Subscribe to the pulls that fail in the background (a poll), which no caller sees: `start()` and `refresh()` throw
39
+ * theirs. Returns an unsubscribe function. Present on a polling source: the `saas` source.
40
+ */
41
+ onPullFailure?(listener: BundlePullFailureListener): () => void;
35
42
  /**
36
43
  * Pull a fresh bundle on demand and notify listeners — the manual,
37
44
  * externally-driven counterpart to background polling. Optional: only
@@ -48,18 +55,49 @@ export interface SkillBundleSource {
48
55
  * a source with a last-good cache: the `saas` source.
49
56
  */
50
57
  keepBundle?(bundle: ResolvedBundle): Promise<void>;
58
+ /**
59
+ * The last good bundle {@link keepBundle} kept, read back from the cache; undefined when none is kept or it can't be
60
+ * read. While no bundle serves, the plugin compares a new bundle with it, and serves it in place of one it refuses.
61
+ */
62
+ keptBundle?(): Promise<ResolvedBundle | undefined>;
51
63
  /** Present on a source that takes pushed bundles: the `saas` source with `enableWebhook`. */
52
64
  readonly push?: BundlePushReceiver;
65
+ /**
66
+ * True on a source whose bundles only move forward: the `saas` source, unless `allowRollback`. The plugin then
67
+ * refuses a bundle older than the one being served, as `compareBundleVersions` orders them.
68
+ */
69
+ readonly forwardOnly?: boolean;
53
70
  /** Halt background work; idempotent. */
54
71
  stop(): Promise<void>;
55
72
  }
56
73
  /** The check a pushed bundle's token passes before the bundle is applied. */
57
74
  export interface BundlePushReceiver {
58
- /** Resolves when the push token is accepted; throws when it is refused or can't be checked. */
59
- verifyPushToken(token: string): Promise<void>;
75
+ /**
76
+ * Resolves when the push token is accepted for `body`, the exact bytes of the request body; throws when it is
77
+ * refused or can't be checked.
78
+ */
79
+ verifyPushToken(token: string, body: Uint8Array): Promise<void>;
60
80
  }
61
81
  /** Takes each new bundle; a pulling source waits for a promise it returns before its pull counts as done. */
62
- export type BundleSourceListener = (bundle: ResolvedBundle) => unknown;
82
+ export type BundleSourceListener = (bundle: ResolvedBundle, origin?: BundleOrigin) => unknown;
83
+ /** How a source came by a bundle it hands its listeners. */
84
+ export interface BundleOrigin {
85
+ /**
86
+ * Set when the pull failed and the bundle is the last good one the source kept, served in its place: why it failed.
87
+ * The plugin doesn't keep such a bundle again, since the cache holds it.
88
+ */
89
+ pullFailure?: string;
90
+ /** Set when that pull failed on its token: the check that refused it, or `jwks_unavailable`. */
91
+ tokenFailure?: BundleTokenFailure;
92
+ }
93
+ /**
94
+ * Which check refused a pull or push token, or `jwks_unavailable` when the issuer's keys could not be read to check
95
+ * it; `body_mismatch` is a push token issued for another body. For the server's logs and `/readyz`: a caller learns
96
+ * only that its token was refused.
97
+ */
98
+ export type BundleTokenFailure = TokenVerifyFailure | 'wrong_audience' | 'body_mismatch';
99
+ /** Takes the reason a background pull failed, and the token check it failed on, if any. */
100
+ export type BundlePullFailureListener = (reason: string, tokenFailure?: BundleTokenFailure) => void;
63
101
  /**
64
102
  * Pluggable last-good bundle cache. The default (Node) implementation writes to
65
103
  * disk; V8-isolate runtimes (Cloudflare Workers) inject a KV-backed store
@@ -76,7 +114,9 @@ export interface BundleCacheStore {
76
114
  * - `cache` replaces the on-disk last-good cache (no filesystem on a Worker),
77
115
  * - `disablePolling` turns off the internal `setInterval` loop (no background
78
116
  * execution on a Worker; a Cron Trigger / DO alarm drives {@link
79
- * SkillBundleSource.refresh} instead).
117
+ * SkillBundleSource.refresh} instead),
118
+ * - `pushReplayStore` records the pushed tokens' `jti`s where every instance
119
+ * reaches them (a Durable Object on a Worker).
80
120
  */
81
121
  export interface BundleSourceDeps {
82
122
  /**
@@ -90,5 +130,10 @@ export interface BundleSourceDeps {
90
130
  * {@link SkillBundleSource.refresh} instead.
91
131
  */
92
132
  disablePolling?: boolean;
133
+ /**
134
+ * Where the push replay guard records the `jti`s it accepted, shared by every instance that serves the server.
135
+ * Replaces the `saas` source's `pushReplayStorage` option and its in-memory default.
136
+ */
137
+ pushReplayStore?: ReplayNonceStore;
93
138
  }
94
139
  //# sourceMappingURL=skill-bundle-source.interface.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"skill-bundle-source.interface.d.ts","sourceRoot":"","sources":["../../../src/skills/sources/skill-bundle-source.interface.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,iBAAiB;IAChC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,IAAI,CAAC;IAErD;;;;;;;;;OASG;IACH,OAAO,CAAC,IAAI,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IAEhD;;;OAGG;IACH,UAAU,CAAC,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD,6FAA6F;IAC7F,QAAQ,CAAC,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAEnC,wCAAwC;IACxC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,6EAA6E;AAC7E,MAAM,WAAW,kBAAkB;IACjC,+FAA+F;IAC/F,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED,6GAA6G;AAC7G,MAAM,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,cAAc,KAAK,OAAO,CAAC;AAEvE;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,IAAI,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IAC5C,KAAK,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B"}
1
+ {"version":3,"file":"skill-bundle-source.interface.d.ts","sourceRoot":"","sources":["../../../src/skills/sources/skill-bundle-source.interface.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAEvE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,iBAAiB;IAChC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,IAAI,CAAC;IAErD;;;OAGG;IACH,aAAa,CAAC,CAAC,QAAQ,EAAE,yBAAyB,GAAG,MAAM,IAAI,CAAC;IAEhE;;;;;;;;;OASG;IACH,OAAO,CAAC,IAAI,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IAEhD;;;OAGG;IACH,UAAU,CAAC,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD;;;OAGG;IACH,UAAU,CAAC,IAAI,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IAEnD,6FAA6F;IAC7F,QAAQ,CAAC,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAEnC;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAE/B,wCAAwC;IACxC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,6EAA6E;AAC7E,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjE;AAED,6GAA6G;AAC7G,MAAM,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC;AAE9F,4DAA4D;AAC5D,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gGAAgG;IAChG,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC;AAED;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,kBAAkB,GAAG,gBAAgB,GAAG,eAAe,CAAC;AAEzF,2FAA2F;AAC3F,MAAM,MAAM,yBAAyB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,kBAAkB,KAAK,IAAI,CAAC;AAEpG;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,IAAI,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IAC5C,KAAK,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,eAAe,CAAC,EAAE,gBAAgB,CAAC;CACpC"}