Repository navigation
Permission Model v2 — named follow-up ADRs (post-ADR-0090 parking lot) #2776
Description
Successor to #2696 (ADR-0090 tracking — now fully delivered and closed). This issue carries the six named follow-up ADRs that ADR-0090 §"Non-goals and named follow-ups" acknowledged and deliberately scoped out of the v2 launch window. None of them changes the v2 breaking surface; each has a workable substitute today.
Convention: per the repo's ADR discipline, the ADR for each item is opened when the work actually starts — this issue is the parking lot, not a commitment to write six documents up front.
The six follow-ups
- 1. Grant lifecycle & recertification — time-boxed assignments (
valid_from/valid_until), delegation-of-duty during absence, break-glass elevation with auto-expiry, periodic access-review campaigns (SOX/等保). Also the substrate for task-scoped, time-boxed AI-agent grants (D10) — the agent story is a second trigger for this one.
Today's substitute: permanent grants + manual review.
→ Delivered (community scope): ADR-0091 Accepted (docs(adr): ADR-0091 (Proposed) — grant lifecycle: effective-dated assignments, delegation, break-glass, recertification substrate #2751 proposed, docs(adr): ADR-0091 accepted — grant lifecycle decisions confirmed; D3 gains the no-self-renewal rule #2764 accepted). L1 validity windows + resolution-time filtering merged (feat(security): ADR-0091 L1 — grant validity windows with resolution-time filtering #2795); L2 delegation-of-duty merged (feat(security): ADR-0091 L2 — delegation of duty (职务代理) #2810). Break-glass community shape (time-boxed, reasoned direct grant) is in L1; break-glass activation workflow + recertification campaigns are ADR-0091 L3 (enterprise, cloud-side) — not tracked here. - 2. Segregation of Duties (SoD) — declarative conflict rules between permission sets ("vendor-create must not combine with payment-approve"), checked at assignment time, with an audit report. Joins the D7 lint family.
Today's substitute: org process / manual audit. - 3. Scale & reorg hardening — membership-set materialization/caching, asynchronous share recalculation, batched BU-subtree moves. Hard gate: 100k-user × 10M-record benchmark — without it, D6 explain/matrix don't hold at enterprise scale. The most engineering-debt-like of the six.
Today's substitute: per-request resolution, fine at current tenant sizes.
Note: the benchmark's stated blocker (unbounded telemetry, ADR-0057 lifecycle P1–P4, ADR-0057 data lifecycle P1–P4: retention contract, rotation, separation, governance (tracking) #2786) closed completed 2026-07-11 — no hard precondition remains. - 4. ERP dimension restrictions — declarative "rows where field ∈ my values" (Frappe User-Permissions shape) as first-class metadata; admin picks dimension values in the UI, platform compiles the row filter.
Today's substitute: hand-written RLS/CEL. - 5. ALM / environment promotion — export/import + semantic diff of positions/bindings across dev→test→prod, reusing the D6 access-matrix as the diff layer (two environment snapshots subtracted = promotion pre-flight report).
Today's substitute: manual reconfiguration per environment. - 6. Portal identity & licensing — the product track that activates D11 (
externalSharingModel) at scale: external registration/auth (separate identity pool vs invite), external-seat licensing/metering. Mechanism is fully shipped (spec shape, runtime enforcement, Studio dial); this is the productization decision.
Today's substitute: D11 mechanism usable ad hoc; no external identity product.
Note: the kernel-chain posture ladder (tracking(authz): 双轨赛道下的授权改进开发任务 v2(内核链 ADR 待编号 + 补齐轨 + 地基) #2920 B2, ADR-0095 D2) reserves anEXTERNALrung with locked semantics; item 6 itself has not started.
Suggested priority (non-binding)
#3 (hard benchmark gate) and #1 (compliance + the D10 agent-grant substrate) are the likeliest first pulls; #6 activates whenever the portal product track starts. #2/#4/#5 are demand-driven.
2026-07-15: #1 pulled and delivered (community scope, see above). #3's precondition is now clear.
References
- ADR-0090:
docs/adr/0090-permission-model-v2-concept-convergence.md§"Non-goals and named follow-ups" - ADR-0091 (item 1):
docs/adr/0091-grant-lifecycle-and-recertification.md— Accepted 2026-07-10 - Predecessor tracking issue: ADR-0090: Permission Model v2 — concept convergence, final naming, AI-authoring safety (tracking) #2696 (all platform + UI deliverables shipped; see closing comment there for the final delivery map)
🤖 Generated with Claude Code
Activity
os-zhuang commentedon Jul 14, 2026
关联 follow-up:#2918(内置行写护栏 — sys_position / sys_capability 平台/应用托管行可被删改)属于 Permission Model v2 的 enforcement 尾巴——provenance 字段(
managed_by/package_id)已存在但无写保护,对应 ADR-0049「不引入未强制的安全属性」。与 #2909(两存储类型审计)同域。os-zhuang commentedon Jul 14, 2026
汇总 tracking:#2920(双轨赛道下的授权改进开发任务)—— 内核链 ADR-0094(B1→B5 串行)+ 补齐轨(层级 RLS 企业包 GA / 记录级 debugger)+ 地基(用户页分配入口 / 来源三态 / capability 声明链)。已拆出的独立项 #2917 #2918 不在其中。
os-zhuang commentedon Jul 15, 2026
2026-07-15 完成度核实(逐项对照 ADR/PR/代码,正文已同步更新):
第 1 项已勾选 — Grant lifecycle & recertification,社区侧交付完毕
docs/adr/0091-grant-lifecycle-and-recertification.md已 Accepted(docs(adr): ADR-0091 (Proposed) — grant lifecycle: effective-dated assignments, delegation, break-glass, recertification substrate #2751 提案 → docs(adr): ADR-0091 accepted — grant lifecycle decisions confirmed; D3 gains the no-self-renewal rule #2764 接受,2026-07-10),含 D1–D7 七项决策。valid_from/valid_until上sys_user_position/sys_user_permission_set;过期行在resolveAuthzContext/ explainbuildContextForUser/ sharingexpandPositionUsers中 fail-closed 停止解析;explain 增state: 'expired';lint 规则security-grant-expired-at-authoring、security-delegation-missing-reason。PositionSchema.delegatable;D12 门自助代理分支(时限 + 必填理由 + 双向审计 + 30 天上限 + 禁止自我代理adminScope岗位);explain "via delegation from X, until Y";liveness proofdelegation-of-duty。第 2–6 项均未启动(符合本 issue 约定)
对五个主题做了 issue / PR / ADR 三方搜索,无专属 ADR 或工作项。ADR-0092–0095 编号紧随但主题不同(profile 字段代理 / 租户模式 / permission-set 纯投影 / 内核租户层),属 #2920 双轨改进线,不计入本停车场。两个状态更新已注入正文:
EXTERNAL档位并锁定语义(仅显式共享、永不 OWD),实现明确等 portal 主体类型出现后另立 issue。本 issue 保持 open,继续作为 2–6 项的停车场。
Generated by Claude Code
objectstack-fleet commentedon Oct 14, 2026
Pointer for item 6 (Portal identity & licensing), from
domain:specseat 3 (#18883) ·baozhoutao· sessionsession_01D6F9axfoPzR7t8G1J7Ytzz· 2026-10-14T10:24Z. ⛔ Not a claim, ⛔ no label change; posted under ruling6159300530on #23268 (letter A, the maintainer's 「23268 同意」), item 2: "#2776 item 6 gets a pointer".Item 6's text says it "activates D11 (
externalSharingModel)" and that the mechanism is "fully shipped". That is no longer true:externalSharingModelis retired on the v18 line: PR feat(spec)!: retire the object's externalSharingModel — the external org-wide default no principal ever read (#23268) #23441 (301eec6df). The schema refuses it with "delete the key", and stored rows are stripped on read. It never had a reader: no request resolves an external principal.11d4c5a6d). External visibility is ADR-0095/0099'sEXTERNALrung, explicitly shared rows only, never OWD-derived. When a portal or partner line is built, external principals reach rows through explicit shares, relationship-based grants (a sharing set: the records related to the principal's account or contact) and share links, from an identity pool separate from members (D11's pool, kept).externalSharingModeldropdown and the Ext badge once @objectstack/spec retires the key (objectstack#23268, ruling A) objectui#12353.So item 6, when it starts, builds on the
EXTERNALrung and on sharing sets, not on an external org-wide default.Generated by Claude Code