You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(spec): discovery reports which optional `/auth` route families are mounted, starting with the better-auth admin family (`authFamilies.admin`) (#21046)
8
+
9
+
Clause-②: yes
10
+
11
+
**New key.**`DiscoverySchema` declares an optional `authFamilies` block, `{ admin: boolean }`. `admin` says whether the better-auth admin family (`{routes.auth}/admin/*`: `list-users`, `set-role`, `update-user`, `ban-user`, …) is mounted on this deployment. On a deployment that does not enable the admin plugin those routes answer a plain `404`, the same as a mistyped path, so a caller checks `authFamilies.admin` before building a URL into the family. `@objectstack/spec/api` also exports the block's schema (`AuthFamiliesSchema`, type `AuthFamilies`) and its reader, `readAuthFamilies(authService)`.
12
+
13
+
**Same answer as `/auth/config`.** The value is the auth service's own `getPublicConfig().features.admin`, the object `GET /api/v1/auth/config` serves. Both discovery producers read it through `readAuthFamilies`: `getDiscovery()` in `@objectstack/metadata-protocol` (served by `@objectstack/rest` at `GET /api/v1/discovery`) and `getDiscoveryInfo()` in `@objectstack/runtime` (served at `GET /.well-known/objectstack`). Neither re-derives whether the admin plugin is on, so on one boot the two documents and `/auth/config` agree. On a stock boot `authFamilies.admin` is `false`. With the admin plugin on (`plugins.admin: true`, or SCIM, which forces it on) it is `true`.
14
+
15
+
**When the key is absent.** A producer that cannot read the answer emits no `authFamilies`, rather than a guessed `false`. That happens when no `auth` service is registered (then `routes.auth` is absent too), when the registered service has no `getPublicConfig()`, or when that call throws (`/auth/config` answers `500 AUTH_CONFIG_ERROR` in that state). Treat an absent block as "not known to be mounted".
16
+
17
+
**What did not change.** No existing key, route or status moved. The unmounted admin routes still answer a plain `404`.
Copy file name to clipboardExpand all lines: content/docs/references/api/discovery.mdx
+23-3Lines changed: 23 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,7 @@
1
1
---
2
2
title: Discovery schema — API Protocol reference
3
3
navTitle: Discovery
4
-
description: "Discovery schemas of the ObjectStack API Protocol: ApiRoutes, CapabilityDescriptor and 9 more — each property with its type, default and a TypeScript example."
4
+
description: "Discovery schemas of the ObjectStack API Protocol: ApiRoutes, AuthFamilies and 10 more — each property with its type, default and a TypeScript example."
5
5
---
6
6
7
7
{/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */}
@@ -13,8 +13,8 @@ description: "Discovery schemas of the ObjectStack API Protocol: ApiRoutes, Capa
@@ -47,6 +47,19 @@ const result = ApiRoutesSchema.parse(data);
47
47
|**mcp**|`string`| optional | e.g. /api/v1/mcp — always the unscoped base; absent when MCP is disabled or unserveable |
48
48
49
49
50
+
---
51
+
52
+
## AuthFamilies
53
+
54
+
Which optional better-auth route families are mounted under routes.auth
55
+
56
+
### Properties
57
+
58
+
| Property | Type | Required | Description |
59
+
| :--- | :--- | :--- | :--- |
60
+
|**admin**|`boolean`| ✅ | Whether the better-auth admin family (`{routes.auth}`/admin/*: list-users, set-role, update-user, ban-user, …) is mounted. Same value as features.admin on GET `{routes.auth}`/config, read from the same source; false means those routes answer a plain 404 on this deployment. |
61
+
62
+
50
63
---
51
64
52
65
## CapabilityDescriptor
@@ -77,6 +90,7 @@ const result = ApiRoutesSchema.parse(data);
77
90
|**capabilities**|`{ comments: object; automation: object; cron: object; search: object; … }`| ✅ | Hierarchical capability descriptors — the full WellKnownCapabilities vocabulary, every key present |
78
91
|**schemaDiscovery**|`{ openapi?: string; jsonSchema?: string }`| optional | Schema discovery endpoints for API toolchain integration |
|**authFamilies**|`{ admin: boolean }`| optional | Which optional better-auth route families are mounted under routes.auth — the same source as GET `{routes.auth}`/config features; absent when no auth service answers |
@@ -148,6 +162,12 @@ const result = ApiRoutesSchema.parse(data);
148
162
|**scoped**|`boolean`| ✅ | Whether THIS response was served from the environment-scoped mount |
149
163
|**environmentId**|`string`| optional | The resolved environment id — present only on a scoped mount |
150
164
165
+
### Nested Shape: `Discovery.authFamilies`
166
+
167
+
| Property | Type | Required | Description |
168
+
| :--- | :--- | :--- | :--- |
169
+
|**admin**|`boolean`| ✅ | Whether the better-auth admin family (`{routes.auth}`/admin/*: list-users, set-role, update-user, ban-user, …) is mounted. Same value as features.admin on GET `{routes.auth}`/config, read from the same source; false means those routes answer a plain 404 on this deployment. |
|**authFamilies**|`{ admin: boolean }`| optional | Which optional better-auth route families are mounted under routes.auth — the same source as GET `{routes.auth}`/config features; absent when no auth service answers |
|**admin**|`boolean`| ✅ | Whether the better-auth admin family (`{routes.auth}`/admin/*: list-users, set-role, update-user, ban-user, …) is mounted. Same value as features.admin on GET `{routes.auth}`/config, read from the same source; false means those routes answer a plain 404 on this deployment. |
|[Automation Protocol](/docs/references/automation)| 14 | 75 | Flows and their nodes, approvals, ETL pipelines, webhooks, state machines, execution records. |
26
26
|[Data Protocol](/docs/references/data)| 30 | 178 | Objects, fields, queries, filters, datasources and drivers — the ObjectQL layer. |
0 commit comments