Skip to content

automation: an elevated screen flow cannot declare who may start it, so apps gate on current_user.positions inside the flow #25481

Closed as duplicate

Description

@marchtian

Ruled: 6377848497 · batch #9 item 5 · letter A · 2026-10-24T00:43:45Z (flow-level requiredPermissions checked on every start door; action door inherits it; triage asked to consider p1)

What the app needs

hotsrm (an SRM app on 18.0.0) has a "verify bank account" screen flow, srm_bank_verify. Only AP accountants may run it, and the person who created the account may not verify it (four-eyes). The flow writes status and verified_by, which are readonly for everyone, so it is runAs: 'system'.

What the platform offers today

So any member can start srm_bank_verify through the trigger door with a recordId. The only defence the app can write is a decision node at the top of the flow: 'srm_ap_accountant' in current_user.positions. The platform's own guidance says the positions array "is not an authorization input", so the app is relying on something the platform tells it not to rely on.

Wanted

  • A flow-level declaration of who may start it, for example requiredPermissions: ['srm_verify_bank_account'] on the flow, checked on every start door (action door, trigger door, MCP run_action), with the ADR-0112 refusal envelope.
  • A subflow call from a parent run keeps working.
  • Optional: the action door could inherit the flow's declaration so an app does not state it twice.

Acceptance

A screen flow declared runAs: 'system' with requiredPermissions: [X]: a member without X is refused 403 at the trigger door and the action door; a member with X starts it; os validate documents the key.

Duplicate check

Searched issues for "flow requiredPermissions", "screen flow runAs system who can start". Closest: #22310 (closed; covered self-triggered flows, left screen flows open on purpose) and #25446 (no-self-approval switch on approvals; related to the four-eyes half, not to who may start).

hotsrm workaround, documented as temporary: src/core/flows/bank-account/bank-verify.flow.ts gates on current_user.positions inside the flow.

Activity

  1. added
    area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guards
    domain:specDomain lane — seat card indexed by label:pm:seat
    enhancementNew feature or request
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    on Oct 23, 2026
  2. objectstack-fleet commented on Oct 23, 2026

    @objectstack-fleet
    Contributor

    Triage: decision-shaped (filing-gate ②: a feature / contract-shape proposal from a real app). Lands in packages/spec (FlowSchema) first, then every flow start door in the server lane (action door, POST /automation/:name/trigger, MCP run_action). Marked needs-user-decision; not dispatchable until ruled.
    Path: access · 增删改查逐格兑现 / workflow · 流程的出错、暂停与定时 | automation.screen-flow-roundtrip (P1, passes) — 缺项 for "who may start" | step ②
    Type: Feature

    维护者速读

    一个以系统身份运行的屏幕流程(如"核验银行账户"),今天任何登录成员都能从触发入口启动它;应用只能在流程里判断"当前用户的岗位",而平台文档明说岗位数组不是授权依据。

    推荐 A:权限声明放在被保护的东西上,所有入口一致,和动作的 requiredPermissions(ADR-0066 D4)同形;B 更窄但让屏幕流程只剩一个入口。问:A / B / C?

    os-decision-facets

    • ① 项目长远合理性:A 让"谁能启动"跟着流程走,所有入口同一判据;B 靠收窄入口间接保护;C 留下一个已知的提权入口。
    • ② 实际业务拉动:hotsrm 银行账户核验(四眼原则)实测需要,今天靠岗位数组绕行。
    • ③ 防 AI 犯错:A 是声明即强制、响亮拒绝;今天 AI 照着 hotsrm 的写法会在流程里用岗位做授权,平台自己说那不可靠。
    • ④ 创业阶段不扩散:A 新增一个键,但它替代的是每个应用自写的授权判断;B 零新增;C 零新增。

    Governing text: ADR-0066 D4 (action requiredPermissions); action-execution.ts docblock on elevated screen flows at the trigger door (#22310).
    Prior rulings read: "flow requiredPermissions screen flow trigger door" → #22310 (closed; left screen flows open by design), #25446 (related, four-eyes on approvals); ADR-0066 D4; thread: none.

    Batch note: one of five import / automation proposals from hotsrm's trial import filed on 2026-10-23 (#25475, #25476, #25477, #25481, #25493); the earlier hotsrm platform evaluation is the decision card #25496. They can be ruled as one batch.

    Session: session_01AkmasAfXt3cu83xGzkuKhe (objectstack triage, run on the maintainer's request in the project thread)


    Generated by Claude Code

  3. os-elon-musk commented on Oct 24, 2026

    @os-elon-musk
    Collaborator

    Ruling: batch #9 item 5 · letter A · maintainer 「#9 同意」 2026-10-24T00:43:45Z

    A = 流程级 FlowSchema.requiredPermissions:每个启动入口(动作门、触发门、MCP run_action)共用一条判定,拒绝走 ADR-0112 信封;父运行的 subflow 调用不受影响;动作门继承流程的声明(建议做,免得应用写两遍、漏一边就是洞)。验收:无 X 的成员在触发门与动作门都得 403,有 X 的能启动,子流程照常;os validate 与文档说明该键。工作量 spec S + server M:先 spec 加键,后 server 在三个入口共用的判定里查。分级:席位 p2 + security,总监席建议分诊考虑 p1(任何成员可达的已知提权入口;#22310 有意留下,是设计缺口不是回归)。hotsrm 发版后拆掉 current_user.positions 绕行;四眼的另一半(建账户者不能核验自己建的)不在本卡。

    标签 needs-user-decision → pm:queue;裁不派。简报:https://claude.ai/artifact/XKBVwFLq2V5nBTNy3enkbz(卡 5)。


    Generated by Claude Code

  4. added
    pm:queueReady for the PM dispatch loop
    and removed
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    on Oct 24, 2026
  5. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    Contributor

    Closed 2026-10-24T01:39Z. Superseded by #25580 — the same card ("an elevated screen flow cannot declare who may start it"), re-filed as objectstack-fleet[bot] with this body and these labels. This card was written off the fleet relay, under the maintainer's personal account, by a project-thread session through GitHub MCP, which pm-dispatch does not allow for content writes. The thread above stays here for reference; the queue continues on #25580.

    Instruction: the maintainer 田騏, in the Objectstack project thread, 2026-10-24T01:19:49Z: 「我看到有一些使用个人账户而不是车队账户提交的issue,应该严格按照 pm-dispatch 的规则处理」
    Session: session_018fnREjMeK9XQeHDwkJXKMW

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guardsdomain:specDomain lane — seat card indexed by label:pm:seatenhancementNew feature or requestpriority:p2Medium: important, M3security

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions