From e551e42ff9c67c196caf7a6a5c904105b7999d2e Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 18 Oct 2026 05:10:02 +0000 Subject: [PATCH] docs(skills): objectstack-api says the form's own publicFormGrant authorizes a public submit and the guest_portal name admits nothing The public-form passage of skills/objectstack-api/SKILL.md described the anonymous form endpoints as running under a synthetic `{ permissions: ['guest_portal'], anonymous: true }` context and named nothing else, so an author inferred that a guest_portal permission set authorizes the submit, or that the form falls open without one. It now names the declaration-derived publicFormGrant (create and read-back of the row it made on the form's target object, nothing else, decided before any permission set resolves) as what authorizes the submit, and says that the guest_portal name admits nothing and needs no set: one registered under it only feeds the grant's result masker. Matches the docs page and the registerFormEndpoints docstring. Text only; a patch changeset for @objectstack/skills. Claude-Session: https://claude.ai/code/session_01QBcLjVCmcWbZEk6qhYMib2 Co-authored-by: Claude --- .changeset/24239-public-form-grant-skill.md | 9 +++++++++ skills/objectstack-api/SKILL.md | 8 +++++--- 2 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 .changeset/24239-public-form-grant-skill.md diff --git a/.changeset/24239-public-form-grant-skill.md b/.changeset/24239-public-form-grant-skill.md new file mode 100644 index 00000000000..7e013eb9660 --- /dev/null +++ b/.changeset/24239-public-form-grant-skill.md @@ -0,0 +1,9 @@ +--- +'@objectstack/skills': patch +--- + +docs(skills): `objectstack-api` states that a public form's submit is authorized by the form's own `publicFormGrant`, and that the `guest_portal` name on the submit context admits nothing and needs no permission set (#24239) + +Clause-②: no + +`skills/objectstack-api/SKILL.md` described the anonymous form endpoints as running under a synthetic `{ permissions: ['guest_portal'], anonymous: true }` execution context and named nothing else, so an author reading it inferred that a `guest_portal` permission set authorizes the submit and declared one, or concluded that the form falls open without one. Neither is true: the submit is authorized by the form's own declaration (ADR-0056 Option A) — the route hands the engine a `publicFormGrant` scoped to the form's target object, which admits the create and the read-back of the row it made and nothing else, decided before any permission set resolves. The `guest_portal` name on the context admits nothing; where a deployment registers a set under it, that set only feeds the grant's result masker. The passage now says so, matching `content/docs/ui/public-data-collection.mdx` and the `registerFormEndpoints` docstring in `@objectstack/rest`. Text only; nothing an author writes changes, and the form routes' behaviour is unchanged. diff --git a/skills/objectstack-api/SKILL.md b/skills/objectstack-api/SKILL.md index 2d55cd4fa2f..74567684b73 100644 --- a/skills/objectstack-api/SKILL.md +++ b/skills/objectstack-api/SKILL.md @@ -84,9 +84,11 @@ GET /api/v1/forms/:slug # returns form spec + restricted objectSchema POST /api/v1/forms/:slug/submit # whitelist-filtered INSERT, no auth header ``` -These bypass `enforceAuth`, run under a synthetic -`{ permissions: ['guest_portal'], anonymous: true }` execution context, and -are intended for Web-to-Lead / Web-to-Case style flows. The framework +These bypass `enforceAuth` (Web-to-Lead / Web-to-Case flows). The form's own +declaration authorizes the submit: a `publicFormGrant` on its target object +(create and read-back of its new row, nothing else), decided before any permission +set resolves. The submit context's `guest_portal` name admits nothing and needs +no set; a set so named only feeds the grant's result masker. The framework strips fields outside the form's `sections[].fields[]` list; a `beforeInsert` hook on the target object should stamp safe defaults (`status='new'`, `lead_source='web'`, …) and `delete` privileged keys