Skip to content

[P2][架构] 独立 hosting 进程复用完整写服务运行时,缺少只读角色的能力与密钥边界 #161

Closed

Description

@LIghtJUNction

范围与基线

基线:476e64f04ed1d9c7dcab4a41c4f3cdb72faad6a7。本项只检查运行角色、对象装配与部署权限的宏观边界,不审计具体请求处理实现,不声称已发现远程执行或密钥泄露。

已对照开放/关闭 issue 的正文及相关检索:#80 跟踪 hosting 发布、浏览器同源/CSP 和存储一致性;#82 跟踪工具/SSH 隔离;#156 跟踪执行器反向依赖。这里单独报告 已经独立启动的只读 hosting 进程,仍被装配为具有完整服务能力的 Application,不重报上述功能矩阵。

结构证据

  1. daemon.py 的 load_application() 构造完整 Application;hosting 分支虽然使用独立 hosting_app(app),其 lifespan 仍调用相同的 app.load()。代码注明该 origin 不暴露 operations、cookies、MCP 或 root routes。
  2. application.py 的构造过程装配全部已配置业务插件;load() 要求 online.key、receipt.key、tokens.key,构造在线/回执签名器、托管 vault 派生材料和 OperationExecutor,并包含 release-owned 规则同步的写事务。该生命周期没有 hosting 只读角色参数或独立装配入口。
  3. extensions/hosting.py 的 hosting_app(service) / serve_hosted(service, request) 接收完整 service。托管读取确实需要当前身份、授权、Revision/内容读取和恢复隔离检查;这些需求不等于需要发行凭据或拥有完整写操作执行器。
  4. deploy/msgd-hosting.service 使用 User=msgd / Group=msgd,并允许 ReadWritePaths=/var/lib/msgd。模板明确隔离了 Root 目录,但没有为 hosting 单独表达服务私钥不可读、数据只读的角色边界。
独立 hosting 进程 / 只读 HTTP 入口
              ↓
完整 Application.load()
  ├─ 所有已配置业务插件与写操作执行器
  ├─ online / receipt / token 私密材料
  └─ 同一写服务存储与启动同步生命周期

架构问题

分离浏览器 origin 和分离进程内部能力是两件事。当前前者已有入口,后者仍依赖完整写服务对象与部署身份。结果是托管读取的启动条件、私密材料暴露面和数据写权限,跟凭据发行及写业务的生命周期绑定。

这不是说浏览器用户因此就能调用这些能力,也不是说共享 Python 包或复用授权代码有问题。问题是现有结构无法直接表达并验证“此进程只能完成托管读取,不能取得不相关签名/发行能力”。仅裁掉 HTTP 路由并不能建立这种装配边界。

建议方向

在现有模块化单体内增加明确的 hosting 只读装配配置或小型运行上下文,复用同一份认证、当前授权、资源读取和 quarantine 规则,不复制政策,不另建微服务框架。

把可信安装/规则同步与 hosting 服务启动分开;hosting 只消费已准备好的资源与 Registry 视图。逐项记录其确实需要的密钥材料,公钥验签、游标需求与在线 CA/回执签名/token 发行能力分别处理,不能为了去掉密钥依赖而关闭认证或 fail-open。

部署模板应配套表达 hosting 的最小操作系统身份、文件访问与数据库权限;只改对象类型而仍授予完整目录写权限,不算完成。

验收

  • 给出 serve、hosting、worker 的装配/能力对照表;本次首先完成 hosting 的明确只读角色,不强制同时重构其他角色。
  • hosting 不装配不需要的在线签名器、凭据发行服务或写操作执行器;不存在依靠完整 Application 回指重新获得它们的路径。
  • 隔离测试中,hosting 在无法读取不相关服务私钥、无法写入业务数据的环境仍能提供合法托管读取;缺少必要信任材料则拒绝启动,不能降级为匿名绕过。
  • hosting 启动不执行安装迁移或 release 规则发布;缺失/过旧前置条件明确报告,而不是自行取得写权限补齐。
  • 部署模板与装配契约一致,并继续验证私有 preview、当前撤权、HEAD/Range、恢复 quarantine 及 origin/CSP 边界。

没有运行生产探测、读取真实密钥、修改部署或执行外部请求。本项是架构硬化提案,不是已证实的利用链;原 #80/#84 现场验收仍独立保留。

Activity

  1. LIghtJUNction commented on Sep 29, 2026

    @LIghtJUNction
    ContributorAuthor

    已在独立 PR #173 实施,进度笔记 docs/HOSTING_RUNTIME_PROGRESS.md。先加入真实只读PostgreSQL角色、不可读服务密钥目录、禁止完整Application/签名器/启动发布、契约一致性、私有preview/撤权/HEAD/Range/304/quarantine和部署身份的失败验收测试;项目测试只在Actions跑。首个专项run 36547254507在容器启动阶段失败(health-cmd引号),未计为有效RED;已修工作流并触发36547778158。实现继续保留现行同源/CSP要求(不擅自恢复旧的跨origin设计),采用相同Registry安装器与认证/授权代码的无业务闭包视图;不涉及生产部署或真实密钥。

  2. LIghtJUNction commented on Sep 29, 2026

    @LIghtJUNction
    ContributorAuthor

    已由 #173 合入真实main:04ffad5,读取Git提交确认tree f377ce7dbdb53e0480552906a7d7529eee67171f 与验收树完全一致。

    完成独立HostingRuntime/无业务闭包Registry、必要公开信任与原认证授权、独立SELECT-only数据库账号、只读存储/无启动初始化或规则补写、独立OS服务身份和明确opt-in内容组只读发布。当前同源/CSP、私有preview、即时撤权(含HEAD/Range/304)、quarantine/悬空marker继续生效。补测还堵住了REVOKE ALL后对象owner可自行恢复写权限的漏洞。

    云端精确head2b80:专项hosting41、同头token122全部通过;full36553079854独立下载四份产物核对1935个实际msg.nodeid(475/506/492/462)精确覆盖全清单,无漏跑/额外/重复/失败/错误/跳过;conformance8、实际tokenizer、wheel/sdist与完整性gate通过。真正UID65534读取新发布文本/二进制的同时,fixture服务密钥读取和业务文件写入均被OS拒绝。证据/hash/源码tree在#173最终正文,历史RED/GREEN与部署矩阵在docs/HOSTING_RUNTIME_PROGRESS.md、HOSTING_AUTHORITY_PROGRESS.md、HOSTING_RUNTIME.md。

    #174的独有测试/9行权限修复/历史已保留,仅关闭重复PR而非抛弃验收。此处关闭架构问题,不表示部署完成;没有操作真实Root/PIN/私钥/资金/外发/恢复promotion,#80/#84等生产验收继续保留。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions