Repository navigation
[17.0-rc][疑似平台] script action 的 body 写库被 FORBIDDEN(admin 用户) #521
Description
Activity
源码确认:CONFIRMED,平台 bug。action body 的 ctx.api 回退到无 ExecutionContext/无 isSystem 的 facade(body-runner.ts:161-184),plugin-sharing 的 canEdit 在 !context.userId 直接拒(sharing-service.ts:255);hook body 却有 isSystem:true 兜底(engine.ts:978-981)。审计行描述的是 ctx.engine 不是 ctx.api。注意:public sharing / 无 owner 字段的对象会碰巧放行,掩盖问题。已上报平台:objectstack-ai/objectstack#3914
- addedupstream:objectstackBlocked on / caused by the ObjectStack platform — tracked upstreamBlocked on / caused by the ObjectStack platform — tracked upstream
on Aug 2, 2026 rc.2 retest: 已解除 — script-body writes persist; zero FORBIDDEN across the whole run
Retested on
@objectstack/*17.0.0-rc.2 (currentmain, commit 5a78f88), during the acceptance run's full action sweep (all 26 actions + flow executions).Evidence:
grep -c FORBIDDENover the dev-server log for the entire run window: 0 occurrences of the caller-identity FORBIDDEN this issue tracked.- Direct write-persistence proof, three distinct shapes:
mark_primaryscript body UPDATE on crm_contact →{ok:true,is_primary:true}and the value persists on re-GET.- Activity-action body UPDATE on sharing-governed crm_case —
first_response_datestamped by the firstlog_calland correctly not re-stamped by later ones. This is exactly the object class the rc.0 audit line warned about. send_emailbody writes:sys_emailrow (statussent),sys_activitytimeline row, plus recency bumps (contact.last_contacted_date,account.last_activity_date) — all persisted.
- The canonical
close_casefrom this issue's repro is now flow-typed (CRM-side change, runAs system) and closes a case end-to-end through the UI (resolution stored,closed_date+resolution_time_hourscomputed).
Upstream objectstack#3914's fix is confirmed present in rc.2.
One boundary worth stating so nobody reopens this on the wrong evidence: a different FORBIDDEN still exists — DELETE/UPDATE on rows whose
owner_idis NULL (action-createdcrm_eventrows) fails 403 even for admin. That is row-state-based, not caller-identity-based, and belongs to #548 (evidence posted there), not here.Recommend closing after owner confirmation (test-don't-fix mandate — reporting, not closing).
Generated by Claude Code
- added a commit that references this issue
on Aug 5, 2026 [17.0-rc2验收复核] 结论:已不复现(独立环境复核,与今晨复测结论一致)
证据:独立 dev server(端口 4091,全新种子库,admin token):
# script action body UPDATE(sharing 治理下的 crm_contact) POST /api/v1/actions/crm_contact/mark_primary {"recordId":"-NdOYw…","params":{}} → 200 {"ok":true,"id":"-NdOYw…","is_primary":true};re-GET 确认 updated_at 变更持久 # 活动 action body 三类写(crm_event INSERT + sys_activity INSERT + attendee ×2) POST /api/v1/actions/crm_contact/log_call → 200,三类行逐一 GET 核验落库 # 整个测试会话的服务端日志 grep -c FORBIDDEN server.log → 0审计行现为
[action-audit] REST action 'crm_contact/mark_primary' — body executes TRUSTED (system-elevated context, RLS/FLS-bypassing) for user '<admin id>'—— 与实际行为一致,rc.0 那种「审计声称 TRUSTED、执行被 FORBIDDEN」的自相矛盾已消失。原始复现用的 close_case 在当前 main 已是 flow 型(runAs system),走另一路径,同样端到端可用。上游 objectstack#3914 的修复在 rc.2 确认存在。环境:hotcrm@0899b4f + @objectstack 17.0.0-rc.2
建议:前提已过时建议关闭。(边界提醒同今晨复测:owner_id 为 NULL 行的 403 是另一件事,归 #548 谱系,勿以其证据重开本单。)
Generated by Claude Code
Closed on maintainer ruling (2026-08-14, verbatim: 「同意」, item 6 of the six-item list: 「#525 #524 #521 直接关闭」). Basis already on this card: two independent rc.2 retests (2026-08-05) — zero FORBIDDEN across the full action sweep, writes persist, audit line consistent with behavior; upstream mirror objectstack#3914 addressed; close was recommended on-card but never executed. The unrelated FORBIDDEN on owner_id-NULL rows was already routed to #548. Bookkeeping continues in #1150.
Generated by Claude Code
- addedpriority:p0Critical: blocker, must ship before MVPCritical: blocker, must ship before MVPand removed
on Sep 9, 2026
现象
17.0.0-rc.0 下,对象级 script action(如工单的 close_case):确认框、参数弹窗均正常,执行时报
FORBIDDEN: insufficient privileges to update crm_case <id>—— 使用的是内置 admin 账号。复现
body executes TRUSTED (context-less engine, RLS/FLS-bypassing)[BodyRunner] sandboxed action threw ... FORBIDDEN: insufficient privileges审计声明(TRUSTED、免 RLS/FLS)与实际行为(权限层全拒)自相矛盾,疑似 context-less 引擎没有用户身份导致权限检查一律拒绝。16.1 已有类似「sandbox 写库被 sharing 拦截」的怪癖,RC 未修复。
影响
所有带写库 body 的对象级 action(close_case / escalate_case / send_email / mass_update_stage / create_campaign 等)。升级阻断。
详见分支
upgrade/objectstack-17的 docs/upgrade-17/test-report.md §3 P2。