Skip to content

feat(rest,plugin-security): REST face for the explain engine — GET/POST /api/v1/security/explain (ADR-0090 D6) - #2743

Merged
os-zhuang merged 3 commits into
mainfrom
claude/great-dijkstra-mg1my6
Jul 10, 2026
Merged

feat(rest,plugin-security): REST face for the explain engine — GET/POST /api/v1/security/explain (ADR-0090 D6)#2743
os-zhuang merged 3 commits into
mainfrom
claude/great-dijkstra-mg1my6

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

摘要

ADR-0090 D6(#2696):explain 引擎此前只以进程内 security 服务的形式存在(explain(request, callerContext),security-plugin.ts),没有 REST 路由,任何 UI 都无法调用。本 PR 补上它的 REST 门面,并让鉴权兼容 D12 委托管理:

@objectstack/rest — 新端点 GET/POST /api/v1/security/explain

  • 参数 object / operation / userId?(GET 走 query,POST 走 body),用 spec 的 ExplainRequestSchema 校验(400);
  • 直接委托给 security 服务的 explain(request, callerContext)(即 SecurityPlugin.explainAccessForCaller)——与强制执行中间件同一条代码路径,"explained by construction";
  • 鉴权语义:仅限已认证调用者(即使部署把 requireAuth=false 也返回 401);服务抛出的 PermissionDeniedError 映射为 403;没有挂载 plugin-security 时返回 501;
  • 与 analytics 端点同构:优先解析环境 kernel 自己的 security 服务,单 kernel 部署回落到新增的 securityServiceProvider(由 rest-api-plugin 注入);
  • 在 scoped(/environments/:environmentId)与 unscoped 两个 base path 上都注册。

@objectstack/plugin-security — explain 鉴权兼容委托管理(D12)

  • 解释其他用户此前只认 manage_users;现在也接受一个覆盖目标用户的委托 adminScope(其 BU 子树包含目标用户的业务单元)——能改一个用户授权的管理员,自然可以读"该用户的权限为什么这样解析"。
  • 新增 DelegatedAdminGate.scopesCoverUser(sets, targetUserId),复用网关已有的 resolveHeldScopes / businessUnitsOfUser,解析失败一律 fail-closed。
  • 自解释(不带 userIduserId 为本人)不需要任何能力,保持不变。

测试

  • packages/rest/src/security-routes.test.ts(新):路由注册、POST/GET 委托与参数解析、401(匿名)、400(缺 object / 非法 operation)、403(权限拒绝映射)、501(无服务)、500(异常)——8 个用例。
  • packages/plugins/plugin-security/src/security-plugin.test.ts:新增 explainAccessForCaller (ADR-0090 D6/D12) 块 —— 委托管理员可解释子树内用户、子树外拒绝、manage_users 路径回归、无能力且无 scope 拒绝 + 自解释放行。
  • 全量:plugin-security 239 通过;rest 226 通过;turbo build(含 d.ts)11 包全绿。

关联

🤖 Generated with Claude Code

https://claude.ai/code/session_01WTubNprerCmJoU1VtUWA93


Generated by Claude Code

…ST /api/v1/security/explain (ADR-0090 D6, #2696)
The D6 explain engine shipped service-only ('security'.explain); no UI
could reach it. Add the admin-facing REST endpoint and the D12 authority
it needs:
- @objectstack/rest: GET/POST {base}/security/explain (object/operation/
userId validated against ExplainRequestSchema) delegating to the
security service's explain(request, callerContext). Authenticated-only
(401 even on requireAuth=false), 501 without a security service,
PermissionDeniedError → 403. Env-kernel service preferred; new
securityServiceProvider host fallback wired by the REST plugin.
- @objectstack/plugin-security: explainAccessForCaller honors delegated
administration (D12) — explaining another user is authorized by
manage_users OR a delegated adminScope whose BU subtree covers the
target user (new DelegatedAdminGate.scopesCoverUser, fail-closed).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WTubNprerCmJoU1VtUWA93
@vercel

vercelBot commented Jul 10, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
specReadyReadyPreview, CommentJul 10, 2026 8:33am

Request Review

@github-actionsgithub-actionsBot added size/m documentation Improvements or additions to documentation tests tooling and removed size/m labels Jul 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/plugin-security, @objectstack/rest.

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

  • content/docs/api/error-catalog.mdx(via @objectstack/rest)
  • content/docs/api/error-handling-server.mdx(via @objectstack/rest)
  • content/docs/api/index.mdx(via @objectstack/rest)
  • 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, packages/rest)
  • 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, @objectstack/rest)
  • content/docs/plugins/packages.mdx(via @objectstack/plugin-security, @objectstack/rest)
  • content/docs/releases/implementation-status.mdx(via @objectstack/plugin-security, @objectstack/rest)
  • content/docs/ui/dashboards.mdx(via @objectstack/plugin-security)
  • content/docs/ui/role-based-interfaces.mdx(via packages/plugins/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.

…12 explain authorization
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WTubNprerCmJoU1VtUWA93
Both sides added a securityServiceProvider (mine for /security/explain,
main's for /security/suggested-bindings): kept one shared provider, kept
main's registerSecurityEndpoints (suggested-bindings) and renamed the
explain registrar to registerSecurityExplainEndpoints.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WTubNprerCmJoU1VtUWA93
@os-zhuang
os-zhuang merged commit ac08698 into mainJul 10, 2026
15 of 16 checks passed
@os-zhuang
os-zhuang deleted the claude/great-dijkstra-mg1my6 branch July 10, 2026 08:18
os-zhuang added a commit that referenced this pull request Jul 10, 2026
Ships the ADR-0090 v2 UI surface into the vendored console: spec-13
adoption + position relabel + external OWD dial + matrix OWD badges
(objectui#2369), the D5 suggested-audience-binding install prompt +
Access-pillar banner (objectui#2376, pairs with #2746), and the D6
'why can this user access?' explain panel (objectui#2375, pairs with
#2743). Console rebuilt and bundle canary verified at this sha.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@os-zhuang@claude