Skip to content

feat(core,plugin-security): B2+B4 — posture 阶梯 + capability 派生 (ADR-0095 D2/D3, #2920)#2938

Merged
os-zhuang merged 1 commit into
mainfrom
claude/authz-b2b4-posture-ladder
Jul 15, 2026
Merged

feat(core,plugin-security): B2+B4 — posture 阶梯 + capability 派生 (ADR-0095 D2/D3, #2920)#2938
os-zhuang merged 1 commit into
mainfrom
claude/authz-b2b4-posture-ladder

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

概述

授权内核链第二段(#2920 的 B2 + B4),落地已合并的 ADR-0095 D2(单调 posture 阶梯)+ D3(posture 从 capability 派生)。基于 B1(Layer 0,已并入 main)。

行为保持。 enforcement 未改动——每对象的 Layer 0 豁免 + 每侧 superuser bypass 仍按原样裁决;posture 是一个 附加的、派生的、可解释的字段。authz-matrix-gate 单元快照与 dogfood authz-conformance 全绿。无迁移。

设计

B2 — posture 阶梯(D2)

  • resolveAuthzContext 现解析并携带显式 posture,复用 spec 的 AuthzPosture 枚举(explain.zod.tsPLATFORM_ADMIN>TENANT_ADMIN>MEMBER>EXTERNAL);ResolvedAuthzContext 新增 posture? 字段。
  • 新模块 packages/core/src/security/posture-ladder.ts:钉住每档恰好一条行可见性注入规则的映射(POSTURE_INJECTION_RULE),并把 ADR 要求的两条不变量作为单测锁死:
    • 严格嵌套:rung n 可见集 ⊇ rung n−1postureVisibleRows 参考模型,union-with-previous 构造,按构造单调)。
    • EXTERNAL 语义锁:仅显式共享行——OWD 基线/共享规则永不放大;配置错误只能缩小、绝不放大可见性。
  • EXTERNAL 定义并锁测但当前永不解析(无外部主体类型;占位注释指向 portal/ADR-0093)。解析器的下界是 MEMBER
  • resolve-authz-context.test.ts 升级为 principal × grants → posture 矩阵 + 嵌套断言。

B4 — posture 从 capability 派生(D3)

  • 档位从持有的 capability 授予派生,绝不读 better-auth role
    • PLATFORM_ADMIN ← 非作用域 admin_full_access 授予(即 superuser bypass 信任的 viewAllRecords/modifyAllRecords 证据)。
    • TENANT_ADMINorganization_admin 授予。
  • better-auth role='admin' 仅作为授予 org_admin 岗位/organization_admin capability 的 provisioning 来源auto-org-admin-grant.ts + resolveAuthzContextmapMembershipRole 投影,已加注释标注为唯一 provisioning 边界)。
  • 新增 spec 导出 ORGANIZATION_ADMIN(org-admin capability 授予名),与既有 ADMIN_FULL_ACCESS 并列;auto-org-admin-grant.ts 复用之,消除本地字面量。

行为 delta

无。 这是纯粹的 behavior-preserving 变更:只新增一个派生字段与其不变量测试,未触碰任何 enforcement filter 计算。

消除 better-auth role 双轨的证据(grep)

全仓 grep enforcement 相关包(plugin-security / core/security / plugin-sharing / runtime/security / rest)确认:当前主体的 admin 层 / posture 裁决绝不读 sys_member.role——permission-evaluatorcomputeRlsFilter 的 bypass 只读 capability 位(viewAllRecords/modifyAllRecords)与已归一化的 ctx.positions

唯一在 enforcement 时读 sys_member.role 的点是 plugin-sharing/team-graph.tsexpandRoleUsers(roleName)——这是共享规则收件人/受众的正向群展开(ADR-0057 D4 过渡来源),按任意传入的 roleName 反查成员 user_id,不裁决请求主体的 admin 层,也不产生 #2836 类 deny-vs-allow 合成冲突。属既有机制、正确且超出本任务范围,未改动。

验证(实测)

  • pnpm --filter @objectstack/core test339 passed(含新 posture-ladder.test.ts + posture 矩阵)。
  • pnpm --filter @objectstack/plugin-security test366 passedauthz-matrix-gate 保持绿,未改一格)。
  • pnpm --filter @objectstack/spec test6777 passed(含 api-surface check;新增 ORGANIZATION_ADMIN)。
  • dogfood authz-conformance 账本 — passed
  • dogfood 行为证明(真实 kernel boot):rls-multitenant / rls-fixture / showcase-private-owd / showcase-public-read-owd / showcase-permission-zoo / two-doors-permission / showcase-bu-hierarchy-sharing / showcase-permission-projection / showcase-permission-seeding全绿(44 tests)
  • core / spec / plugin-security 的 DTS build(tsc 源码类型检查)通过。

Reviewer checklist

  • posture 派生复用 D3 指定证据(admin_full_access / organization_admin capability 授予),未引入对 better-auth role 的 enforcement 读。
  • EXTERNAL 已定义 + 注入规则 + 语义锁测,但解析器永不返回(占位指向 ADR-0093)。
  • 严格嵌套不变量为真实执行的被测属性(postureVisibleRows)。
  • enforcement 无行为 delta:authz-matrix-gate 与 dogfood 全绿。
  • ORGANIZATION_ADMIN 作为 spec 常量单一真源,auto-org-admin-grant.ts 已复用。
  • (后续 C 阶段)posture 尚未透传进 ExecutionContext / explain principal.posture——β 引擎消费为 C-phase follow-up;本 PR 刻意止步于解析器层,保持 blast radius 最小(含 OAuth agent 天花板的边界处理留待后续)。

🤖 Generated with Claude Code

https://claude.ai/code/session_019QRUvVfpvSycAHMMF2xTxs


Generated by Claude Code

…(ADR-0095 D2/D3, #2920)

Resolve an explicit monotonic posture rung
(PLATFORM_ADMIN > TENANT_ADMIN > MEMBER > EXTERNAL) once in
resolveAuthzContext and carry it on ResolvedAuthzContext.posture.

D2 — new @objectstack/core/security module posture-ladder.ts reuses the spec
AuthzPosture enum, pins the rung -> injection-rule mapping (one rule per rung),
and locks its two ADR-required invariants as unit tests: strict nesting
(rung n's visible set superset of n-1) and EXTERNAL deny-by-default (explicit
shares only; OWD never widens it). EXTERNAL is defined/test-locked but never
resolved (no external principal type yet); the floor is MEMBER.

D3 — the rung derives from held capability grants, never a better-auth role:
PLATFORM_ADMIN from the unscoped admin_full_access grant (the same
viewAllRecords/modifyAllRecords evidence the superuser bypass trusts),
TENANT_ADMIN from the organization_admin grant. The better-auth role remains a
provisioning source only (auto-org-admin-grant.ts, mapMembershipRole); no
enforcement path adjudicates the raw role, closing the #2836 dual-track class.

Behavior-preserving: enforcement is unchanged (per-object Layer 0 exemption +
per-side superuser bypass still gate access); posture is an additive derived,
explainable field. authz-matrix-gate + dogfood authz-conformance stay green.

- spec: add ORGANIZATION_ADMIN constant; auto-org-admin-grant.ts reuses it.
- resolve-authz-context.test.ts: principal x grants -> posture matrix + nesting.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019QRUvVfpvSycAHMMF2xTxs
@vercel

vercel Bot commented Jul 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jul 15, 2026 12:42am

Request Review

@github-actions github-actions Bot added size/l documentation Improvements or additions to documentation tests tooling and removed size/l labels Jul 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 3 package(s): @objectstack/core, @objectstack/plugin-security, @objectstack/spec.

109 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/actions-as-tools.mdx (via @objectstack/core)
  • content/docs/ai/agents.mdx (via @objectstack/spec)
  • content/docs/ai/knowledge-rag.mdx (via @objectstack/core)
  • content/docs/ai/natural-language-queries.mdx (via @objectstack/core)
  • content/docs/ai/skills-reference.mdx (via @objectstack/spec)
  • content/docs/ai/skills.mdx (via @objectstack/spec)
  • content/docs/api/client-sdk.mdx (via @objectstack/spec)
  • content/docs/api/environment-routing.mdx (via @objectstack/spec)
  • content/docs/api/error-catalog.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/api/index.mdx (via @objectstack/spec)
  • content/docs/automation/approvals.mdx (via packages/spec)
  • content/docs/automation/flows.mdx (via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx (via packages/spec)
  • content/docs/automation/hooks.mdx (via @objectstack/spec)
  • content/docs/automation/index.mdx (via @objectstack/spec)
  • content/docs/automation/webhooks.mdx (via @objectstack/core, @objectstack/spec)
  • content/docs/automation/workflows.mdx (via @objectstack/spec)
  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via packages/core, packages/spec)
  • content/docs/data-modeling/analytics.mdx (via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx (via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx (via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx (via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx (via @objectstack/spec)
  • content/docs/data-modeling/index.mdx (via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx (via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx (via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx (via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx (via @objectstack/spec)
  • content/docs/deployment/migration-from-objectql.mdx (via @objectstack/core)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx (via @objectstack/spec)
  • content/docs/getting-started/cli.mdx (via @objectstack/plugin-security, @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/getting-started/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/spec)
  • content/docs/kernel/cluster.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx (via @objectstack/core, @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx (via packages/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/examples.mdx (via @objectstack/core)
  • content/docs/kernel/runtime-services/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via packages/spec)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/core, @objectstack/spec)
  • content/docs/kernel/services.mdx (via @objectstack/core)
  • content/docs/permissions/access-recipes.mdx (via packages/plugins/plugin-security)
  • content/docs/permissions/authentication.mdx (via @objectstack/core)
  • content/docs/permissions/authorization.mdx (via packages/plugins/plugin-security, @objectstack/spec)
  • content/docs/permissions/explain.mdx (via @objectstack/plugin-security)
  • content/docs/permissions/permission-sets.mdx (via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx (via packages/plugins/plugin-security, @objectstack/spec)
  • content/docs/permissions/positions.mdx (via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/plugin-security, @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/plugins/anatomy.mdx (via @objectstack/core)
  • content/docs/plugins/development.mdx (via @objectstack/core, @objectstack/spec)
  • content/docs/plugins/index.mdx (via @objectstack/core, @objectstack/plugin-security, @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/core, @objectstack/plugin-security, @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/protocol/diagram.mdx (via packages/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/config-resolution.mdx (via @objectstack/core, @objectstack/spec)
  • content/docs/protocol/objectos/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/index.mdx (via @objectstack/core)
  • content/docs/protocol/objectos/lifecycle.mdx (via @objectstack/core, @objectstack/spec)
  • content/docs/protocol/objectos/plugin-spec.mdx (via @objectstack/core, @objectstack/spec)
  • content/docs/protocol/objectos/runtime-capabilities.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via packages/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via packages/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx (via @objectstack/core, @objectstack/plugin-security, @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v12.mdx (via @objectstack/spec)
  • content/docs/releases/v13.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/spec)
  • content/docs/ui/audience-based-interfaces.mdx (via packages/plugins/plugin-security)
  • content/docs/ui/create-vs-edit-form.mdx (via @objectstack/spec)
  • content/docs/ui/dashboards.mdx (via @objectstack/plugin-security, @objectstack/spec)
  • content/docs/ui/forms.mdx (via @objectstack/spec)
  • content/docs/ui/index.mdx (via @objectstack/spec)
  • content/docs/ui/setup-app.mdx (via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@os-zhuang os-zhuang marked this pull request as ready for review July 15, 2026 00:40
@os-zhuang os-zhuang merged commit 13749ec into main Jul 15, 2026
17 checks passed
@os-zhuang os-zhuang deleted the claude/authz-b2b4-posture-ladder branch July 15, 2026 00:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants