@ggui-ai/registry-core 0.7.0 → 0.8.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 (37) hide show
  1. package/dist/impls/memory-bundle-storage.d.ts.map +1 -1
  2. package/dist/impls/memory-bundle-storage.js +25 -22
  3. package/dist/impls/memory-registry-storage.d.ts.map +1 -1
  4. package/dist/impls/memory-registry-storage.js +3 -0
  5. package/dist/index.d.ts +4 -2
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +4 -1
  8. package/dist/interfaces/bundle-storage.d.ts +55 -31
  9. package/dist/interfaces/bundle-storage.d.ts.map +1 -1
  10. package/dist/interfaces/registry-storage.d.ts +11 -0
  11. package/dist/interfaces/registry-storage.d.ts.map +1 -1
  12. package/dist/mcp-tool-filters.d.ts +23 -0
  13. package/dist/mcp-tool-filters.d.ts.map +1 -0
  14. package/dist/mcp-tool-filters.js +14 -0
  15. package/dist/ops/list-versions.d.ts +19 -10
  16. package/dist/ops/list-versions.d.ts.map +1 -1
  17. package/dist/ops/list-versions.js +43 -8
  18. package/dist/ops/private-read-authz.d.ts +88 -0
  19. package/dist/ops/private-read-authz.d.ts.map +1 -0
  20. package/dist/ops/private-read-authz.js +58 -0
  21. package/dist/ops/publish.d.ts +30 -0
  22. package/dist/ops/publish.d.ts.map +1 -1
  23. package/dist/ops/publish.js +162 -28
  24. package/dist/ops/read.d.ts +28 -6
  25. package/dist/ops/read.d.ts.map +1 -1
  26. package/dist/ops/read.js +47 -7
  27. package/dist/ops/search.d.ts +13 -1
  28. package/dist/ops/search.d.ts.map +1 -1
  29. package/dist/ops/search.js +54 -2
  30. package/dist/testing/bundle-storage-contract.d.ts.map +1 -1
  31. package/dist/testing/bundle-storage-contract.js +61 -27
  32. package/dist/testing/registry-storage-contract.d.ts.map +1 -1
  33. package/dist/testing/registry-storage-contract.js +122 -1
  34. package/dist/types.d.ts +115 -16
  35. package/dist/types.d.ts.map +1 -1
  36. package/dist/types.js +30 -14
  37. package/package.json +11 -5
@@ -1 +1 @@
1
- {"version":3,"file":"memory-bundle-storage.d.ts","sourceRoot":"","sources":["../../src/impls/memory-bundle-storage.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAErE,MAAM,WAAW,4BAA4B;IAC3C;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAgB,qBAAqB,CACnC,OAAO,GAAE,4BAAiC,GACzC,aAAa,CA2Cf"}
1
+ {"version":3,"file":"memory-bundle-storage.d.ts","sourceRoot":"","sources":["../../src/impls/memory-bundle-storage.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAGrE,MAAM,WAAW,4BAA4B;IAC3C;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAgB,qBAAqB,CACnC,OAAO,GAAE,4BAAiC,GACzC,aAAa,CAkDf"}
@@ -3,38 +3,41 @@ export function inMemoryBundleStorage(options = {}) {
3
3
  const bundles = new Map();
4
4
  const signatures = new Map();
5
5
  const manifests = new Map();
6
- const key = (scope, name, version) => `${scope}/${name}/${version}`;
6
+ // Visibility segments the key (H1 prefix split) — a blob written
7
+ // `public` must be invisible to a `private` read of the same triple,
8
+ // exactly like the prefix-split object keys of the durable impls.
9
+ const key = (scope, name, version, visibility) => `${visibility}/${scope}/${name}/${version}`;
7
10
  return {
8
- async putBundle(scope, name, version, bytes) {
9
- bundles.set(key(scope, name, version), new Uint8Array(bytes));
10
- return this.bundleUrl(scope, name, version);
11
+ async putBundle(scope, name, version, visibility, bytes) {
12
+ bundles.set(key(scope, name, version, visibility), new Uint8Array(bytes));
13
+ return this.bundleUrl(scope, name, version, visibility);
11
14
  },
12
- async getBundle(scope, name, version) {
13
- const bytes = bundles.get(key(scope, name, version));
15
+ async getBundle(scope, name, version, visibility) {
16
+ const bytes = bundles.get(key(scope, name, version, visibility));
14
17
  return bytes === undefined ? null : new Uint8Array(bytes);
15
18
  },
16
- async putSignature(scope, name, version, signature) {
17
- signatures.set(key(scope, name, version), signature);
18
- return this.signatureUrl(scope, name, version);
19
+ async putSignature(scope, name, version, visibility, signature) {
20
+ signatures.set(key(scope, name, version, visibility), signature);
21
+ return this.signatureUrl(scope, name, version, visibility);
19
22
  },
20
- async getSignature(scope, name, version) {
21
- return signatures.get(key(scope, name, version)) ?? null;
23
+ async getSignature(scope, name, version, visibility) {
24
+ return signatures.get(key(scope, name, version, visibility)) ?? null;
22
25
  },
23
- async putManifest(scope, name, version, manifest) {
24
- manifests.set(key(scope, name, version), manifest);
25
- return this.manifestUrl(scope, name, version);
26
+ async putManifest(scope, name, version, visibility, manifest) {
27
+ manifests.set(key(scope, name, version, visibility), manifest);
28
+ return this.manifestUrl(scope, name, version, visibility);
26
29
  },
27
- async getManifest(scope, name, version) {
28
- return manifests.get(key(scope, name, version)) ?? null;
30
+ async getManifest(scope, name, version, visibility) {
31
+ return manifests.get(key(scope, name, version, visibility)) ?? null;
29
32
  },
30
- bundleUrl(scope, name, version) {
31
- return `${bundleHost}/bundles/${scope}/${name}/${version}/bundle.js`;
33
+ bundleUrl(scope, name, version, visibility) {
34
+ return `${bundleHost}/bundles/${visibility}/${scope}/${name}/${version}/bundle.js`;
32
35
  },
33
- signatureUrl(scope, name, version) {
34
- return `${bundleHost}/bundles/${scope}/${name}/${version}/bundle.js.sig`;
36
+ signatureUrl(scope, name, version, visibility) {
37
+ return `${bundleHost}/bundles/${visibility}/${scope}/${name}/${version}/bundle.js.sig`;
35
38
  },
36
- manifestUrl(scope, name, version) {
37
- return `${bundleHost}/bundles/${scope}/${name}/${version}/manifest.json`;
39
+ manifestUrl(scope, name, version, visibility) {
40
+ return `${bundleHost}/bundles/${visibility}/${scope}/${name}/${version}/manifest.json`;
38
41
  },
39
42
  };
40
43
  }
@@ -1 +1 @@
1
- {"version":3,"file":"memory-registry-storage.d.ts","sourceRoot":"","sources":["../../src/impls/memory-registry-storage.ts"],"names":[],"mappings":"AAmBA,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,mCAAmC,CAAC;AAK3C,wBAAgB,uBAAuB,IAAI,eAAe,CA2JzD"}
1
+ {"version":3,"file":"memory-registry-storage.d.ts","sourceRoot":"","sources":["../../src/impls/memory-registry-storage.ts"],"names":[],"mappings":"AAoBA,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,mCAAmC,CAAC;AAM3C,wBAAgB,uBAAuB,IAAI,eAAe,CA2JzD"}
@@ -1,4 +1,5 @@
1
1
  import { AuthorKeyAlreadyExistsError, } from '../interfaces/registry-storage.js';
2
+ import { matchesMcpToolFilters } from '../mcp-tool-filters.js';
2
3
  const DEFAULT_LIMIT = 50;
3
4
  const MAX_LIMIT = 200;
4
5
  export function inMemoryRegistryStorage() {
@@ -177,6 +178,8 @@ function rowMatchesFilter(row, q) {
177
178
  return false;
178
179
  if (q.hook !== undefined && row.hook !== q.hook)
179
180
  return false;
181
+ if (!matchesMcpToolFilters(row.mcpTools, q))
182
+ return false;
180
183
  if (q.tag !== undefined) {
181
184
  if (row.tags === undefined || !row.tags.includes(q.tag))
182
185
  return false;
package/dist/index.d.ts CHANGED
@@ -10,11 +10,12 @@
10
10
  export type { AuthnContext } from './interfaces/authn.js';
11
11
  export type { BundleStorage } from './interfaces/bundle-storage.js';
12
12
  export { AuthorKeyAlreadyExistsError, type PutAuthorKeyOptions, type RegistryStorage, type ScopeOwnerExpectation, } from './interfaces/registry-storage.js';
13
- export { ARTIFACTS_METADATA_SK, type ArtifactKind, type ArtifactScanFilter, type ArtifactVersionRow, type ArtifactsMetadataRow, type AuthorKeyListEntry, type AuthorKeyRow, type CompiledBlobRow, DELETE_AUTHOR_KEY_ERROR_CODES, type DeleteAuthorKeyErrorBody, type DeleteAuthorKeyErrorCode, type DeleteAuthorKeyResponseBody, type ErrorBody, LIST_AUTHOR_KEYS_ERROR_CODES, type ListAuthorKeysErrorBody, type ListAuthorKeysErrorCode, type ListAuthorKeysResponseBody, LIST_VERSIONS_ERROR_CODES, type ListVersionsErrorBody, type ListVersionsErrorCode, type ListVersionsResponse, PUBLISH_ERROR_CODES, type PublishErrorBody, type PublishErrorCode, type PublishRequestBody, type PublishResponseBody, READ_ERROR_CODES, type ReadErrorBody, type ReadErrorCode, type ReadPkgResponse, REGISTER_AUTHOR_KEY_ERROR_CODES, type RegisterAuthorKeyErrorBody, type RegisterAuthorKeyErrorCode, type RegisterAuthorKeyRequestBody, type RegisterAuthorKeyResponseBody, SCOPE_VERIFICATIONS, type ScopeOwnerRow, type ScopeVerification, SEARCH_ERROR_CODES, SEARCH_SORT_OPTIONS, unauthorizedErrorBody, type SearchErrorBody, type SearchErrorCode, type SearchResponse, type SearchResultEntry, type SearchSort, type VersionListEntry, type Visibility, } from './types.js';
13
+ export { ARTIFACTS_METADATA_SK, type ArtifactKind, type ArtifactScanFilter, type ArtifactVersionRow, type ArtifactsMetadataRow, type AuthorKeyListEntry, type AuthorKeyRow, type CompiledBlobRow, DELETE_AUTHOR_KEY_ERROR_CODES, type DeleteAuthorKeyErrorBody, type DeleteAuthorKeyErrorCode, type DeleteAuthorKeyResponseBody, type ErrorBody, LIST_AUTHOR_KEYS_ERROR_CODES, type ListAuthorKeysErrorBody, type ListAuthorKeysErrorCode, type ListAuthorKeysResponseBody, LIST_VERSIONS_ERROR_CODES, type ListVersionsErrorBody, type ListVersionsErrorCode, type ListVersionsResponse, PUBLISH_ERROR_CODES, type PublishErrorBody, type PublishErrorCode, type PublishRequestBody, type PublishResponseBody, READ_ERROR_CODES, type ReadErrorBody, type ReadErrorCode, type ReadPkgResponse, REGISTER_AUTHOR_KEY_ERROR_CODES, type RegisterAuthorKeyErrorBody, type RegisterAuthorKeyErrorCode, type RegisterAuthorKeyRequestBody, type RegisterAuthorKeyResponseBody, SAN_ALLOWLIST_INVALID, type SanAllowlistInvalid, SCOPE_VERIFICATIONS, type ScopeOwnerRow, type ScopeVerification, SEARCH_ERROR_CODES, SEARCH_SORT_OPTIONS, unauthorizedErrorBody, type SearchErrorBody, type SearchErrorCode, type SearchResponse, type SearchResultEntry, type SearchSort, type VersionListEntry, type Visibility, } from './types.js';
14
14
  export { compileBlueprint, type CompileBlueprintErr, type CompileBlueprintOk, type CompileBlueprintResult, } from './ops/compile.js';
15
15
  export { checkConformance, MAX_BLUEPRINT_SOURCE_BYTES, type BlueprintProbeRunner, type ConformanceError, type ConformanceErrorCode, type ConformanceFailureCode, type ConformanceRequestPayload, type ConformanceResponseBody, } from './ops/conformance.js';
16
- export { publishArtifact, MAX_BUNDLE_BYTES, RESERVED_SCOPES, type PublishArtifactDeps, type PublishArtifactInput, type PublishArtifactResult, } from './ops/publish.js';
16
+ export { publishArtifact, MAX_BUNDLE_BYTES, RESERVED_SCOPES, type PublishArtifactDeps, type PublishArtifactInput, type PublishArtifactResult, type VerifiedEmailResolver, } from './ops/publish.js';
17
17
  export { readArtifact, type ReadArtifactDeps, type ReadArtifactInput, type ReadArtifactResult, } from './ops/read.js';
18
+ export { artifactScope, canReadPrivateArtifact, createScopeOwnerResolver, } from './ops/private-read-authz.js';
18
19
  export { listArtifactVersions, type ListArtifactVersionsDeps, type ListArtifactVersionsInput, type ListArtifactVersionsResult, } from './ops/list-versions.js';
19
20
  export { searchArtifacts, type SearchArtifactsDeps, type SearchArtifactsInput, type SearchArtifactsResult, } from './ops/search.js';
20
21
  export { registerAuthorKey, type RegisterAuthorKeyDeps, type RegisterAuthorKeyInput, type RegisterAuthorKeyResult, } from './ops/register-author-key.js';
@@ -22,6 +23,7 @@ export { listAuthorKeys, type ListAuthorKeysDeps, type ListAuthorKeysResult, } f
22
23
  export { deleteAuthorKey, type DeleteAuthorKeyDeps, type DeleteAuthorKeyInput, type DeleteAuthorKeyResult, } from './ops/delete-author-key.js';
23
24
  export { inMemoryRegistryStorage } from './impls/memory-registry-storage.js';
24
25
  export { inMemoryBundleStorage, type InMemoryBundleStorageOptions, } from './impls/memory-bundle-storage.js';
26
+ export { matchesMcpToolFilters } from './mcp-tool-filters.js';
25
27
  export { installCommand, type InstallCommandOptions, } from './install-command.js';
26
28
  export { compareSemver } from './utils/semver.js';
27
29
  export { base64Encode, safeBase64Decode, sha384Base64 } from './utils/base64.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -9,12 +9,13 @@
9
9
  */
10
10
  export { AuthorKeyAlreadyExistsError, } from './interfaces/registry-storage.js';
11
11
  // Types — rows + wire shapes
12
- export { ARTIFACTS_METADATA_SK, DELETE_AUTHOR_KEY_ERROR_CODES, LIST_AUTHOR_KEYS_ERROR_CODES, LIST_VERSIONS_ERROR_CODES, PUBLISH_ERROR_CODES, READ_ERROR_CODES, REGISTER_AUTHOR_KEY_ERROR_CODES, SCOPE_VERIFICATIONS, SEARCH_ERROR_CODES, SEARCH_SORT_OPTIONS, unauthorizedErrorBody, } from './types.js';
12
+ export { ARTIFACTS_METADATA_SK, DELETE_AUTHOR_KEY_ERROR_CODES, LIST_AUTHOR_KEYS_ERROR_CODES, LIST_VERSIONS_ERROR_CODES, PUBLISH_ERROR_CODES, READ_ERROR_CODES, REGISTER_AUTHOR_KEY_ERROR_CODES, SAN_ALLOWLIST_INVALID, SCOPE_VERIFICATIONS, SEARCH_ERROR_CODES, SEARCH_SORT_OPTIONS, unauthorizedErrorBody, } from './types.js';
13
13
  // Operations
14
14
  export { compileBlueprint, } from './ops/compile.js';
15
15
  export { checkConformance, MAX_BLUEPRINT_SOURCE_BYTES, } from './ops/conformance.js';
16
16
  export { publishArtifact, MAX_BUNDLE_BYTES, RESERVED_SCOPES, } from './ops/publish.js';
17
17
  export { readArtifact, } from './ops/read.js';
18
+ export { artifactScope, canReadPrivateArtifact, createScopeOwnerResolver, } from './ops/private-read-authz.js';
18
19
  export { listArtifactVersions, } from './ops/list-versions.js';
19
20
  export { searchArtifacts, } from './ops/search.js';
20
21
  export { registerAuthorKey, } from './ops/register-author-key.js';
@@ -23,6 +24,8 @@ export { deleteAuthorKey, } from './ops/delete-author-key.js';
23
24
  // In-memory impls
24
25
  export { inMemoryRegistryStorage } from './impls/memory-registry-storage.js';
25
26
  export { inMemoryBundleStorage, } from './impls/memory-bundle-storage.js';
27
+ // Shared scan-filter semantics
28
+ export { matchesMcpToolFilters } from './mcp-tool-filters.js';
26
29
  // Utils
27
30
  export { installCommand, } from './install-command.js';
28
31
  export { compareSemver } from './utils/semver.js';
@@ -2,8 +2,8 @@
2
2
  * `BundleStorage` — bundle + signature + manifest blob storage. A
3
3
  * hosted implementation may serve blobs from object storage behind a
4
4
  * CDN; the open-source server backs it with the filesystem under
5
- * `<root>/bundles/<scope>/<name>/<version>/`. A memory impl is
6
- * provided for tests.
5
+ * `<root>/bundles/<visibility>/<scope>/<name>/<version>/`. A memory
6
+ * impl is provided for tests.
7
7
  *
8
8
  * Each `put*` method returns the fully-qualified URL the consumer
9
9
  * (iframe runtime, install CLI) can fetch. The URL prefix is
@@ -11,17 +11,33 @@
11
11
  * CDN-fronted implementation, or `http://localhost:9001` (or
12
12
  * whatever the server is bound to) for the open-source server.
13
13
  *
14
- * Bundles are immutable post-publish. Responses MUST emit
15
- * `Cache-Control: public, max-age=31536000, immutable` — SRI integrity
16
- * depends on it. The OSS server's bundle route sets this header
17
- * explicitly; a CDN-fronted implementation sets it via its cache
18
- * policy.
14
+ * ## Visibility-split key layout (load-bearing)
15
+ *
16
+ * Every blob lives under a visibility-segmented key:
17
+ *
18
+ * bundles/public/<scope>/<name>/<version>/{bundle.js,bundle.js.sig,manifest.json}
19
+ * bundles/private/<scope>/<name>/<version>/{...}
20
+ *
21
+ * Placement IS the access-control boundary: the `bundles/public/`
22
+ * prefix may be served anonymously (CDN, static route); the
23
+ * `bundles/private/` prefix MUST only be reachable through an
24
+ * authenticated route that authorizes the caller against the
25
+ * artifact's publisher or scope owner. An impl that flattens the two
26
+ * prefixes back together silently republishes every private artifact.
27
+ *
28
+ * Bundles are immutable post-publish. Public-prefix responses MUST
29
+ * emit `Cache-Control: public, max-age=31536000, immutable` — SRI
30
+ * integrity depends on it. Private-prefix responses stay immutable but
31
+ * MUST NOT be shared-cacheable (`Cache-Control: private, …`). The OSS
32
+ * server's bundle routes set these headers explicitly; a CDN-fronted
33
+ * implementation sets the public policy on its cache behavior.
19
34
  *
20
35
  * ## Protocol & Contract Bar
21
36
  *
22
37
  * **Parties:**
23
38
  * - Producer: {@link publishArtifact} writes bundle (gadgets),
24
- * signature (gadgets), and manifest (always) on every publish.
39
+ * signature (gadgets), and manifest (always) on every publish, at
40
+ * the key the manifest's `visibility` selects.
25
41
  * - Consumer: iframe-runtime (bundleUrl), install CLI (signatureUrl,
26
42
  * manifestUrl), audit tooling (manifestUrl on yanked versions).
27
43
  *
@@ -31,49 +47,57 @@
31
47
  * per-version row immutability invariant on {@link RegistryStorage}
32
48
  * prevents true re-publishes; the bundle-storage layer needs no
33
49
  * conflict semantics).
50
+ * - Key composition MUST segment on `visibility` — a blob written
51
+ * `public` is invisible to a `private` read of the same triple, and
52
+ * vice versa.
34
53
  * - URL composition methods (`bundleUrl`, `signatureUrl`,
35
- * `manifestUrl`) MUST be pure — no I/O, no async. Consumers cache
36
- * URLs liberally.
54
+ * `manifestUrl`) MUST be pure — no I/O, no async — and MUST embed
55
+ * the same visibility segment the corresponding `put*` used, so the
56
+ * persisted row URLs point at the blob's real location. Consumers
57
+ * cache URLs liberally.
37
58
  *
38
59
  * **Failure mode:**
39
60
  * - Transport-level failures throw; the publish op wraps and returns
40
61
  * 500.
41
- * - Missing-blob reads return `null`; never throw.
62
+ * - Missing-blob reads return `null`; never throw. A visibility
63
+ * mismatch reads as a miss.
42
64
  *
43
65
  * **Observable violation:**
44
66
  * - Contract test {@link bundleStorageContract} covers: bundle
45
67
  * round-trip preserves bytes; signature round-trip preserves the
46
68
  * structured object; manifest round-trip preserves the full
47
- * discriminated-union shape; URL methods compose without side effects;
48
- * missing reads return null.
69
+ * discriminated-union shape; URL methods compose without side effects
70
+ * and embed the visibility segment; missing reads return null;
71
+ * cross-visibility reads return null.
49
72
  */
50
73
  import type { ArtifactManifest } from '@ggui-ai/artifact-manifest';
51
74
  import type { GadgetSignature } from '@ggui-ai/gadget-signing';
75
+ import type { Visibility } from '../types.js';
52
76
  export interface BundleStorage {
53
- /** Write gadget bundle bytes. Returns the public URL. */
54
- putBundle(scope: string, name: string, version: string, bytes: Uint8Array): Promise<string>;
55
- /** Read gadget bundle bytes. `null` on miss. */
56
- getBundle(scope: string, name: string, version: string): Promise<Uint8Array | null>;
77
+ /** Write gadget bundle bytes. Returns the fetch URL. */
78
+ putBundle(scope: string, name: string, version: string, visibility: Visibility, bytes: Uint8Array): Promise<string>;
79
+ /** Read gadget bundle bytes. `null` on miss (including visibility mismatch). */
80
+ getBundle(scope: string, name: string, version: string, visibility: Visibility): Promise<Uint8Array | null>;
57
81
  /**
58
- * Write the signature envelope. Returns the public URL.
82
+ * Write the signature envelope. Returns the fetch URL.
59
83
  *
60
84
  * The envelope is a {@link GadgetSignature} — a discriminated union
61
85
  * over `algorithm` (`ed25519` for private gadgets, `sigstore-cosign`
62
86
  * for public). Impls serialize via `JSON.stringify(signature)` and
63
87
  * store the resulting bytes verbatim.
64
88
  */
65
- putSignature(scope: string, name: string, version: string, signature: GadgetSignature): Promise<string>;
66
- /** Read the signature envelope. `null` on miss. */
67
- getSignature(scope: string, name: string, version: string): Promise<GadgetSignature | null>;
68
- /** Write the manifest verbatim. Returns the public URL. */
69
- putManifest(scope: string, name: string, version: string, manifest: ArtifactManifest): Promise<string>;
70
- /** Read the manifest. `null` on miss. */
71
- getManifest(scope: string, name: string, version: string): Promise<ArtifactManifest | null>;
72
- /** Compose the public bundle URL. No I/O. */
73
- bundleUrl(scope: string, name: string, version: string): string;
74
- /** Compose the public signature URL. No I/O. */
75
- signatureUrl(scope: string, name: string, version: string): string;
76
- /** Compose the public manifest URL. No I/O. */
77
- manifestUrl(scope: string, name: string, version: string): string;
89
+ putSignature(scope: string, name: string, version: string, visibility: Visibility, signature: GadgetSignature): Promise<string>;
90
+ /** Read the signature envelope. `null` on miss (including visibility mismatch). */
91
+ getSignature(scope: string, name: string, version: string, visibility: Visibility): Promise<GadgetSignature | null>;
92
+ /** Write the manifest verbatim. Returns the fetch URL. */
93
+ putManifest(scope: string, name: string, version: string, visibility: Visibility, manifest: ArtifactManifest): Promise<string>;
94
+ /** Read the manifest. `null` on miss (including visibility mismatch). */
95
+ getManifest(scope: string, name: string, version: string, visibility: Visibility): Promise<ArtifactManifest | null>;
96
+ /** Compose the bundle URL (embeds the visibility segment). No I/O. */
97
+ bundleUrl(scope: string, name: string, version: string, visibility: Visibility): string;
98
+ /** Compose the signature URL (embeds the visibility segment). No I/O. */
99
+ signatureUrl(scope: string, name: string, version: string, visibility: Visibility): string;
100
+ /** Compose the manifest URL (embeds the visibility segment). No I/O. */
101
+ manifestUrl(scope: string, name: string, version: string, visibility: Visibility): string;
78
102
  }
79
103
  //# sourceMappingURL=bundle-storage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bundle-storage.d.ts","sourceRoot":"","sources":["../../src/interfaces/bundle-storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5F,gDAAgD;IAChD,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAEpF;;;;;;;OAOG;IACH,YAAY,CACV,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,eAAe,GACzB,OAAO,CAAC,MAAM,CAAC,CAAC;IACnB,mDAAmD;IACnD,YAAY,CACV,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IAEnC,2DAA2D;IAC3D,WAAW,CACT,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAAC,MAAM,CAAC,CAAC;IACnB,yCAAyC;IACzC,WAAW,CACT,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAEpC,6CAA6C;IAC7C,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IAChE,gDAAgD;IAChD,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACnE,+CAA+C;IAC/C,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;CACnE"}
1
+ {"version":3,"file":"bundle-storage.d.ts","sourceRoot":"","sources":["../../src/interfaces/bundle-storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC5B,wDAAwD;IACxD,SAAS,CACP,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,UAAU,GAChB,OAAO,CAAC,MAAM,CAAC,CAAC;IACnB,gFAAgF;IAChF,SAAS,CACP,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAE9B;;;;;;;OAOG;IACH,YAAY,CACV,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,eAAe,GACzB,OAAO,CAAC,MAAM,CAAC,CAAC;IACnB,mFAAmF;IACnF,YAAY,CACV,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IAEnC,0DAA0D;IAC1D,WAAW,CACT,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAAC,MAAM,CAAC,CAAC;IACnB,yEAAyE;IACzE,WAAW,CACT,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAEpC,sEAAsE;IACtE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,MAAM,CAAC;IACxF,yEAAyE;IACzE,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,MAAM,CAAC;IAC3F,wEAAwE;IACxE,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,MAAM,CAAC;CAC3F"}
@@ -53,6 +53,13 @@
53
53
  * rows MUST come back ordered by `publishedAt` descending (newest
54
54
  * first), globally correct across the full cursor chain. Without an
55
55
  * `order`, consumers MUST treat ordering as non-deterministic.
56
+ * - {@link scanArtifacts} MUST apply the `tool` / `server` filter
57
+ * dimensions with the shared semantics of `matchesMcpToolFilters`:
58
+ * `tool` matches any binding entry with that tool name; `server`
59
+ * matches entries declaring that server (bare entries never match);
60
+ * together they require one entry with exactly that (server, tool)
61
+ * pair. Case-sensitive exact, AND-composed with every other
62
+ * dimension.
56
63
  *
57
64
  * **Failure mode:**
58
65
  * - Transport-level failures (store throttling, disk full) throw.
@@ -122,6 +129,10 @@ export interface RegistryStorage {
122
129
  * When `filter.order` is `'recent'`, rows MUST be returned newest
123
130
  * first by `publishedAt`, globally correct across the full cursor
124
131
  * chain — see the Obligations section above.
132
+ *
133
+ * `filter.tool` / `filter.server` follow the shared MCP-binding
134
+ * filter semantics (`matchesMcpToolFilters`) — see the Obligations
135
+ * section above.
125
136
  */
126
137
  scanArtifacts(filter: ArtifactScanFilter): Promise<{
127
138
  readonly rows: readonly ArtifactsMetadataRow[];
@@ -1 +1 @@
1
- {"version":3,"file":"registry-storage.d.ts","sourceRoot":"","sources":["../../src/interfaces/registry-storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEG;AACH,OAAO,KAAK,EACV,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACZ,eAAe,EACf,aAAa,EACd,MAAM,aAAa,CAAC;AAErB;;;;;;;;;GASG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;GAQG;AACH,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBACX,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;CAQ3C;AAED;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAC7B;IACE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC,cAAc,CAAC,CAAC;CACtD,GACD;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;CAAE,CAAC;AAE9B,MAAM,WAAW,eAAe;IAE9B,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;IAC9E,mBAAmB,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D;;;;;;;;;;OAUG;IACH,aAAa,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC;QACjD,QAAQ,CAAC,IAAI,EAAE,SAAS,oBAAoB,EAAE,CAAC;QAC/C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;KAC9B,CAAC,CAAC;IAGH,kBAAkB,CAChB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IACtC;;;;;;;;;;;;;;;;;OAiBG;IACH,oBAAoB,CAClB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,SAAS,kBAAkB,EAAE,CAAC,CAAC;IAC1C;;;;;OAKG;IACH,0BAA0B,CACxB,GAAG,EAAE,kBAAkB,GACtB,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,gBAAgB,CAAA;KAAE,CAAC,CAAC;IACnE,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAGxE;;;;;;;;;;;;;OAaG;IACH,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IAEzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgDG;IACH,oBAAoB,CAClB,UAAU,EAAE,kBAAkB,EAC9B,OAAO,EAAE,eAAe,GACvB,OAAO,CACN;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAA;KAAE,GACxC;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,gBAAgB,CAAA;KAAE,CAC1C,CAAC;IAGF;;;;;;OAMG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IAC5D;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,QAAQ,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC;IAC3E;;;;;;;;;;;;;;;;;;;OAmBG;IACH,gBAAgB,CACd,GAAG,EAAE,aAAa,EAClB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,QAAQ,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC;IAG9C,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAC3E;;;;;;OAMG;IACH,YAAY,CACV,GAAG,EAAE,YAAY,EACjB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,YAAY,EAAE,CAAC,CAAC;IAClE;;;;;;;;;;;;OAYG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACnE"}
1
+ {"version":3,"file":"registry-storage.d.ts","sourceRoot":"","sources":["../../src/interfaces/registry-storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Shared MCP-tool search-filter predicate — the reference semantics
3
+ * every {@link RegistryStorage.scanArtifacts} implementation must
4
+ * reproduce for the `tool` / `server` filter dimensions:
5
+ *
6
+ * - `tool` only → any binding entry with that tool name (with or
7
+ * without a `server`).
8
+ * - `server` only → any binding entry declaring that server; bare
9
+ * (server-less) entries never match.
10
+ * - both → a single entry with exactly that (server, tool)
11
+ * pair.
12
+ * - neither → always `true` (the filter is inactive).
13
+ *
14
+ * Matching is case-sensitive exact on both dimensions — MCP tool names
15
+ * are case-sensitive. AND-composes with every other scan-filter
16
+ * dimension; artifacts without bindings never match an active filter.
17
+ */
18
+ import type { McpToolBinding } from '@ggui-ai/artifact-manifest';
19
+ export declare function matchesMcpToolFilters(bindings: ReadonlyArray<McpToolBinding> | undefined, filters: {
20
+ tool?: string;
21
+ server?: string;
22
+ }): boolean;
23
+ //# sourceMappingURL=mcp-tool-filters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-tool-filters.d.ts","sourceRoot":"","sources":["../src/mcp-tool-filters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAEjE,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,aAAa,CAAC,cAAc,CAAC,GAAG,SAAS,EACnD,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1C,OAAO,CAST"}
@@ -0,0 +1,14 @@
1
+ export function matchesMcpToolFilters(bindings, filters) {
2
+ const { tool, server } = filters;
3
+ if (tool === undefined && server === undefined)
4
+ return true;
5
+ if (bindings === undefined || bindings.length === 0)
6
+ return false;
7
+ return bindings.some((binding) => {
8
+ if (tool !== undefined && binding.tool !== tool)
9
+ return false;
10
+ if (server !== undefined && binding.server !== server)
11
+ return false;
12
+ return true;
13
+ });
14
+ }
@@ -7,12 +7,20 @@
7
7
  * 1. Point-read the metadata row via {@link RegistryStorage.getArtifactMetadata}.
8
8
  * Missing metadata → 404 (`not_found`).
9
9
  * 2. Fetch all version rows via {@link RegistryStorage.listArtifactVersions}.
10
- * 3. Filter out private rows for unauthenticated callers — same gate
11
- * as the read op's `visibility === 'private' && authn === undefined`
12
- * branch. We do NOT 403 on a fully-private artifact for an unauthed
13
- * caller; we 200 with `versions: []` so the wire response doesn't
14
- * leak the existence of a private artifact (cf. GitHub's 404-on-
15
- * private-repo behaviour).
10
+ * 3. Filter out private rows the caller cannot read — the same
11
+ * ownership rule as the read op ({@link canReadPrivateArtifact}:
12
+ * publisher or scope owner). Unreadable rows are FILTERED, never
13
+ * errored: an unauthorized caller (anonymous or authenticated)
14
+ * gets the readable subset. When NOTHING is readable, the
15
+ * response is the SAME 404 `not_found` as a true miss — a 200
16
+ * `versions: []` would differ from the miss shape and that
17
+ * difference is an existence oracle (cf. GitHub's
18
+ * 404-on-private-repo behaviour). The scope-owner lookup is lazy,
19
+ * memoized, and fail-closed ({@link createScopeOwnerResolver}):
20
+ * at most one {@link RegistryStorage.getScopeOwner} call per
21
+ * request; none when every row is public, the caller published
22
+ * every private row, or the caller is anonymous; a lookup fault
23
+ * denies instead of erroring.
16
24
  * 4. Sort by semver DESC so the latest version is first. Yanked rows
17
25
  * are NOT filtered — they stay in the list with `yanked: true`
18
26
  * so the UI can show "this version was yanked".
@@ -38,10 +46,11 @@ export interface ListArtifactVersionsInput {
38
46
  export interface ListArtifactVersionsDeps {
39
47
  readonly storage: RegistryStorage;
40
48
  /**
41
- * Optional — when undefined, the op filters `private` versions OUT
42
- * of the response. Authenticated callers see every version they own
43
- * (the storage layer's row-level visibility filter is the source of
44
- * truth; this op just honours it).
49
+ * Optional — the verified caller context, produced by the
50
+ * transport's own credential verification. Private versions appear
51
+ * in the response only for the caller who published them or the
52
+ * owner of the artifact's scope ({@link canReadPrivateArtifact});
53
+ * every other caller — anonymous included — gets the public subset.
45
54
  */
46
55
  readonly authn?: AuthnContext;
47
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"list-versions.d.ts","sourceRoot":"","sources":["../../src/ops/list-versions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAEV,qBAAqB,EAErB,oBAAoB,EAErB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAGzE,MAAM,WAAW,yBAAyB;IACxC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC;CAC/B;AAED,MAAM,MAAM,0BAA0B,GAClC;IACE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;CACrC,GACD;IACE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;CACtC,CAAC;AAEN,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,yBAAyB,EAChC,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,0BAA0B,CAAC,CA6DrC"}
1
+ {"version":3,"file":"list-versions.d.ts","sourceRoot":"","sources":["../../src/ops/list-versions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,KAAK,EAEV,qBAAqB,EAErB,oBAAoB,EAErB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAOzE,MAAM,WAAW,yBAAyB;IACxC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC;CAC/B;AAED,MAAM,MAAM,0BAA0B,GAClC;IACE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;CACrC,GACD;IACE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;CACtC,CAAC;AAEN,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,yBAAyB,EAChC,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,0BAA0B,CAAC,CAsErC"}
@@ -1,4 +1,5 @@
1
1
  import { compareSemver } from '../utils/semver.js';
2
+ import { canReadPrivateArtifact, createScopeOwnerResolver, } from './private-read-authz.js';
2
3
  export async function listArtifactVersions(input, deps) {
3
4
  if (typeof input.artifactId !== 'string' || input.artifactId.length === 0) {
4
5
  return errorResult(400, 'invalid_request', 'missing artifactId');
@@ -12,10 +13,11 @@ export async function listArtifactVersions(input, deps) {
12
13
  metadataExists = metadata !== null;
13
14
  }
14
15
  catch (err) {
15
- return errorResult(500, 'server_error', `failed to read metadata: ${err instanceof Error ? err.message : String(err)}`);
16
+ logStorageFailure('read metadata', input.artifactId, err);
17
+ return errorResult(500, 'server_error', 'failed to list versions');
16
18
  }
17
19
  if (!metadataExists) {
18
- return errorResult(404, 'not_found', `no such artifact: ${input.artifactId}`);
20
+ return notFoundResult(input);
19
21
  }
20
22
  // Step 2 — fetch all version rows.
21
23
  let rows;
@@ -23,18 +25,31 @@ export async function listArtifactVersions(input, deps) {
23
25
  rows = await deps.storage.listArtifactVersions(input.artifactId);
24
26
  }
25
27
  catch (err) {
26
- return errorResult(500, 'server_error', `failed to list versions: ${err instanceof Error ? err.message : String(err)}`);
28
+ logStorageFailure('list version rows', input.artifactId, err);
29
+ return errorResult(500, 'server_error', 'failed to list versions');
27
30
  }
28
- // Step 3 — visibility filter. Unauthed callers see only public rows;
29
- // authed callers see everything (finer org-membership gating is a
30
- // future concern — for now, "authed" === "can see your own private
31
- // rows" is captured by the verified caller subject being non-null).
31
+ // Step 3 — ownership filter. A private row stays in the list only
32
+ // when the caller may read it under the shared rule (publisher or
33
+ // scope owner). All rows share one artifactId, hence one scope —
34
+ // the shared resolver memoizes the lazy owner lookup (one
35
+ // getScopeOwner call at most; none for public rows / anonymous
36
+ // callers / publisher-only matches) and fails CLOSED on a storage
37
+ // fault (deny + server-side log, never a distinctive error status).
38
+ const getScopeOwner = createScopeOwnerResolver(deps.storage, input.artifactId);
32
39
  const visibleRows = [];
33
40
  for (const row of rows) {
34
- if (row.visibility === 'private' && deps.authn === undefined)
41
+ if (row.visibility === 'private' &&
42
+ !(await canReadPrivateArtifact(deps.authn, row, getScopeOwner))) {
35
43
  continue;
44
+ }
36
45
  visibleRows.push(row);
37
46
  }
47
+ // No visible versions ⇒ answer exactly as a true miss. Emitting a
48
+ // 200 `versions: []` here would differ from the miss shape, and
49
+ // that difference is an existence oracle for private artifacts.
50
+ if (visibleRows.length === 0) {
51
+ return notFoundResult(input);
52
+ }
38
53
  // Step 4 — semver DESC sort. `compareSemver(a, b)` returns -1/0/1
39
54
  // matching ascending order; flip the sign for DESC.
40
55
  const sorted = [...visibleRows].sort((a, b) => -compareSemver(a.version, b.version));
@@ -55,6 +70,26 @@ function rowToEntry(row) {
55
70
  visibility: row.visibility,
56
71
  };
57
72
  }
73
+ /**
74
+ * The one not-found projection — used for a true miss AND an artifact
75
+ * with no versions visible to the caller, so the two responses cannot
76
+ * drift apart (drift would reintroduce the existence signal).
77
+ */
78
+ function notFoundResult(input) {
79
+ return errorResult(404, 'not_found', `no such artifact: ${input.artifactId}`);
80
+ }
81
+ /**
82
+ * Structured server-side failure log. Raw storage error text stays
83
+ * OUT of wire bodies (it can carry backend identifiers a caller has
84
+ * no business seeing); this log line is the operator's copy.
85
+ */
86
+ function logStorageFailure(operation, artifactId, err) {
87
+ // eslint-disable-next-line no-console -- server-side operator signal; the wire stays generic
88
+ console.error(`registry list-versions: failed to ${operation}`, {
89
+ artifactId,
90
+ error: err instanceof Error ? err.message : String(err),
91
+ });
92
+ }
58
93
  function errorResult(status, error, message) {
59
94
  return { ok: false, status, body: { error, message } };
60
95
  }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * The single ownership rule for private-row reads.
3
+ *
4
+ * A `visibility: 'private'` row is readable when the verified caller
5
+ * is the row's publisher (`authn.subject === row.publishedBy`) OR the
6
+ * owner of the artifact's scope (`authn.subject === ScopeOwnerRow.
7
+ * ownerSubject`). Everyone else — including anonymous callers — MUST
8
+ * receive a response indistinguishable from "no such artifact" so a
9
+ * probe can never confirm a private artifact exists.
10
+ *
11
+ * Every read-path consumer (the read op, the list-versions op, any
12
+ * transport route that serves private artifact content — bundle and
13
+ * signature byte routes included) MUST authorize through this one
14
+ * predicate. A second hand-rolled comparison is how the rule forks;
15
+ * import this instead. Note the byte-route obligation explicitly:
16
+ * metadata gating alone is insufficient while bundle URLs serve
17
+ * private bytes anonymously — a deployment MUST place its private
18
+ * bundle storage behind a route that applies this same predicate
19
+ * (the hosted deployment's public/private storage-prefix split does
20
+ * exactly that).
21
+ *
22
+ * ## Protocol & Contract Bar
23
+ *
24
+ * **Parties:** read-path ops and transport routes are the callers;
25
+ * the deployment's {@link RegistryStorage.getScopeOwner} backs the
26
+ * lazy scope-owner lookup.
27
+ *
28
+ * **Obligations:** callers MUST pass the verified caller context (or
29
+ * `undefined` for anonymous) — never a caller-supplied subject. The
30
+ * `getScopeOwner` thunk MUST resolve the ownership row for the
31
+ * artifact's scope (see {@link artifactScope}); it is invoked at most
32
+ * once, and ONLY when the caller is authenticated and not the
33
+ * publisher — the hot public path and the publisher fast path incur
34
+ * zero extra storage reads. Callers SHOULD build the thunk via
35
+ * {@link createScopeOwnerResolver}, which adds memoization and the
36
+ * fail-closed error posture.
37
+ *
38
+ * **Failure mode:** {@link createScopeOwnerResolver} resolves a
39
+ * storage failure to `null` (unclaimed) — the owner arm DENIES, the
40
+ * caller answers with its ordinary miss shape, and the fault is
41
+ * logged server-side. Failing open would serve the private row;
42
+ * failing loud (a 5xx only private rows can trigger) would leak
43
+ * existence. A hand-built thunk that rejects propagates to the
44
+ * caller instead — prefer the resolver.
45
+ *
46
+ * **Observable violation:** a private row served to a subject that is
47
+ * neither its `publishedBy` nor its scope's `ownerSubject` — pinned
48
+ * by the op suites (`read.test.ts`, `list-versions.test.ts`) and the
49
+ * server parity suite.
50
+ */
51
+ import type { AuthnContext } from '../interfaces/authn.js';
52
+ import type { RegistryStorage } from '../interfaces/registry-storage.js';
53
+ import type { ArtifactVersionRow, ScopeOwnerRow } from '../types.js';
54
+ /**
55
+ * Decide whether `authn` may read a private row.
56
+ *
57
+ * @param authn verified caller context; `undefined` for anonymous.
58
+ * @param row the private row under decision (only `publishedBy` is
59
+ * consulted — pass the full row or a narrowed projection).
60
+ * @param getScopeOwner lazy scope-owner lookup for the artifact's
61
+ * scope. Called at most once, only when the publisher fast path
62
+ * misses. Build it with {@link createScopeOwnerResolver} for
63
+ * memoization + fail-closed semantics.
64
+ */
65
+ export declare function canReadPrivateArtifact(authn: AuthnContext | undefined, row: Pick<ArtifactVersionRow, 'publishedBy'>, getScopeOwner: () => Promise<ScopeOwnerRow | null>): Promise<boolean>;
66
+ /**
67
+ * Build the memoized, fail-closed `getScopeOwner` thunk for
68
+ * {@link canReadPrivateArtifact}.
69
+ *
70
+ * - **Lazy** — no storage read happens until the owner arm is
71
+ * actually needed (public rows, anonymous callers, and publisher
72
+ * matches never trigger one).
73
+ * - **Memoized** — a caller checking many rows of one artifact
74
+ * (the list op) pays for at most one lookup.
75
+ * - **Fail-closed** — a storage failure resolves to `null`
76
+ * (unclaimed ⇒ deny) and is logged server-side with structure;
77
+ * the raw error never reaches a wire body. See the failure-mode
78
+ * section above for why neither fail-open nor fail-loud is
79
+ * acceptable here.
80
+ */
81
+ export declare function createScopeOwnerResolver(storage: Pick<RegistryStorage, 'getScopeOwner'>, artifactId: string): () => Promise<ScopeOwnerRow | null>;
82
+ /**
83
+ * Extract the scope segment (leading `@` included) from a canonical
84
+ * `<@scope>/<name>` artifactId — the key for
85
+ * {@link RegistryStorage.getScopeOwner}.
86
+ */
87
+ export declare function artifactScope(artifactId: string): string;
88
+ //# sourceMappingURL=private-read-authz.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"private-read-authz.d.ts","sourceRoot":"","sources":["../../src/ops/private-read-authz.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAErE;;;;;;;;;;GAUG;AACH,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,YAAY,GAAG,SAAS,EAC/B,GAAG,EAAE,IAAI,CAAC,kBAAkB,EAAE,aAAa,CAAC,EAC5C,aAAa,EAAE,MAAM,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,GACjD,OAAO,CAAC,OAAO,CAAC,CAKlB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,IAAI,CAAC,eAAe,EAAE,eAAe,CAAC,EAC/C,UAAU,EAAE,MAAM,GACjB,MAAM,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAiBrC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAGxD"}