Skip to content

fix(security): getReadFilter 对 on-behalf-of 读 fail-closed 哨兵(#2852 Gap 1 潜伏面) - #2988

Merged
os-zhuang merged 1 commit into
mainfrom
claude/nice-tesla-jpzls8
Jul 15, 2026
Merged

fix(security): getReadFilter 对 on-behalf-of 读 fail-closed 哨兵(#2852 Gap 1 潜伏面)#2988
os-zhuang merged 1 commit into
mainfrom
claude/nice-tesla-jpzls8

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

目的

关闭 #2852 剩余的 Gap 1 的潜伏面(Gap 2 /analytics/query 无 context 已在 #2956 修复)。getReadFilter——analytics/raw-SQL 路径绑定的 read-scope 提供者——只解析调用方自身 ceiling;engine middleware 对 find/count/aggregate 施加的 ADR-0090 D10 delegator RLS 交集resolveDelegatorContextsecurity-plugin.ts:689)在这条路径上缺位。因此对一个 delegated(onBehalfOf)上下文在这里算 filter 会静默放宽到 agent 自身(更宽)的 scope,正是 D10 在 CRUD 路径上防住的 confused-deputy 放宽。

改动(哨兵,非完整交集)

getReadFiltercontext.onBehalfOf.userId 存在时 fail-closed:返回 RLS_DENY_FILTER + 响亮 error 日志,而不是 under-scope。与该函数已有的 fail-closed 风格(解析失败分支)一致。

  • system on-behalf-of 豁免isSystem 短路在哨兵之前(engine 自调用不被拒)。
  • 当前无 live 流量:OAuth agent 只能到 /mcp,不暴露 analytics——这是潜伏不变量守卫,不是 live 行为变更。把「将来某人把 analytics 桥进 agent 面时静默放宽」提前变成「显式拒绝 + 报错」。

为什么是哨兵而非完整交集

完整修复要把 delegator 交集下沉进 computeRlsFilter/共享 helper(单缝,避免复制 middleware↔service 分叉),而 #2920 B1(租户隔离拆 Layer 0,ADR-0095 D1)会重构同一条缝。现在精雕会与 B1 冲突/白做,故只落 fail-closed 哨兵,完整交集随 B1(issue #2852 已记录两档计划)。

验证

  • @objectstack/plugin-security441 passed(新增 2:delegated context → deny sentinel + 日志;system on-behalf-of → 豁免放行)
  • turbo build(plugin-security + deps)✓ · ESLint(改动文件)✓ · changeset:plugin-security patch

关联

#2852(read-scope D10 缺口,Gap 2 已修)· ADR-0090 D10 · #2920 B1 / ADR-0095 D1(computeRlsFilter 重构缝,完整交集落点)· #2949(explain-vs-enforcement 分叉先例)

🤖 Generated with Claude Code

https://claude.ai/code/session_012RE5oFswe4DUvExuAgvbg2


Generated by Claude Code

…Filter (#2852)

getReadFilter — the read-scope provider the analytics/raw-SQL path binds
to — resolves only the caller's own ceiling; the ADR-0090 D10 delegator
RLS intersection that the engine middleware applies to find/count/
aggregate is absent on this path. Computing a filter here for a delegated
(on-behalf-of) context would silently widen the read past the delegator's
scope — the confused-deputy widening D10 prevents on the CRUD path.

Until the intersection is threaded through computeRlsFilter (tracked with
#2920 B1 / ADR-0095 D1), deny fail-closed (deny sentinel + error log) when
context.onBehalfOf.userId is set. System on-behalf-of bypasses ahead of
the guard; no agent surface reaches analytics today, so this is a
latent-invariant guard, not a live-traffic change.

Tests: 2 new getReadFilter cases (delegated context → deny sentinel +
logged; system on-behalf-of → bypass). plugin-security 441 passed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012RE5oFswe4DUvExuAgvbg2
@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 Building Building Preview, Comment Jul 15, 2026 4:02pm

Request Review

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

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/plugin-security.

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

  • content/docs/getting-started/cli.mdx (via @objectstack/plugin-security)
  • content/docs/permissions/access-recipes.mdx (via packages/plugins/plugin-security)
  • content/docs/permissions/authorization.mdx (via packages/plugins/plugin-security)
  • content/docs/permissions/explain.mdx (via @objectstack/plugin-security)
  • content/docs/permissions/permissions-matrix.mdx (via packages/plugins/plugin-security)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/plugin-security)
  • content/docs/plugins/index.mdx (via @objectstack/plugin-security)
  • content/docs/plugins/packages.mdx (via @objectstack/plugin-security)
  • content/docs/releases/implementation-status.mdx (via @objectstack/plugin-security)
  • content/docs/ui/audience-based-interfaces.mdx (via packages/plugins/plugin-security)
  • content/docs/ui/dashboards.mdx (via @objectstack/plugin-security)

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 16:30
@os-zhuang
os-zhuang merged commit 93bb7b4 into main Jul 15, 2026
15 of 16 checks passed
@os-zhuang
os-zhuang deleted the claude/nice-tesla-jpzls8 branch July 15, 2026 16:30
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 size/s tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants