Skip to content

Commit 2123ea4

Browse files
rdimitrovclaude
andcommitted
Address PR review findings from Dan Barr
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 81e522e commit 2123ea4

4 files changed

Lines changed: 25 additions & 35 deletions

File tree

docs/toolhive/guides-registry/authorization.mdx

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ who can manage sources, registries, and entries. Authorization builds on top of
1010
[authentication](./authentication.mdx) — you need OAuth authentication enabled
1111
before configuring authorization.
1212

13-
Claims operate at three layers, checked in order when a client reads entries:
13+
## How authorization works
14+
15+
When a client accesses registry data, the server checks three layers in order:
1416

1517
1. **Registry claims** (access gate) — can the caller access this registry at
1618
all? If the registry has claims and the caller's JWT doesn't satisfy them,
@@ -23,17 +25,6 @@ Claims operate at three layers, checked in order when a client reads entries:
2325
operation? Publishing, deleting, and managing sources/registries require
2426
specific [roles](#configure-roles).
2527

26-
## How authorization works
27-
28-
Authorization in the Registry server operates at two levels:
29-
30-
1. **Role-based access control (RBAC)**: Determines which admin operations a
31-
caller can perform (manage sources, manage registries, publish/delete
32-
entries).
33-
2. **Claims-based scoping**: Limits visibility and access to specific sources,
34-
registries, and entries based on key-value claims attached to both resources
35-
and callers.
36-
3728
When a caller makes an API request, the server:
3829

3930
1. Extracts the caller's claims from their JWT token
@@ -221,16 +212,21 @@ caller's claims must be a superset of the resource's claims. For example:
221212
| `{org: "acme"}` | `{org: "contoso"}` | Denied |
222213

223214
Registries and sources with no claims are accessible to all authenticated
224-
callers. However, **entries** with no claims behave differently: they are
225-
visible in anonymous mode and [auth-only mode](#auth-only-mode), but invisible
226-
when full authorization is enabled. With authorization, the per-entry filter
227-
requires both sides to have claims for a match — so entries without claims are
228-
filtered out. To make entries visible to authorized callers, attach claims to
229-
the source (for synced sources) or to individual entries (via the publish
215+
callers.
216+
217+
:::warning[Entries without claims are invisible when authorization is enabled]
218+
219+
Entries with no claims are visible in anonymous mode and
220+
[auth-only mode](#auth-only-mode), but **invisible** when full authorization is
221+
enabled. The per-entry filter requires both sides to have claims for a match —
222+
entries without claims are filtered out. To make entries visible, attach claims
223+
to the source (for synced sources) or to individual entries (via the publish
230224
payload or the
231225
[`authz-claims` annotation](./configuration.mdx#per-entry-claims-via-annotation)
232226
for Kubernetes sources).
233227

228+
:::
229+
234230
## Claims on published entries
235231

236232
When you publish an MCP server version or skill to a managed source, you can

docs/toolhive/guides-registry/configuration.mdx

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -429,16 +429,12 @@ is fixed.
429429
See [Authorization](./authorization.mdx) for how claims control entry
430430
visibility.
431431

432-
:::info[How does it work?]
432+
#### Workload annotations
433433

434-
Kubernetes workload discovery works by looking for annotations in a specific set
435-
of workloads. The types being watched are
434+
Kubernetes workload discovery watches for annotations on
436435
[`MCPServer`](../guides-k8s/run-mcp-k8s.mdx),
437436
[`MCPRemoteProxy`](../guides-k8s/remote-mcp-proxy.mdx), and
438-
[`VirtualMCPServer`](../guides-vmcp/configuration.mdx).
439-
440-
The Registry server will receive events when a resource among those listed above
441-
is annotated with the following annotations:
437+
[`VirtualMCPServer`](../guides-vmcp/configuration.mdx) resources.
442438

443439
```yaml {7-16}
444440
apiVersion: toolhive.stacklok.dev/v1alpha1
@@ -472,7 +468,7 @@ spec:
472468
| `toolhive.stacklok.dev/tool-definitions` | No | JSON array of tool definitions with MCP tool metadata (name, description, schema) |
473469
| `toolhive.stacklok.dev/authz-claims` | No | JSON object of authorization claims for per-entry visibility control |
474470

475-
**Tool definitions format:**
471+
#### Tool definitions format
476472

477473
The `tool-definitions` annotation accepts a JSON array containing tool metadata
478474
that follows the MCP specification. Each tool definition can include:
@@ -512,8 +508,6 @@ This feature requires the Registry server to be granted access to those
512508
resources via a Service Account. See the
513509
[deployment section](./deploy-manual.mdx#workload-discovery) for details.
514510

515-
:::
516-
517511
**Use cases:**
518512

519513
- Discover MCP servers deployed via ToolHive Operator

docs/toolhive/guides-registry/deploy-operator.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,8 @@ spec:
174174
:::tip
175175

176176
You can use `branch`, `tag`, or `commit` to pin to a specific version. If
177-
multiple are specified, `commit` takes precedence over `tag`, which takes
178-
precedence over `branch`.
177+
multiple are specified, `commit` takes precedence over `branch`, which takes
178+
precedence over `tag`.
179179

180180
:::
181181

docs/toolhive/guides-registry/skills.mdx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ upstream registry format.
2121
- If authentication is enabled, a valid bearer token (see
2222
[Authentication](./authentication.mdx))
2323

24-
## API base path
24+
## API paths
2525

26-
All skills endpoints use the following base path:
26+
Skills use two API path families:
2727

28-
```text
29-
/{registryName}/v0.1/x/dev.toolhive/skills
30-
```
28+
- **Browse endpoints** (list, get, search) use the registry-scoped path:
29+
`/{registryName}/v0.1/x/dev.toolhive/skills`
30+
- **Admin endpoints** (publish, delete) use the `/v1/entries` path
3131

3232
Replace `{registryName}` with the `name` of the registry as defined in your
3333
[configuration file](./configuration.mdx) (for example, `my-registry` if your

0 commit comments

Comments
 (0)