Skip to content

Comment moderation is dead behind the platform delete floor: a parent-editor cannot remove another user's comment in any org-bound deployment #8839

Description

@qq9340100

Found while sweeping the dogfood fixtures for #8408 (#8023's org-less disarm). Filed unassigned; grading and routing are the triage seat's call.

The defect

plugin-audit's comment access gate implements an explicit author-or-parent-editor rule for removing a comment (packages/plugins/plugin-audit/src/comment-access-hooks.ts):

"Rewriting or removing someone else's words is moderation, hence the tighter author-or-parent-editor rule."

That rule is unreachable in any org-bound deployment. The platform's wildcard row-level delete floor —

{ name: 'owner_only_deletes', object: '*', operation: 'delete',
using: 'created_by == current_user.id', positions: ['org_member'] }

(packages/plugins/plugin-security/src/objects/default-permission-sets.ts) — refuses a non-author's DELETE /data/sys_comment/{id} before the moderation rule is ever consulted. A parent-record editor moderating someone else's comment holds org_member and is not the comment's created_by, so the floor denies with PERMISSION_DENIED.

Net effect: comment moderation does not work in a real deployment. The capability plugin-audit implements is dead behind the platform floor.

Why nothing caught it

packages/qa/dogfood/test/comments-permission-matrix.dogfood.test.ts case (d) a user who can EDIT the record may moderate anyone's comment on it is the fixture that proves the capability. It boots org-less, so its principals resolve positions: ['everyone'], the positions-gated floor never applies, and the case passes over the broken behaviour — exactly #8023's shape.

Measured, on b705a6ce2

Flipping only that fixture's boot to orgContext: true (nothing else changed):

WARN [Security] Access denied: not permitted to delete this 'sys_comment' record
(row-level security) {"operation":"delete","object":"sys_comment",
"positions":["org_member","everyone"], ...}
AssertionError: {"error":"You do not have access to this record. ...",
"code":"PERMISSION_DENIED","object":"sys_comment"}: expected 403 to be less than 300
at test/comments-permission-matrix.dogfood.test.ts:191
Tests 1 failed | 9 passed (10)

The other 9 cases stay green, including (d)'s first half (the author deleting their own comment), which the floor permits because created_by matches. So the disarm is isolated to the moderation limb.

The two readings, for triage

  1. Product defect (my reading): moderation is a declared, implemented capability and the floor should not pre-empt it — sys_comment needs a per-object delete policy contributing the author-or-parent-editor alternate match, the way the better-auth tables get their *_self policies in the same file.
  2. Fixture over-claim: moderation was never intended to survive the ownership floor, and case (d) asserts a capability the platform does not offer. Then the fixture is what changes.

I did not pick between them — #8408's scope is packages/qa/dogfood/test/ and either fix lands outside it. #8408 records this fixture as blocked on this card rather than arming it, since arming without the underlying decision would land a red test.

Related


Generated by Claude Code

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions