Skip to content

Row-level write gate consults neither modifyAllRecords nor sys_record_share.access_level — both declared write-widening mechanisms are inert #5492

Description

@yinlianghui

Part of objectstack-ai/hotcrm#705

Found during HotCRM's 17.0 GA acceptance sweep on @objectstack/* 17.0.0-rc.2, permission matrix phase. Two write-widening mechanisms, both inert; filed together because they share one root: the row write gate consults neither.

Measured

The effective row write gate is: owner_id == caller AND (member_default's wildcard RLS owner_only_writes: created_by == caller, OR an explicit RLS update-widener). Nothing else widens writes.

1. modifyAllRecords is inert. A manager profile with declared viewAll + modifyAll on its core objects got 403 row-level on every cross-owner write probed (update AND delete, four objects). Reads widen exactly as declared (43/43, 9/9); writes never.

2. Edit-level shares grant read only. All three edit-level sharing rules verified to materialize in sys_record_share (incl. a fixture created after rule evaluation — the hook fires; and clean revocation on unbinding) and to widen reads exactly. But a PATCH by the share target on the shared record → 403 row-level, every time. The write gate does not consult sys_record_share.access_level.

Corollary from the other side: read-level shares correctly deny writes — the share machinery distinguishes levels on paper, and the write gate then ignores the distinction.

Reproduction

# as a manager-profile user with modifyAllRecords on crm_opportunity
PATCH /api/v1/data/crm_opportunity/<other-owner-record> {"next_step":"x"}
→ 403 "[Security] … not permitted to update this 'crm_opportunity' record (row-level security)"
# share row present (object=crm_account, access_level=edit, target=<user>):
PATCH that account as the share target → 403 (same shape)

Impact

A manager cannot correct, reassign, or clean up anything they didn't personally create; every "manager fixes it" workflow is unimplementable. Org-admin is the only identity that can write across owners.

Prior related issues (checked)

Evidence: HotCRM acceptance run w4/results.jsonl (M3/M4/M8). Sibling: objectstack-ai/hotcrm#703 (the same member_default wildcard RLS supplies the created_by co-gate).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions