子账号(role=user)只能使用 Bot 模式。管理员在「设置 → 用户与权限」创建账号时分配当前服务的基础 Profile,也可以随后修改分配。子账号只能基于这些 Profile 创建自己的 Bot Agent;不能读取原生 Profile、聊天和历史,不能使用原生 Hermes Bot、看板、节点配对或全局设置。
assignedProfiles 保存在本地账号记录中。旧账号没有该字段时视为未分配,不自动授权 default 或全部 Profile。/Users/...、/attachments/...)均拒绝。自己的附件使用 owner 隔离的 /api/app/files/:id/...。GET /api/app/bootstrap 提供 CSRF 和 registrationAvailable。管理员尚未初始化时为 false;旧服务器未提供标记时,新客户端提示不支持注册。POST /api/app/register 仅接收 username、password,沿用用户名规则和至少 8 位密码要求。创建 role=user、enabled=false、assignedProfiles=[]、mustChangePassword=false、registrationStatus=pending,返回 201,不签发业务会话。Retry-After。不信任转发 IP 请求头;多用户共享反向代理出口时共享该限额。account_pending_approval,错误密码仍为原有 401。兼容登录入口同样生效。POST /api/app/admin/users/:userID/approve 接收 assignedProfiles,核对实时本机 Profile 目录,要求至少一个可用来源,在同次保存中写入分配、已开通、启用状态。registrationStatus 时按 approved 处理,不改变其启用状态、密码、分配或首次改密要求。本实现是 Web/iOS 账号与服务 API 的授权隔离,不创建 Hermes 工具执行的操作系统沙箱。分配的 Profile 仍按 Hermes 自身的工具权限运行,工具可访问的磁盘和外部服务范围需要在 Hermes 执行环境中约束。
tests/server/subaccountPermissions.test.ts 使用真实账号、Cookie 和 CSRF,覆盖默认拒绝、Profile/节点伪造、REST/实时/媒体/密钥入口、跨 owner 资源和撤权。tests/e2e/workspace-chat.spec.ts 的 subaccount 用例验证管理员分配、首次改密、限制后的创建列表、隐藏模式菜单和手输旧路由重定向。WorkspaceChatTests 和 AuthAndRESTTests 覆盖服务权限解析、能力撤回和保留的原生模式设置被纠正。tests/server/subaccountRegistration.test.ts 通过完整应用中间件覆盖注册、审核、知识与附件隔离、SSE 鉴权和禁用后的旧连接关闭;不替换认证。