@knitli/openapi-mcp 1.2.1 → 1.3.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.
package/README.md CHANGED
@@ -277,6 +277,14 @@ retains its signed-envelope-only contract. Storage must preserve immutable relea
277
277
  identities. Admission does not guarantee future availability, so runtime reads
278
278
  continue verifying records at use time.
279
279
 
280
+ For a boundary that needs strict manifest and signature authentication plus the
281
+ logical digest without changing generation state, use
282
+ `authenticateManifest(envelope, trust, limitOverrides?)` from
283
+ `@knitli/openapi-mcp/runtime`. It does not verify records, decide rollback
284
+ against current state, or admit an executable release. Callers activating a
285
+ catalog use `admitCatalogRelease`; callers retaining reviewed authority must
286
+ still perform that authority and admission step after authentication.
287
+
280
288
  ## Recover from a bad release
281
289
 
282
290
  Before release, record the prior **observed package version**, its tarball digest,
@@ -5,8 +5,8 @@ export { digestCredentialAuthorizationBinding, snapshotCredentialAuthorizationBi
5
5
  export { sha256, verifyEd25519 } from "./digest.ts";
6
6
  export type { OpenApiMcpErrorCode } from "./errors.ts";
7
7
  export { OpenApiMcpError } from "./errors.ts";
8
- export type { AdmittedManifest, ManifestTrust, TrustedManifestKey, } from "./manifest.ts";
9
- export { admitManifest } from "./manifest.ts";
8
+ export type { AdmittedManifest, AuthenticatedManifest, ManifestTrust, TrustedManifestKey, } from "./manifest.ts";
9
+ export { admitManifest, authenticateManifest } from "./manifest.ts";
10
10
  export { createPreparedCall, digestBytes, digestPreparedCall, type PreparedCallInput, verifyPreparedCall, } from "./prepared-call.ts";
11
11
  export { decodeOperationRef, encodeOperationRef, parseTypedRecordId, } from "./references.ts";
12
12
  export { createOpenApiRuntime, type OpenApiRuntimeOptions } from "./runtime.ts";
@@ -3,7 +3,7 @@ export { classifyOperation, } from "./classify.js";
3
3
  export { digestCredentialAuthorizationBinding, snapshotCredentialAuthorizationBinding, } from "./credential-binding.js";
4
4
  export { sha256, verifyEd25519 } from "./digest.js";
5
5
  export { OpenApiMcpError } from "./errors.js";
6
- export { admitManifest } from "./manifest.js";
6
+ export { admitManifest, authenticateManifest } from "./manifest.js";
7
7
  export { createPreparedCall, digestBytes, digestPreparedCall, verifyPreparedCall, } from "./prepared-call.js";
8
8
  export { decodeOperationRef, encodeOperationRef, parseTypedRecordId, } from "./references.js";
9
9
  export { createOpenApiRuntime } from "./runtime.js";
@@ -19,7 +19,14 @@ export interface AuthenticatedManifest extends AdmittedManifest {
19
19
  readonly rollback: RollbackAuthorization | undefined;
20
20
  readonly rollbackMalformed: boolean;
21
21
  }
22
- /** Authenticate a v4/v5 manifest without reading or mutating generation state. */
22
+ /**
23
+ * Authenticate a strict v4/v5 manifest and trusted release signature, then
24
+ * return its domain-separated logical digest without reading or mutating
25
+ * generation state. This does not verify referenced inventory, validate
26
+ * rollback authorization against current state, admit a generation, or make a
27
+ * release executable; activation must use admitCatalogRelease or an equivalent
28
+ * authority path that performs the full inventory and state decision.
29
+ */
23
30
  export declare function authenticateManifest(envelope: ManifestEnvelope, trust: ManifestTrust, limitOverrides?: Partial<RuntimeLimits>): Promise<AuthenticatedManifest>;
24
31
  /** Atomically commit the generation transition for an authenticated manifest. */
25
32
  /**
@@ -349,7 +349,14 @@ function deepFreeze(value) {
349
349
  function detachedManifest(manifest, limits) {
350
350
  return parseManifest(canonicalJson(manifest), limits);
351
351
  }
352
- /** Authenticate a v4/v5 manifest without reading or mutating generation state. */
352
+ /**
353
+ * Authenticate a strict v4/v5 manifest and trusted release signature, then
354
+ * return its domain-separated logical digest without reading or mutating
355
+ * generation state. This does not verify referenced inventory, validate
356
+ * rollback authorization against current state, admit a generation, or make a
357
+ * release executable; activation must use admitCatalogRelease or an equivalent
358
+ * authority path that performs the full inventory and state decision.
359
+ */
353
360
  export async function authenticateManifest(envelope, trust, limitOverrides) {
354
361
  const limits = resolveRuntimeLimits(limitOverrides);
355
362
  if (!isObject(envelope))
@@ -344,6 +344,13 @@ function validateSchema(schema, value, closure, depth, context) {
344
344
  if (schema === false || !isObject(schema))
345
345
  schemaFailure();
346
346
  for (const key of Object.keys(schema)) {
347
+ // OpenAPI Specification Extensions (`^x-`, OpenAPI 3.1 §4.9) are legal on a Schema Object and
348
+ // carry no validation semantics, so ignore the key and never walk its value -- Cloudflare's
349
+ // API document puts `x-auditable: true` on parameter schemas, and the compiler copies
350
+ // component schemas verbatim. Every other unknown keyword still fails: one with validation
351
+ // semantics (`pattern`, `contains`) must not be silently skipped.
352
+ if (key.startsWith("x-"))
353
+ continue;
347
354
  if (!supportedSchemaKeys.has(key))
348
355
  schemaFailure();
349
356
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@knitli/openapi-mcp",
3
3
  "private": false,
4
- "version": "1.2.1",
4
+ "version": "1.3.1",
5
5
  "type": "module",
6
6
  "description": "Compile signed OpenAPI catalogs and serve verified search and authorized API calls over MCP.",
7
7
  "license": "MIT OR Apache-2.0",