RuView Cognitum Spaces OAuth 激活指南:基于spaces:read的只读语义空间投影与 MCP 授权实践
【免费下载链接】RuViewπ RuView turns commodity WiFi signals into real-time spatial intelligence, vital sign monitoring, and presence detection — all without a single pixel of video.项目地址: https://gitcode.com/GitHub_Trending/wi/RuView
导读
本文是 RuView 仓库中 Cognitum Spaces OAuth activation 操作手册 的完整技术指南,讲解如何在不向 Agent 交付 bearer token 或 API key 的前提下,激活并安全检查租户隔离的 Cognitum Spaces 语义投影。读完本文,你将掌握三条核心技能:通过wifi-densepose login --spaces显式申请spaces:read作用域并验证身份;通过npx @ruvnet/ruview spaces元 harness 对 sites/buildings/floors/spaces/zones/entities/events/alerts 八类版本化集合做分页只读查询;以及在 MCP 场景下使用ruview_spaces_list工具时的授权模型、失败关闭语义与结果诚实解读方法。
背景:为什么需要一条"不给凭证的只读激活路径"
RuView 通过 Wi-Fi CSI 信号在本地实现无摄像头的空间感知(姿态、存在、呼吸)。当这些感知需要进入云端形成跨房间、跨站点的空间状态时,Cognitum Spaces 提供了租户/工作区作用域的云侧投影——它不是第二个传感器,而是对边缘状态的语义化同步(详见 ADR-325 的决策链:RuView RF capture → 语义观察 → HomeCore 权威边缘状态 → Cognitum Spaces 投影 → 受限读客户端)。
问题的关键在于:当把这种能力交给 AI Agent(如 Claude Code、Codex)或 MCP 服务器使用时,直接下发 token 或 API key 会带来严重的凭证泄露风险。本手册定义的安全模型是:
- 激活凭证与数据面凭证分离:登录授权(Authorization Code + PKCE)与后续只读查询解耦;
- Agent 永不接触裸凭证:元 harness 内部持有凭据,对外只暴露结构化的、经过二次校验的结果;
- 读取权限最小化:
spaces:read只允许读取语义投影,不授予任何配对、发布、写入、命令、策略审批、消费或执行器(actuator)权限。
边界约束(Boundary):先理解"能做什么,不能做什么"
在动手之前,必须先明确本投影的语义边界,它决定了后续所有命令的使用方式:
| 约束维度 | 具体内容 |
|---|---|
| 投影性质 | 只读的 P2/P3 语义投影;HomeCore Edge 始终是权威状态源 |
| 禁止字段 | 原始 CSI、CIR、RF 张量、录音、姿态帧、生命体征波形、身份观测——一律禁止跨云 |
| 权限含义 | spaces:read不授予配对、发布、写入、命令、策略审批、消费或执行器权限 |
| 副作用 | 一次读取可能刷新即将过期的 OAuth 会话,并原子轮换本地凭证文件(这是设计内的认证副作用,不增加云写权限) |
从源码看,这条边界在 spaces.js 中被硬编码为REQUIRED_EXCLUSIONS与FORBIDDEN_FIELDS:前者要求每个响应必须携带raw_csi、cir、rf_tensors、recordings、pose_frames、vital_waveforms、identity_observations七项排除声明;后者则进一步拦截csi、packetcapture、skeleton、keypoints、faceembedding等别名与近似字段——这是纵深防御:即使服务端投影漏了某个字段名,客户端也会独立拒绝。
激活 OAuth:wifi-densepose login --spaces
前置条件
安装或构建wifi-denseposeCLI(仓库内的 Rust 实现位于 v2/crates/wifi-densepose-cli,harness 的 guidance 记录中引用其 spaces.rs)。OAuth 流程使用 Cognitum 既有的 Authorization Code + PKCE 流程,公共客户端标识为ruview。
显式请求附加作用域
wifi-densepose login --spaces- 该命令会通过 PKCE 流程显式请求
spaces:read作用域; - 注册是上限:普通感知登录不会静默获得云访问权,必须显式加
--spaces才会申请; - 授权服务器校验是合取式的(ADR-325 第 1 节):ES256 签名(
https://auth.cognitum.one/.well-known/jwks.json)、签发者精确为https://auth.cognitum.one、受众精确为ruview、客户端声明精确为ruview、令牌类型为普通access(setup/workload 令牌拒绝)、有效期在 5 秒时钟容差内、作用域精确包含spaces:read、且必须绑定非空 UUID 形式的org_id与workspace_id。
无浏览器终端
wifi-densepose login --spaces --no-browser用于没有浏览器的 SSH 或 CI 终端场景,登录码/设备流由 CLI 自行处理。
验证身份并开始查询
wifi-densepose whoami npx @ruvnet/ruview spaces npx @ruvnet/ruview spaces --resource sites npx @ruvnet/ruview spaces --resource events --limit 25whoami用于确认账号确实报告spaces:read作用域;npx @ruvnet/ruview spaces是元 harness(harness/ruview)暴露的 CLI 动词,其内部实现位于 spaces.js 的listCognitumSpaces,通过runProcess以经过净化的子进程环境调用已安装的wifi-densepose二进制(spaces --json --base-url https://api.cognitum.one --resource <kind> --limit <n>)。
版本化集合与分页
八类版本化集合为:sites、buildings、floors、spaces、zones、entities、events、alerts。它们的层级关系遵循 ADR-306 的规范空间词汇表:
Site -> Building -> Floor -> Space -> Zone -> Sensor / Person / Object / Track -> Observation -> Event -> Alert分页要点:
- 使用响应返回的不透明
nextCursor继续下一页; - 不要解码 cursor,也不要在不同集合间复用 cursor——cursor 是 API 实现细节,跨集合使用违反契约;
- 元 harness 侧对 cursor 的校验(spaces.js):必须是非空字符串、长度 ≤ 512、且不含控制字符;
--limit的合法范围是1–100,默认 50(spaces.js 中强制校验:非安全整数、越界均返回invalid_limit)。
凭证路径的谨慎使用
wifi-densepose login --spaces --credentials-path /private/ruview/credentials.json--credentials-path <private-file>只能用于人工调用 CLI 且确实需要非默认凭证存储的场景;- 绝不允许把 bearer token 或 API key 放在命令行上(会被 shell 历史、进程列表泄露)。在元 harness 中,
--credentials-path会原样传给wifi-densepose(spaces.js),但 MCP 调用路径会拒绝该参数(见下文)。
MCP 集成:ruview_spaces_list的授权模型
默认拒绝
MCP 工具名是ruview_spaces_list。尽管云操作本身只读,但由于它会消费本地身份凭证并联系外部服务,默认情况下该工具被拒绝。对应策略声明位于 policy.js:
ruview_spaces_list: { class: 'external-read', readOnly: true, requiredGrant: 'credential-use', openWorld: true, usesCredentials: true, mayRefreshCredentials: true },这意味着:在 mcp-server.js 中,MCP 服务器启动时从RUVIEW_MCP_GRANTS环境变量读取逗号分隔的授权列表;若该列表不含credential-use,任何ruview_spaces_list调用都会在触碰本地凭证或网络之前被authorizeTool拒绝(返回authority_denied/requiredGrant: 'credential-use'),对应测试见 spaces.test.mjs。
运维人员显式授权并绑定凭证路径
RUVIEW_MCP_GRANTS=credential-use \ RUVIEW_CREDENTIALS_PATH=/private/ruview/credentials.json \ npx @ruvnet/ruview mcp startRUVIEW_MCP_GRANTS=credential-use:运维人员显式授予该工具使用凭证的能力;RUVIEW_CREDENTIALS_PATH:在服务器环境中绑定非默认凭证文件路径,这样工具调用参数里就不需要也不允许出现任意文件路径;SPACES_ENV_ALLOWLIST(spaces.js)在默认环境白名单之上仅追加RUVIEW_CREDENTIALS_PATH,其余环境变量全部被scrubEnvironment剥离。
MCP 调用的硬性限制(源码级证据)
- 不能选凭证路径:
listCognitumSpaces在source === 'mcp'且传入credentials_path时直接返回credentials_path_not_allowed(spaces.js);测试 spaces.test.mjs 验证了即使有credential-use授权,MCP 也不能选择任意凭证文件; - 工具 schema 没有 token、API-key、工作区覆盖或 base-URL 字段:
ruview_spaces_list的 inputSchema(tools.js)只暴露credentials_path(CLI 专用)、resource、limit、cursor四项; - API 源固定为
https://api.cognitum.one(spaces.js),不可被调用方覆盖; - 适配器要求已安装的
wifi-densepose二进制:而不是在持证状态下执行自动检测仓库里的 Cargo 构建脚本(cli_missing错误,测试见 spaces.test.mjs); - 子进程环境排除
COGNITUM_SPACES_API:该兼容性环境变量只存放 API key,被刻意从允许列表中剔除,因此这条 MCP 面只会验证 OAuth 路径,绝不会静默走兼容 API-key 路径(spaces.js 与测试 spaces.test.mjs 均验证了该变量不会被转发)。
诚实解读结果:空列表也是合法结果
{ "object": "list", "data": [], "boundary": { "authoritativeState": "HomeCore Edge", ... } }- 空的
data列表可以是合法的已认证租户结果(例如 ADR-325 的线上审计中,账号没有配对站点,因此认证结果是空列表而非捏造的示例状态); - 空结果证明的是读取路径与隔离行为,而不是感知质量——不要把它解读成"这个空间没人在"的证据,也不要用它证明模型或感知的准确性;
- 每条被接受的响应必须声明
HomeCore Edge为权威状态,并携带完整的禁止字段列表(spaces.js 的parseSpacesOutput会校验boundary.authoritativeState === 'HomeCore Edge'且excluded完整包含七项排除声明,缺失即抛incomplete edge privacy boundary)。
元 harness 的独立语义校验(fail-closed 的落实)
parseSpacesOutput(spaces.js)在返回给 CLI/MCP 调用者之前,会对"已经验证过的语义投影"再做一次独立校验,包括:
| 校验项 | 规则 | 违反时错误 |
|---|---|---|
| 输出体积 | ≤ 2 MiB | CLI response exceeds bound |
| JSON 结构 | 深度 ≤ 16、节点 ≤ 10,000、数组项 ≤ 1000、对象键 ≤ 128、字符串 ≤ 4096 字节 | JSON structure exceeds node bound等 |
| 禁止字段 | 任意层级出现raw_csi/packet_capture/poseframe等即拒绝 | forbidden raw field |
| 列表信封 | object === 'list'且data为数组且 ≤ 100 条 | invalid list envelope |
| 版本契约 | schemaVersion === '1.0'且kind属于八类集合 | invalid spatial contract version or kind |
| 隐私类 | 每条记录privacy必须为P2或P3 | non-semantic privacy class |
| 置信度 | 若存在则必须为 [0,1] 的有限数值 | invalid confidence |
| 空间身份 | id匹配^[A-Za-z0-9][A-Za-z0-9_.:-]{0,119}$、tenantId非空;版本化记录还要求 UUIDworkspaceId、非负eventSequence、version ≥ 1、可解析的observedAt、attributes/provenance为对象 | spatial identity is incomplete/versioned spatial identity is incomplete |
| 父级血缘 | floors需buildingId;spaces需buildingId+floorId;zones/entities/events/alerts需spaceId | spatial parent is incomplete |
| 实体隐私 | entities的entityType限sensor/person/object/track,且person/track的identityMode必须为anonymous | entity privacy contract is invalid |
| 事件/告警 | events需eventType;alerts需alertType且severity ∈ info/warning/critical、status ∈ open/acknowledged/resolved | event type is missing/alert contract is invalid |
| Cursor | 非空、≤ 512 字符、无控制字符 | invalid next cursor |
任何畸形、超大、非语义或含原始字段的响应都会失败关闭(fail closed)——返回invalid_spaces_output,绝不把未经验证的数据当作成功结果。测试覆盖见 spaces.test.mjs(拒绝禁止字段、拒绝不完整边界与非法置信度)与 spaces.test.mjs(拒绝原始字段别名、非匿名实体身份、非法 workspaceId 与非法时间戳)。
错误分类与脱敏
子进程失败时,commandFailure(spaces.js)会把错误归入spaces_scope_missing、not_logged_in、oauth_refresh_failed、authentication_failed、spaces_command_failed五类原因;同时所有输出经redact脱敏——测试 spaces.test.mjs 验证了 JWT 形态令牌与cog_API key 在错误详情中会被替换为REDACTED。
端到端实践清单
以下是将整套流程投入实际使用的最小操作序列:
- 安装/构建 CLI:安装
wifi-densepose二进制(或进入 v2/crates/wifi-densepose-cli 构建),并确认其位于PATH; - 激活作用域:
wifi-densepose login --spaces(无浏览器环境加--no-browser),按需用--credentials-path指定非默认凭证存储(仅限人工 CLI); - 验证身份:
wifi-densepose whoami,确认账号报告spaces:read; - CLI 查询:
npx @ruvnet/ruview spaces --resource sites、npx @ruvnet/ruview spaces --resource events --limit 25,用返回的nextCursor翻页; - MCP 部署:以
RUVIEW_MCP_GRANTS=credential-use与RUVIEW_CREDENTIALS_PATH=<路径>启动npx @ruvnet/ruview mcp start,之后才允许ruview_spaces_list调用; - 验证通道:运行
cd harness/ruview && node --test test/spaces.test.mjs test/policy.test.mjs(guidance 记录cognitum-spaces-oauth中给出的验证命令,guidance.js),或在仓库内执行wifi-densepose login --spaces && node harness/ruview/bin/cli.js spaces --resource events。
安全与治理要点小结
- 凭证最小化:bearer token 与 API key 永不进入命令行、工具参数或 MCP 消息;
COGNITUM_SPACES_API兼容密钥被刻意排除在子进程环境外; - 默认拒绝:
ruview_spaces_list在 MCP 下默认不可用,必须由运维人员显式授予credential-use; - 只读且单向:
spaces:read授予的只是读取语义投影的能力;行动授权属于 ADR-321 策略门 的范畴,且需携带新鲜能力证书、边界内不确定性、租户/工作区授权、幂等键与见证回执(ADR-325 第 8 节); - 防反馈洗白:来自 Spaces 的记录若源自 RuView 证据,则携带派生血缘,返回时只能作为投影/回忆,不能提升证据等级、不能作为独立模态融合、不能重置新鲜度(ADR-325 第 6 节)——空列表证明读取路径而非感知质量,这一诚实原则贯穿整个 harness 的
ruview_claim_check守卫。
【免费下载链接】RuViewπ RuView turns commodity WiFi signals into real-time spatial intelligence, vital sign monitoring, and presence detection — all without a single pixel of video.项目地址: https://gitcode.com/GitHub_Trending/wi/RuView
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考