节点在线、应用在线、配置在线使用令牌查询
|
# 星尘 Stardust 架构与权限审查报告
> 审查日期:2026-07-24
> 审查范围:Stardust 仓库全部工程(Stardust / Stardust.Data / Stardust.Extensions / Stardust.Server / Stardust.Web / Stardust.Web.Vue / StarAgent / DeployAgent / StarGateway / Plugins / SDK / 测试 / Doc)
> 审查方式:只读代码核查,所有结论均基于代码事实与路径证据。
> 说明:本报告为分析产物,未修改任何项目源码;仅新增本文档。
---
## 一、定位与现状对照
项目定位(AGENTS.md):NewLife.X 生态的轻量级分布式服务治理平台 = **配置中心 + 注册发现 + APM 监控 + 日志中心 + 远程发布 + 节点运维**,对标"轻量版 Nacos + 运维 Agent + 监控"。
代码成熟度:2993 commits,分层清晰,核心能力(配置/注册/追踪/指标/发布/Agent 守护/管理台/MCP)**主体已落地**,是可运行工程而非原型。
---
## 二、分层架构与模块职责
| 层 | 工程 | 职责 | 关键入口/类 |
|----|------|------|-------------|
| 客户端 SDK | `Stardust/` | 配置拉取、注册发现、调用追踪、指标/日志上报 | `StarFactory`、`AppClient`(IRegistry)、`StarTracer`(ITracer)、`StarHttpConfigProvider`(IConfigProvider) |
| ASP.NET 扩展 | `Stardust.Extensions/` | 管线接入中间件 | `AddStardust`/`UseStardust`/`RegisterService`、`TracerMiddleware` |
| 数据层 | `Stardust.Data/` | XCode ORM 实体与统计任务,9 个 Model.xml、~70 表,按天分表+归档 | `Platform/Model.xml`、`StarDataHelper.SplitSqliteTables` |
| 控制面 | `Stardust.Server/` | 注册/配置/发布/统计 API、指标聚合;无状态,状态全在 DB | `Node/Config/App/Deploy/Trace/Log/Gateway/OAuth` 控制器、`NodeStatService` 等 |
| 管理台 | `Stardust.Web/`(Cube)+ `Stardust.Web.Vue/` | 管理与可视化 | Areas:Nodes/Registry/Configs/Deployment/Monitors/Redis/MySql/Gateway/Platform |
| 边缘代理 | `StarAgent/` + `DeployAgent/` | 节点守护、进程生命周期、指标采集、心跳、指令执行、远程发布 | `StarService`(NewLife.Agent)、`CheckDog` 看门狗、`DeployService` |
| 网关 | `StarGateway/` | HTTP 反向代理、负载均衡、TCP 健康检查、SSL、Admin API、WS 透传 | `HttpReverseProxy`、`ProxyServer` |
| 插件 | `Plugins/`(NetworkDetect / AgentExpansion / MySqlAgent) | Agent 侧辅助能力 | 继承 `AgentPlugin`(Start/Stop) |
| 多语言 SDK | `SDK/`(JS/Python/Go/PHP/ASP;Java 空白) | 异构语言接入 | 各语言 StardustClient/Tracer/Config |
| 基础设施 | NewLife.Core / NewLife.Cube / XCode | 通用能力底座 | ClientBase、ObjectContainer、Membership、Entity<T> |
> 架构分层可视化见 AGENTS.md 心智模型与下方"依赖关系"章节;核心依赖链:客户端/网关/Agent → Server(HTTP/WS)→ Data(XCode)→ 基础设施(Core/Cube/XCode)。
---
## 三、模块间依赖关系
- **客户端 → Server**:`StarHttpConfigProvider`/`AppClient`/`StarTracer` 经 HTTP/WS 调用 Server 的 `Config/App/Trace` 接口;配置支持轮询 + `config/publish` 命令推送;服务发现结果缓存 `star_services.json` 并支持 `Bind` 变更回调。
- **Agent ↔ Server**:双通道——WebSocket 实时指令下发(`NodeSessionManager` 内存会话)+ HTTP 心跳拉取(`NodeCommand` 表 `AcquireCommands`)。
- **Web → Server/Data**:基于 Cube 的控制器直连 `Stardust.Data` 实体读写,无独立 BFF。
- **Gateway → Agent**:联动 StarAgent 做冷启动/空闲回收,并透传 WS;路由用静态 `GatewayRoute/GatewayNode` 表 + TCP 探测(非注册中心动态发现)。
- **Plugins ← StarAgent**:由 Agent 加载并事件驱动。
- **全栈 → 基础设施**:依赖 NewLife.Core(XTrace/ClientBase/ObjectContainer/Snowflake/缓存)、NewLife.Cube(权限/自动控制器)、XCode(ORM/分表)。
---
## 四、功能完整性评估(对照定位)
| 能力 | 完成度 | 说明 |
|------|--------|------|
| 配置中心 | 中 | 有版本/历史/灰度字段,但客户端只取快照,无强 `onChanged` 回调,无按比例灰度下发与客户端回滚 |
| 注册发现 | 中 | RoundRobin+Weight+Tag/Scope 过滤;无熔断/限流;`HealthCheckHelper` 存在但消费端未主动剔除;无显式 Unregister,下线靠心跳超时 |
| APM 追踪 | 中 | 自动 span + 服务端回写采样参数;但用**自有头、`traceparent` 被 Exclude,未用 W3C**,异构链路不互通 |
| 指标监控 | 中 | 系统指标(CPU/内存/线程/句柄)齐全、分表聚合;**无自定义业务指标、无多维 Tag** |
| 日志中心 | 良 | `AppClientLog` + `LogController` 接收 |
| 远程发布 | 中 | Git→构建→打包→分发→解压守护;有 `ShadowDeployStrategy` 影子部署雏形,但**无一键回滚 / 灰度比例控制台编排** |
| 节点运维 Agent | 良 | 守护/看门狗/采集/指令执行成熟 |
| 管理控制台 | 良 | Cube 多 Area 覆盖,权限模型完整;告警仅钉钉/Webhook |
| 网关 | 弱 | 反向代理+LB+健康检查,**无限流/熔断/鉴权/WAF** |
| 多语言 SDK | 弱 | 普遍仅"配置+APM",**注册发现/指标/事件总线缺失,Java 空白** |
| MCP 集成 | 中 | Token 资源授权 + 反射自动注册 27 个 Action + 审计 + 单测,已有管理面能力;但 SDK 侧无 MCP 客户端,文档落后代码 |
---
## 五、项目 ID 隔离与权限专题分析(重点)
> 用户反馈:"项目 id 有的有有的没有,有的接口调用没有按照项目隔离,项目权限这块很不完善。" 本节量化核实。
### 5.1 实体层 ProjectId 分布(Stardust.Data/**/Model.xml)
**有 ProjectId 的表(约 15 张,~23%)**:App、AppOnline、Service(Entity);AppTracer、AlarmGroup(Monitors);AppConfig(Configs);AppDeploy、AppPipeline(Deployment);Node、NodeOnline(Nodes);MySqlNode、RedisNode;GatewayCluster、GatewayRoute;ProjectUser(Platform)。锚点表 `GalaxyProject` 自身用 `TenantId` 而非 ProjectId。
**缺 ProjectId 的表(约 49 张,量化风险)**:
- Registry:`AppService`、`AppConsume`、`AppMeter`、`AppHistory`、`AppCommand`、`AppClientLog`
- Monitors:`TraceItem`、`TraceRule`、`TraceData`、`SampleData`、`SampleData2`、`TraceDayStat`/`HourStat`/`MinuteStat`、`AppDayStat`/`MinuteStat`、`AlarmRecord`、`AlarmHistory`
- Configs:`AppRule`、`AppQuote`、`ConfigData`、`ConfigHistory`
- Deployment:`AppDeployNode`、`AppDeployVersion`、`AppDeployHistory`、`AppBuildNode`、`AppPipelineRun`/`Step`、`Attachment`、`SslCertificate`
- Nodes:`NodeHistory`、`NodeData`、`NodeCommand`、`NodeVersion`、`NodeStat`、`NodeRule`、`NodeLocation`、`DomainProvider`、`ProductRelease`、`ProductPackage`、`DotNetPackage`
- MySql/Redis:`MySqlData`、`RedisData`、`RedisMessageQueue`;Gateway:`GatewayNode`;Platform:`McpToken`、`McpTokenResource`、`McpAudit`
**结论**:聚合根(应用/节点/部署集/项目)有 ProjectId,但其下所有明细与海量时序数据表(追踪、采样、统计、历史、服务实例、配置数据、部署节点/版本)均无 ProjectId,只能经 AppId/NodeId 间接关联,**无法在字段级过滤项目**。
### 5.2 接口/控制器层隔离情况(Stardust.Web/Areas)
**未按项目隔离的接口(证据)**:
- `Registry/Controllers/AppServiceController.cs:40` Search 仅按 `appId/client/serviceId` 过滤,实体 AppService 无 ProjectId → 跨项目服务实例全可见。
- `Registry/Controllers/AppMeterController.cs:35`、`AppConsumeController`、`AppHistoryController`、`AppCommandController`、`AppClientLogController` 同上,均无 ProjectId 维度。
- `Monitors/Controllers/TraceDataController.cs:28`、SampleData/TraceDayStat 等 Search 仅按 `appId/itemId/clientId` 过滤,TraceData 无 ProjectId。
- `Deployment` 的 AppDeployNode/Version/History、`Monitors` 的 AlarmRecord/History 均无 ProjectId 字段,无法按项目过滤。
**即使有 ProjectId 的实体,过滤也是"opt-in"非强制**:
- `Nodes/Controllers/NodeController.cs:141,160` 取 `p["projectId"]`,仅在 URL 带 projectId 时才过滤;直接访问 `/Nodes/Node` 无参即返回所有项目节点。
- `Registry/Controllers/AppController.cs:72,79`、`AppOnlineController.cs:74,80`、`AppConfigController`、`AppDeployController`、`AppTracerController` 等同理:projectId 来自查询参数,非全局强制。
**管理台项目上下文**:`Views/Shared/_Project_Nav.cshtml:7` 仅从 `Context.Request.Query["projectId"]` 读取并拼接到各列表链接(opt-in);`Stardust.Web.Vue` 中**无任何 projectId 处理**(grep 无匹配),Vue 前台无项目作用域概念。
### 5.3 权限模型(基于 NewLife.Cube)
- 仅见**功能级**注解 `[EntityAuthorize(PermissionFlags.X)]`(约 30 处,如 NodeController、AppController、TraceDataController 等),控制菜单/增删改查动作权限。
- **全库零处 `[DataPermission]`**(grep 确认),即无数据级行权限注解。
- `ProjectUser`(项目用户关系,`Platform/Model.xml:70`)仅由 `ProjectUserController.cs` 自身维护,**从未在任何业务查询中用于限制当前用户可看的项目** → 用户-项目绑定形同虚设,无数据级隔离。
- `GalaxyProject` 的 `TenantId` 同样未在控制器中做租户过滤。
### 5.4 缺口清单
- **(a) 缺 ProjectId 的实体**:上述 ~49 张表,尤其所有时序/明细表。
- **(b) 未按项目隔离的接口**:所有无 ProjectId 实体对应的控制器(AppService/AppConsume/AppMeter/TraceData/SampleData/各 Stat/AlarmRecord/ConfigData/ConfigHistory/AppDeployNode 等)必然跨项目泄露;有 ProjectId 的控制器因 projectId 为可选参数,未强制时亦泄露。
- **(c) 权限缺口**:仅功能级(角色/菜单),无数据级项目隔离;ProjectUser 绑定未生效;无 `[DataPermission]`/全局查询过滤器;Vue 前台无项目作用域。
### 5.5 改进建议(项目隔离与权限)
1. **统一 ProjectId 基线**:为 AppService、AppConsume、AppMeter、TraceData/SampleData/各 Stat、ConfigData/ConfigHistory、AppDeployNode/Version/History、AlarmRecord/History、GatewayNode、McpToken 等补 ProjectId(可由 AppId/NodeId 反填,参考 `FixDataHostedService.cs` 的回填逻辑)。
2. **查询自动注入项目作用域**:在 `Search(Pager p)` 基类或全局 ActionFilter 中,从当前用户经 ProjectUser 解析"可访问项目集合",对所有带 ProjectId 的查询强制 `ProjectId In (...)`;对无 ProjectId 的表通过 AppId/NodeId 子查询间接隔离。
3. **引入数据级权限**:采用 `[DataPermission]` 或重写 `EntityController` 的 `Search` 注入用户-项目白名单;用 `SetProject` 全局中间件代替当前 opt-in 的 URL 参数。
4. **Vue 前台补齐"当前项目"选择器**并让所有列表请求携带项目作用域,与管理台一致。
---
## 六、总体改进建议(P0→P3)
**P0(核心治理闭环 + 安全 + 数据隔离)**
- 追踪切换/兼容 W3C `traceparent`,打通 OpenTelemetry 生态。
- Agent 指令加白名单/沙箱;核查并加固 `SendCommand` 鉴权;传输强制 TLS/mTLS。
- 落地 RedisStream(或等价)事件总线,消除单实例 `SessionManager` 瓶颈,支撑 Server 多实例水平扩展。
- **项目隔离基线 + 查询自动注入项目作用域 + 启用 `[DataPermission]`/全局过滤器,堵住跨项目数据泄露**(详见第五节)。
**P1(补齐多语言与网关,扩大覆盖面)**
- 补齐 Java SDK;统一多语言 SDK 接口契约,补齐注册发现/指标/事件总线(至少 Python/Go 优先)。
- 网关增加限流/熔断/鉴权插件化 + 对接注册中心动态路由。
**P2(增强治理深度与运营能力)**
- 配置:强 `onChanged` 回调 + 按比例灰度下发 + 客户端回滚。
- 服务发现:消费端主动健康检查剔除 + 显式 Unregister 优雅下线;可选熔断/限流。
- 指标:自定义业务指标 + 多维 Tag。
- 发布:一键回滚 + 灰度比例控制台编排。
- 告警:规则引擎 + 多渠道(邮件/短信/电话/Webhook)。
- 自身可观测性大盘。
**P3(工程与生态)**
- 推进 Vue 前端替换 Razor(含项目作用域);补充真实业务 Samples 与跨语言测试。
- 文档刷新(MCP/网关/服务网格/CI/CD/安全),与代码对齐。
---
## 七、结论
星尘已具备一个**可运行的轻量服务治理平台骨架**,核心链路基本打通,工程体量成熟。主要短板集中在三处:**异构生态接入(多语言 SDK 不对等 + 非 W3C 追踪 + 无服务网格)**、**横向扩展与实时性(单实例会话/事件总线未落地)**、**安全与深度治理能力(网关薄弱、指令 RCE、多租户弱、回滚/告警不足)**。
其中**项目 ID 隔离与权限是当前最突出、也最易被忽视的数据安全短板**:约 77% 的数据表无 ProjectId,绝大多数查询未强制按项目过滤,用户-项目绑定(ProjectUser)形同虚设,仅有功能级权限而无数据级隔离——在真实多租户场景下存在跨项目数据泄露风险。建议作为 P0 优先治理。
---
*本报告为只读审查产物,未修改任何项目源码,仅新增本文档。*
|