diff --git a/.github/upstream-projects.yaml b/.github/upstream-projects.yaml index 7182c2b6..2ef59d3c 100644 --- a/.github/upstream-projects.yaml +++ b/.github/upstream-projects.yaml @@ -29,7 +29,7 @@ projects: - id: toolhive-registry-server repo: stacklok/toolhive-registry-server - version: v1.5.1 + version: v1.5.2 docs_paths: - docs/toolhive/guides-registry - docs/toolhive/concepts/registry-criteria.mdx diff --git a/docs/toolhive/guides-registry/configuration.mdx b/docs/toolhive/guides-registry/configuration.mdx index f84901ab..deb65d2c 100644 --- a/docs/toolhive/guides-registry/configuration.mdx +++ b/docs/toolhive/guides-registry/configuration.mdx @@ -475,17 +475,63 @@ spec: # ... MCP server spec ``` -| Annotation | Required | Description | -| -------------------------------------------- | -------- | --------------------------------------------------------------------------------- | -| `toolhive.stacklok.dev/registry-export` | Yes | Must be `"true"` to include in registry | -| `toolhive.stacklok.dev/registry-url` | Yes | The external endpoint URL for this server | -| `toolhive.stacklok.dev/registry-description` | Yes | Description text displayed in registry listings | -| `toolhive.stacklok.dev/registry-title` | No | Human-friendly display name for the registry entry (overrides the generated name) | -| `toolhive.stacklok.dev/registry-icon` | No | Icon URL displayed alongside the entry in registry listings | -| `toolhive.stacklok.dev/registry-category` | No | Category label used to group and filter this entry (added as a ToolHive tag) | -| `toolhive.stacklok.dev/tools` | No | JSON array of tool name strings (e.g., `["get_weather","get_forecast"]`) | -| `toolhive.stacklok.dev/tool-definitions` | No | JSON array of tool definitions with MCP tool metadata (name, description, schema) | -| `toolhive.stacklok.dev/authz-claims` | No | JSON object of authorization claims for per-entry visibility control | +| Annotation | Required | Description | +| -------------------------------------------- | -------- | ----------------------------------------------------------------------------------------- | +| `toolhive.stacklok.dev/registry-export` | Yes | Must be `"true"` to include in registry | +| `toolhive.stacklok.dev/registry-url` | Yes | The external endpoint URL for this server | +| `toolhive.stacklok.dev/registry-description` | Yes | Description text displayed in registry listings | +| `toolhive.stacklok.dev/registry-title` | No | Human-friendly display name for the registry entry (overrides the generated name) | +| `toolhive.stacklok.dev/registry-icon` | No | Icon URL displayed alongside the entry in registry listings | +| `toolhive.stacklok.dev/registry-category` | No | Category label used to group and filter this entry (added as a ToolHive tag) | +| `toolhive.stacklok.dev/tools` | No | JSON array of tool name strings (e.g., `["get_weather","get_forecast"]`) | +| `toolhive.stacklok.dev/tool-definitions` | No | JSON array of tool definitions with MCP tool metadata (name, description, schema) | +| `toolhive.stacklok.dev/authz-claims` | No | JSON object of authorization claims for per-entry visibility control | +| `toolhive.stacklok.dev/registry-version` | No | Semantic version string used as the entry's version (see [Entry version](#entry-version)) | + +#### Entry version + +Each registry entry has a version that appears in its identifier and in +`GET .../versions/{version}` URLs. For entries discovered from Kubernetes +resources, the version is resolved with this precedence: + +1. The `toolhive.stacklok.dev/registry-version` annotation, when set to a value + the server accepts as publishable. +2. The container image tag for resources that run an image. When the reference + pins both a tag and a digest (for example, `db:1.4.2@sha256:...`), the tag is + used and the digest is ignored for version selection. +3. `1.0.0` as the fallback. + +`VirtualMCPServer` and `MCPRemoteProxy` resources run no image, so the +annotation is the only route to a non-default version. + +A publishable value is a three-part semantic version (`major.minor.patch`), +optionally `v`-prefixed and optionally carrying a prerelease (for example, +`v2.1.0-rc.1`). Build metadata (`+build`) is rejected because semver comparison +ignores it, so two versions differing only in metadata would sort equal but be +stored as distinct entries. The value must be 255 characters or fewer. + +Values the server can't publish (reserved strings like `latest`, ranges like +`1.x`, whitespace, or oversized values) are ignored, and the server falls back +to the image tag (when publishable) or `1.0.0`. An ignored annotation is logged +as a warning naming the server and namespace so operators can correct it. An +unpublishable image tag (`latest`, channel names, bare digests, or fewer than +three parts like `3.12`) also falls through without a warning, since untagged +and `latest` images are routine. + +The `v` prefix is preserved as written: `v2.1.0` stays `v2.1.0` in the entry's +identifier and URLs. + +:::info[Changed in v1.5.2] + +Entries discovered from Kubernetes resources previously always published as +`1.0.0`. After upgrading, entries whose images carry a semver-compatible tag +move to that tag on the next reconcile, and the previous `1.0.0` entry is +removed. `GET .../versions/1.0.0` starts returning 404 for those entries, and +any cached version ID breaks. Set the `toolhive.stacklok.dev/registry-version` +annotation to override this per resource. Entries with `latest`, channel-name, +untagged, or digest-only images are unaffected. + +::: #### Tool definitions format diff --git a/static/api-specs/toolhive-registry-api.yaml b/static/api-specs/toolhive-registry-api.yaml index 32cdaaa7..b531a352 100644 --- a/static/api-specs/toolhive-registry-api.yaml +++ b/static/api-specs/toolhive-registry-api.yaml @@ -872,6 +872,37 @@ components: semantic version or a commit hash. type: string type: object + registry.Provenance: + description: |- + Provenance is the expected signer identity for this skill, checked on + first install instead of trust-on-first-use. Absent means unconstrained + — most catalog entries won't have this for a while, and that must not + break installs; it's an opt-in tightening per entry, not a requirement. + + Each field constrains independently, and an empty string leaves that + dimension unconstrained. Attestation is the exception: setting it at + all, even to an empty struct, requires the artifact to be attested, so + verification fails against a signature carrying no statement. Its own + PredicateType and Predicate then follow the usual rule and constrain + only when set. Predicate must be a JSON object; anything else can never + match, and Validate rejects it rather than letting it through as a + constraint that silently fails every artifact. + properties: + attestation: + $ref: '#/components/schemas/registry.VerifiedAttestation' + cert_issuer: + type: string + repository_ref: + type: string + repository_uri: + type: string + runner_environment: + type: string + signer_identity: + type: string + sigstore_url: + type: string + type: object registry.Skill: properties: _meta: @@ -924,6 +955,8 @@ components: $ref: '#/components/schemas/registry.SkillPackage' type: array uniqueItems: false + provenance: + $ref: '#/components/schemas/registry.Provenance' repository: $ref: '#/components/schemas/registry.SkillRepository' status: @@ -997,6 +1030,12 @@ components: description: URL is the URL of the repository. type: string type: object + registry.VerifiedAttestation: + properties: + predicate: {} + predicate_type: + type: string + type: object v0.Metadata: properties: count: @@ -1916,14 +1955,6 @@ paths: type: string type: object description: Internal server error - "503": - content: - application/json: - schema: - additionalProperties: - type: string - type: object - description: No managed source available summary: Get entry claims tags: - v1 @@ -1988,14 +2019,6 @@ paths: type: string type: object description: Internal server error - "503": - content: - application/json: - schema: - additionalProperties: - type: string - type: object - description: No managed source available summary: Update entry claims tags: - v1