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
{{ message }}
Repository navigation
Commit 92e6b2f
Browse filesBrowse the repository at this point in the historyBrowse files
fix(rest): the app row of the stored-version doors waits on a decision; cite landing commits for two cards that no longer resolve
The refuse-on-partial app arm on /layers, ?layers=true and /diff drew a new
permission boundary: it locked any author lacking one entry's permission,
platform admins included, out of the designer's layered view. It is removed
whole: those three doors serve the stored app exactly as before the gate, and
the census pins those cells as a declared pending-decision exemption anchored
to the card. Every other arm stands.
The two citations the shared gate moved (the plural-spelling and folded-type
cards) no longer resolve on the board; they now name the commits that landed
them.
Claude-Session: https://claude.ai/code/session_01UYBdGBzWSrAMzpW8ah3GbP
Co-authored-by: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: .changeset/20156-alternate-door-read-gates.md
+9-9Lines changed: 9 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,18 +2,18 @@
2
2
"@objectstack/rest": patch
3
3
---
4
4
5
-
**Every read door beside `GET /api/v1/meta/:type/:name` now applies the same per-caller read gate as the plain read.** The plain read withholds a document per caller in four ways: the documentation audience on `doc` and `book`(a `{ permissionSet }`-gated doc or book is `403 PERMISSION_DENIED` to a non-holder, `401 UNAUTHENTICATED` to an anonymous caller), the app navigation filter on `app` (an app whose `requiredPermissions` the caller lacks is `403`, an unpublished app is `404` to a non-builder, and entries gated by `requiredPermissions` or the docs audience are left out), and the field mask on `object` schemas. The doors beside it served the same stored document with none of those gates:
5
+
**The read doors beside `GET /api/v1/meta/:type/:name` now apply the plain read's per-caller gates to docs, books and object schemas.** The plain read withholds a document per caller in several ways. On `doc` and `book`it applies the documentation audience: a `{ permissionSet }`-gated doc or book is `403 PERMISSION_DENIED` to a non-holder and `401 UNAUTHENTICATED` to an anonymous caller. On `app` it applies the navigation filter: an app whose `requiredPermissions` the caller lacks is `403`, an unpublished app is `404` to a non-builder, and gated entries are left out. On `object` schemas it applies the field mask. It also applies the optional-service widget gate on `dashboard`. The doors beside it served the same stored document with none of those gates:
6
6
7
7
-`GET …/:name/layers`, and the deprecated `GET …/:name?layers=true`, served every layer. This exposed a gated doc's or book's body to any signed-in member. Through `?layers=true`, which sits on the route anonymous callers may reach for public docs, it also exposed any doc or book to a caller who was not signed in.
8
-
-`GET …/:name/published` served a gated doc's or book's body, a gated or unpublished app whole, and an object schema's unreadable fields.
9
-
-`GET …/:name/diff` served both compared versions' values, including a doc's content, an app's navigation and an object's fields.
10
-
-`GET …/:name/history` and `GET …/:name/audit` served the change log and audit trail of an item the caller may not open.
8
+
-`GET …/:name/published` served a gated doc's or book's body, a gated or unpublished app whole, a dashboard's widgets bound to an optional service this deployment lacks, and an object schema's unreadable fields.
9
+
-`GET …/:name/diff` served both compared versions' values, including a doc's content and an object's fields.
10
+
-`GET …/:name/history` and `GET …/:name/audit` served the change log and audit trail of a doc, book or app the caller may not open.
11
11
12
12
What each door answers now:
13
13
14
-
-`/published` answers exactly what the plain read answers the same caller: the same refusal, or the same pruned or masked document.
15
-
-`/layers`, `?layers=true` and `/diff`serve stored versions. Where the plain read refuses the item, they refuse it with the same status and code. Where the plain read would serve a caller only part of an app, they answer `403 PERMISSION_DENIED` instead of a pruned version, because Studio's designer saves back what it loads, and a pruned version saved back deletes the entries withheld from that caller. They mask object fields as the plain read does. Per-deployment gates are not applied to them: a dashboard widget or app entry whose optional service is off in this deployment is still shown, because it is stored.
16
-
-`/history`and `/audit` answer the plain read's refusal when the plain read refuses the item whole. Otherwise they serve the events, which carry no document body.
17
-
-`/diff` of a `doc`, `book` or `app` with nothing behind the name answers `404 RESOURCE_NOT_FOUND`, as the plain read does.
14
+
-`/published` answers exactly what the plain read answers the same caller, for every type: the same refusal, or the same pruned or masked document. That includes the dashboard widget gate: a widget bound to an optional service this deployment does not register is left out of `/published`, as it is from the plain read.
15
+
-`/layers`, `?layers=true` and `/diff`refuse a `doc` or `book`the plain read refuses, with the same status and code, and mask object fields as the plain read does. `/diff`of a `doc` or `book` with nothing behind the name answers `404 RESOURCE_NOT_FOUND`, as the plain read does. They do not apply the dashboard widget gate or any other per-deployment gate: they show the stored version, which is what an author edits.
16
+
-**For `app`, `/layers`, `?layers=true`and `/diff` are unchanged in this release.** They still serve the stored app, including navigation entries the plain read withholds from the caller, to every signed-in caller. What they should answer is pending a decision, because both ways of matching the plain read restrict authors. Pruning the stored app would delete the withheld entries when Studio's designer saves back what it loaded. Refusing it would lock out any author who lacks one entry's permission, platform admins included.
17
+
-`/history` and `/audit` answer the plain read's refusal when the plain read refuses the doc, book or app whole. Otherwise they serve the events, which carry no document body.
18
18
19
-
Nothing changes for a caller the plain read serves in full: every door answers as before. Types no per-caller gate judges (`view`, `flow`, and others) are untouched on every door. A client reading these doors as a caller the plain read restricts now receives the plain read's answer. That includes an integration reading `?layers=true` anonymously. To read a gated doc, hold the permission set its book names. To use the layered view or the diff of an app, hold every permission its entries require.
19
+
Types no per-caller gate judges, such as `view` and `flow`, are unchanged on every door. `dashboard` is unchanged on every door except `/published`. A caller the plain read serves in full gets the same answers as before. A client reading these doors as a caller the plain read restricts now receives the plain read's answer, including an integration reading `?layers=true` anonymously. To read a gated doc or book through any of these doors, hold the permission set its book names.
0 commit comments