Files

4.1 KiB
Raw Permalink Blame History

NekoNest Cloud 状态模型

账号、租户与席位

  • 一个 Cloud 账号拥有一个 tenant_instances 记录。
  • 一个 activeslot_state=active 的主机占一个席位,在线与否不改变计数。
  • 未过期的 waiting pairing 只预留容量;取消、过期或成功 claim 后释放预留。
  • pairing 创建与 claim 都在写入 SQL 内复核容量。第 N+1 台返回 device_capacity_exceeded
  • 账户所有者可以轮询自己创建的配对状态,但不能读取其他账户的请求。
  • 等待中的请求可由所有者取消;若 daemon 已先认领,则取消失败,不能撤销已提交的设备凭据。
  • 主机撤销将主机标记为 deactivated、撤销所有设备凭证、释放席位,并推进 authorization revision。
  • 同一身份恢复复用原 host ID;不能因复制公开指纹而获得第二个身份。

席位允许设备成为租户成员,不自动授权任何手机读取该设备。

Placement

tenant_placements 是共享 Relay 的部署权威:

  • home_region_id 固定租户主区域;
  • relay_node_id 指向当前唯一可写节点;
  • generation 只能单调增加;
  • state 首版使用 provisioning|active|quiescing|copying|switching|draining|failed

客户端只看到稳定 Connect origin。provisioning 时在同一地址重试,不得到后端节点 URL。

授权 revision

每个租户有一条 tenant_authorization_state

  • status=active|suspended
  • revision 在成功 claim、主机撤销、手机撤销或租户暂停时单调增加;
  • 变更只有在相应设备/主机写入已经成功时才推进,避免未提交操作造成虚假撤销。

Relay 获取最长 5 分钟的签名快照,每 60 秒完整刷新、默认每 5 秒检查 revision(delta 与随后的完整刷新各限制为 3 秒)。控制面不可达时不建立新 principal;现有连接最多存活到快照到期。

节点与签名密钥

节点状态为 provisioning|active|draining|offline|retired。heartbeat 只接受非回退 generation。节点以 D1 中未撤销、未过期的 SPIFFE ID 与证书 SHA-256 指纹记录为身份。所有内部调用必须先通过受信 mTLS 终止层注入绑定 method/path 的短时 HMAC assertion;控制面不要求共享 bearer。

Ed25519 私钥不进入 D1。relay_signing_keys 只保存 public JWK、private_key_refkid、有效期与状态。签名密钥必须至少有效到新快照的 expires_at;轮换重叠必须长于 5 分钟最大快照 TTL,旧 public JWK 也必须保留超过最后一份旧 key 快照的 TTL,保证验证窗口不断裂。

Phone handoff

phone_handoff_tickets 生命周期:issued → consumedissued → expired。ticket

  • 随机 256 bit
  • D1 只保存 SHA-256 摘要;
  • 绑定账号、租户、精确 PWA origin;
  • 60 秒有效;
  • 条件 UPDATE 原子消费一次。

控制面只允许目标 placement 节点原子消费 ticket,并向该节点返回 tenant 与手机公钥。目标 Relay Engine 创建独立 phone principal/token 后,把 routing-only handle 摘要登记回来。控制面不生成或保存 phone token。该流程不创建 device grantroute handle 只负责解析 tenant placement,不能替代 phone token。

每次 phone WS/REST 入口都必须同时校验 route handle 摘要与 phone token 摘要,并要求两者绑定同一未撤销 phone principal 和 tenant;单独持有 route handle 不构成授权。已消费或已过期 ticket 只短暂保留摘要和公开身份字段用于防重放诊断,24 小时后由维护任务删除;D1 从未保存明文 ticket。

数据边界

D1 保存账号、权益、主机身份元数据、凭证摘要、placement、授权 revision、公钥、ticket/route 摘要和审计。新增表不得出现 prompt、session、attachment 明文或私钥。

控制面 last_used_at 只证明设备凭证最近成功通过授权,不证明租户 relay、WebSocket、Relay Engine 或本地 Agent 在线。

遗留 grace_days 不参与资格、设备认证或页面判断。

加载、离线和页面失败是客户端展示状态,不得改写控制面 placement、授权或主机身份事实。