279 lines
28 KiB
Markdown
279 lines
28 KiB
Markdown
# 首次配网设备认证与绑定 SaaS 支撑功能分析
|
||||
|
|
|
|||
|
|
分析日期:2026 年 9 月 11 日
|
|||
|
|
|
|||
|
|
依据:附件《AI电话 首次配网 注册与激活 完整流程与详细设计》,整合日期 2026 年 9 月 8 日,公共契约 ONBOARDING-1.1;以及当前工作区 SaaS 的路由、服务、数据库迁移和前端代码。
|
|||
|
|
|
|||
|
|
结论:现有平台具备设备建档、独立密钥、设备鉴权、家庭和使用者权限、绑定关系、设备配置与命令、供应商凭据和审计等基础,但尚未实现附件要求的完整首次接入流程。主要新增工作是可信首次校时、设备注册协议、云端设置会话、手机入口交接、登录后按键确认绑定,以及绑定状态保存回执。激活任务也需要独立的持久化状态和异常恢复机制。
|
|||
|
|
|
|||
|
|
本分析只列 SaaS 要承担的工作及其设备协议边界。Wi-Fi 扫描、密码保存、AP、NAPT、GPIO 和设备存储的具体实现由设备承担。SaaS 不接收家庭 Wi-Fi 密码。本文区分附件要求、当前实现和实施建议;附件中的设计不代表这些功能已经上线。
|
|||
|
|
|
|||
|
|
核对方式:读取正文、附件 A 至 K 和 5 张流程图;静态检查实际路由和实现。附件列出的 18 个云端接口均未在当前 router 中以相同方法和路径注册,但部分能力有现有服务可复用。附件 H 的 HMAC 示例和三组热点名称向量已离线复算一致。没有进行真实设备、短信服务或供应商联调。
|
|||
|
|
|
|||
|
|
## 1 SaaS 应负责的完整业务顺序
|
|||
|
|
|
|||
|
|
1. 受控生产流程登记设备身份和密钥,建立唯一库存记录。
|
|||
|
|
2. 设备联网后请求可信时间,再携带设备认证信息完成注册和状态恢复。
|
|||
|
|
3. SaaS 为未绑定设备创建设置会话,签发短时手机交接入口。
|
|||
|
|
4. 手机兑换入口并登录账号;服务端保存当前设备上下文,提供有权限的使用者列表。
|
|||
|
|
5. 手机选择使用者并创建绑定申请,此时设备尚未归属于该账号。
|
|||
|
|
6. SaaS 向设备下发当前申请的确认挑战;用户按键后,设备回传对应申请的确认。
|
|||
|
|
7. SaaS 在一次事务内提交绑定、消费申请、增加绑定代数、更新状态版本、写入激活待办。
|
|||
|
|
8. 设备保存绑定并回执;手机读取结果并回执。设置入口按收尾条件关闭。
|
|||
|
|
9. AI 激活任务独立继续;失败、页面关闭或设置会话过期,都不撤销已提交绑定。
|
|||
|
|
|
|||
|
|
必须分别展示三个结果:设备身份已认证、账号已绑定、AI 服务是否可用。SaaS 收到 HTTP 请求成功、设备本地保存成功、真实首音频验证成功,也分别记录。
|
|||
|
|
|
|||
|
|
## 2 功能清单与现有实现对照
|
|||
|
|
|
|||
|
|
“可复用”表示存在相应基础逻辑,不表示已经符合 ONBOARDING-1.1 的报文和全部业务约束。
|
|||
|
|
|
|||
|
|
| SaaS 功能 | 附件要求和用途 | 当前实现 | 需要的工作 |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| 生产身份与库存 | 按完整设备 ID 和出厂 MAC 唯一登记;返修恢复原记录;密钥轮换留审计 | 运维接口可建档、生成随机 UUID 和密钥、轮换凭据 | 增加生产身份映射、MAC 唯一约束和幂等生产登记;区分库存与首次上线 |
|
|||
|
|
| 设备认证 | 按设备和密钥版本验证 DEVREQ1 HMAC,检查时间、nonce、停用和吊销 | 已有 HMAC、时间窗口、防重放、加密密钥存储、状态限制 | 新增 ONBOARDING-1.1 认证适配;现有签名格式不能直接兼容 |
|
|||
|
|
| 首次可信校时 | 用单设备密钥签名时间挑战,设备验签后再严格使用 HTTPS | bootstrap 返回服务器时间,但须先通过现有认证 | 新增 C01;不能把现有 bootstrap 当作无可信时间时的校时入口 |
|
|||
|
|
| 设备注册与恢复 | 只接受已登记的生产身份;重复注册返回原设备、绑定和激活状态 | 设备由运维创建;bootstrap 更新在线报告并返回绑定 | 新增 C02、挑战消费、业务幂等及完整公共状态 |
|
|||
|
|
| 云端设置会话 | 关联设备、启动、本地会话、期限和流程阶段 | 未发现 setup_session 完整实现 | 新增 C03 和设置会话;已绑定设备只进入恢复模式 |
|
|||
|
|
| 手机入口交接 | handoff 与 verifier 摘要匹配,短时、一次性兑换,生成浏览器会话 | 未发现此交接流程 | 新增 C04、Web exchange 和 HTTPS 入口页 |
|
|||
|
|
| 账号登录与使用者权限 | 短信登录或注册、保留 setup、校验有权管理的老人档案 | 已有 OIDC 登录、平台账号映射、家庭成员权限、使用者档案 | 若严格遵循附件需补短信入口与注册映射;也可复用 OIDC,但须修改双方认可的登录契约 |
|
|||
|
|
| 绑定申请 | 登录后固定设备、账号、使用者、绑定代数和挑战;每设备一条有效申请 | 一次性绑定码表存在,但不绑定某次设备按键挑战 | 新增待确认申请;不能直接把现有 claim_code 当作新 claim |
|
|||
|
|
| 设备确认后提交绑定 | 核验 claim、challenge、digest、按键事件和当前权限后原子提交 | 当前 POST /api/v1/device-claims 提交绑定码后直接写绑定 | 新增 C06;保留并扩展行锁、有效绑定唯一约束与审计 |
|
|||
|
|
| 状态版本和保存回执 | 独立 binding_generation、device_revision、local_generation、state_hash;记录设备与页面 ACK | 已有 device.version、activation_revision、配置 revision | 新增明确的绑定代数和状态快照;现有版本不能直接互相替代 |
|
|||
|
|
| 流程命令与进度查询 | CONFIRM_CLAIM、APPLY_ACTIVATION、UPDATE_STATE、CLOSE_SETUP | 已有配置、重启、诊断、OTA 命令 | 增加流程命令及权限、过期、去重规则;通用命令 ACK 不等于绑定确认 |
|
|||
|
|
| 独立激活任务 | 固定设备供应商身份与任务;保存调用许可、尝试结果、未知状态和对账证据 | 已有平台代注册、供应商凭据加密保存和复用 | 新增任务和尝试记录;统一平台代注册与设备 SDK 注册的路线 |
|
|||
|
|
| 中断恢复与设置收尾 | 页面关闭、断电、回包丢失后按原任务恢复;关闭 setup 不解除归属 | 有一般设备查询、解绑、重置和部分请求幂等基础 | 新增 C07/C10/C11、Web status/ack/cancel 及完整恢复规则 |
|
|||
|
|
| 运维处理和验收 | 查阶段、绑定、ACK、激活和失败原因,处理停用、返修、对账 | 设备运维、状态迁移、审计和通用 outbox 已有 | 增加首次接入诊断视图和激活对账;将绑定事件接入 outbox |
|
|||
|
|
|
|||
|
|
## 3 认证和生产登记的具体要求
|
|||
|
|
|
|||
|
|
### 3.1 区分生产登记与设备首次注册
|
|||
|
|
|
|||
|
|
上一轮提取的 `POST /api/v1/ops/devices` 是运维建档入口。附件的 `POST /api/v1/device/register` 是设备证明已有身份并报告上线的入口。两者调用者、鉴权和数据用途不同,不能替换使用。
|
|||
|
|
|
|||
|
|
生产侧至少保存:设备固定编号、出厂 MAC、型号、硬件版本、凭据版本、受控密钥引用、生产及返修记录。设备注册请求不能仅凭公开 MAC 获取新密钥,也不能让请求方自行指定账号归属。
|
|||
|
|
|
|||
|
|
现有 Create 每次生成新 UUID 和随机 serial_digest,没有按输入 MAC 重复登记的能力。建议保留数据库内部 UUID,新增唯一的工厂编号与 MAC 映射,由新协议在边界解析 `KP01-84FCE6123456` 一类编号;无需为匹配外部编号直接重写全部内部外键。
|
|||
|
|
|
|||
|
|
现有 FACTORY 状态不允许通过通用设备认证。若生产登记先进入该状态,还需明确出厂放行到可认证状态的流程,或为新库存认证设置单独的准入规则,不能让新设备被自己的初始状态永久挡住。
|
|||
|
|
|
|||
|
|
### 3.2 HMAC 契约存在实质差异
|
|||
|
|
|
|||
|
|
| 项目 | 附件 ONBOARDING-1.1 | 当前平台 |
|
|||
|
|
|---|---|---|
|
|||
|
|
| 设备编号 | KP01- 加完整 12 位大写 MAC | UUID |
|
|||
|
|
| HMAC 密钥字节 | 原始 32 字节 device_key | 当前运维 Create 返回 64 位 hex 字符串,并把该字符串的 UTF-8 字节作为 HMAC 密钥 |
|
|||
|
|
| 时间字段 | X-Timestamp-Ms,Unix 毫秒 | X-Timestamp,RFC3339 |
|
|||
|
|
| 密钥版本 | X-Key-Version,参与签名和密钥选择 | 密钥库有版本,但当前请求签名不包含版本头 |
|
|||
|
|
| 业务请求号 | X-Request-ID,参与签名和幂等 | 现有五行签名不包含业务请求号;部分业务另用 Idempotency-Key |
|
|||
|
|
| 签名正文 | DEVREQ1 开头的九行,包含设备 ID、版本、请求号;路径不含 query | 方法、包含 query 的 RequestURI、时间、nonce、body 哈希,共五行 |
|
|||
|
|
| 签名传输 | Authorization: Device-HMAC-SHA256 加小写 hex | X-Signature,Base64url 无填充 |
|
|||
|
|
| 时间容差 | ±120 秒 | 默认 ±5 分钟,可配置 |
|
|||
|
|
| nonce | 16 随机字节的 Base64url,按设备和版本保存至少 5 分钟 | 接受 16 至 128 字符;当前按设备和 nonce 防重放 |
|
|||
|
|
|
|||
|
|
Header 名称的大小写不是差异重点;签名所包含的内容、编码、密钥字节和时间含义才是兼容性问题。
|
|||
|
|
|
|||
|
|
建议以独立协议适配层支持新路径,复用密钥加密存储和设备状态查询。旧设备继续使用旧契约,避免在同一入口中静默尝试不同签名算法。密钥迁移需要显式标记编码与版本,不能把当前返回的字符串自动解码后用于旧接口。
|
|||
|
|
|
|||
|
|
### 3.3 首次校时与注册提交
|
|||
|
|
|
|||
|
|
C01 接收公开 device_id、key_version、boot_id、client_nonce,返回只包含时间及挑战的签名响应。未知设备通用拒绝。挑战 120 秒有效,签名域为 `TIME1`,不签发账号、绑定或供应商凭据。
|
|||
|
|
|
|||
|
|
C02 验证设备请求后,原子消费与当前设备、启动关联的 challenge_id,并提交注册结果。同一 request_id、同一原始 body 的已成功重试应返回匹配结果;不同 body 返回冲突。已消费挑战不能阻止读取同一已提交结果,但不能授权一次新注册操作。
|
|||
|
|
|
|||
|
|
## 4 手机登录交接需要新增的功能
|
|||
|
|
|
|||
|
|
SaaS 必须维护独立的 setup 上下文,不能只把 device_id 放入登录页 URL。一次 setup 关联设备、boot_id、本地 local_setup_id、模式、期限和当前阶段;默认 15 分钟,绝对上限 30 分钟。
|
|||
|
|
|
|||
|
|
handoff 默认 90 秒有效,数据库保存 token 哈希,并绑定 setup 与 code_challenge。兑换时核对 verifier 摘要、过期状态和一次性消费状态,再建立浏览器会话。它只证明进入了某次设备流程,不授予设备所有权。
|
|||
|
|
|
|||
|
|
HTTPS 入口页从 URL fragment 读取 token 与 verifier,立即清理地址,再同源 POST 兑换。入口固定白名单、禁止任意跳转,页面不加载第三方统计脚本,凭据响应禁止缓存。SaaS HTTPS 页面不反向请求设备的本地 HTTP 接口。
|
|||
|
|
|
|||
|
|
登录前后都需保留服务端 setup;登录成功后更新会话身份并防止会话固定。按附件实现 Cookie 时,应配置 Secure、HttpOnly 和适合该跳转链路的 SameSite,并执行 Origin/CSRF 检查。短信需按手机号、IP、浏览器流程限流,约束验证码期限和尝试次数。
|
|||
|
|
|
|||
|
|
现有 OIDC 登录和家庭权限可以作为账号基础,但 OIDC 自带的 PKCE 不等于附件中的设备 handoff。若继续复用 OIDC,仍要实现“设备流程交接”和“登录后继续原 setup”。
|
|||
|
|
|
|||
|
|
新用户还需要能创建或进入家庭、创建或选择使用者。现有家庭与档案接口可复用:`POST /api/v1/households`、`GET/POST /api/v1/households/{id}/subjects`。附件没有完整规定账号首次加入租户和家庭的策略,这部分必须补入实施设计。
|
|||
|
|
|
|||
|
|
## 5 绑定事务与状态同步
|
|||
|
|
|
|||
|
|
### 5.1 一次绑定申请固定哪些数据
|
|||
|
|
|
|||
|
|
| 数据 | 为什么需要 |
|
|||
|
|
|---|---|
|
|||
|
|
| device_id、setup_id | 确定当前设备和操作流程 |
|
|||
|
|
| 登录账号、tenant_id、household_id、subject_id | 确定归属范围和使用者;账号从登录态取得 |
|
|||
|
|
| claim_id | 为一次明确申请提供长期业务去重标识 |
|
|||
|
|
| challenge、expires_at | 限定本次物理确认窗口,默认 120 秒 |
|
|||
|
|
| binding_digest | 固定被确认的账号和使用者内容;目标变化就重建申请 |
|
|||
|
|
| expected_binding_generation | 防止旧申请在设备已经换绑后继续生效 |
|
|||
|
|
| press_event_id | 防止旧按键事件重复确认另一笔操作 |
|
|||
|
|
| 状态、取消与消费时间、提交结果引用 | 处理取消、确认、超时和网络重试竞争 |
|
|||
|
|
|
|||
|
|
服务端检查的是经过设备认证的“指定申请确认”,不是相信浏览器上传 `button_pressed=true`。配网前的按键授权也不能作为登录后绑定申请的确认。
|
|||
|
|
|
|||
|
|
### 5.2 在一次事务中完成绑定
|
|||
|
|
|
|||
|
|
建议事务顺序:锁定设备及申请 → 识别同申请的已提交结果 → 核验当前权限、代数和未过期挑战 → 检查唯一有效归属 → 写入绑定 → 绑定代数增加一次 → 消费 claim → 更新 device_revision → 写入激活 outbox 事件和审计 → 提交。
|
|||
|
|
|
|||
|
|
复用当前 device_binding 的有效记录唯一索引和行锁,同时为待确认申请增加唯一约束。取消与确认并发时以事务提交结果为准:取消未完成申请不能删除已提交绑定。
|
|||
|
|
|
|||
|
|
现有绑定码逻辑可以保留为独立入口,但不能绕过新协议的按键确认。新模式需明确哪些设备允许使用旧绑定入口,以及运维强制分配归属是否属于受控例外,否则只增加一个安全入口并不能保证所有绑定都经过同样规则。
|
|||
|
|
|
|||
|
|
重试判断不仅要比较原目标,还要确认绑定仍是当前有效归属。当前旧 claim 的已使用分支会读取原 used_binding_id;新流程必须补上绑定代数和当前状态检查,避免设备已解绑或换绑后再返回旧状态作为可用配置。
|
|||
|
|
|
|||
|
|
### 5.3 两种版本与两种回执
|
|||
|
|
|
|||
|
|
`binding_generation` 只在归属发生变化时递增;`device_revision` 在对设备公开的业务状态变化时递增。`local_generation` 是设备存储版本,由设备报告。普通网络更新不能增加绑定代数,普通配置 revision 也不能冒充绑定代数。
|
|||
|
|
|
|||
|
|
C07 验证 device_revision、binding_generation、local_generation 和 state_hash,记录设备已保存哪一版状态。Web ack 记录手机已看到哪次绑定结果。二者均不改变 owner;设备保存失败也不能回滚服务端绑定。
|
|||
|
|
|
|||
|
|
前台应分别显示“待按键确认”“账号已绑定,设备保存中”“账号已绑定,AI 服务准备中”“AI 服务待处理”“AI 服务可用”。轮询超时后仍能从账号设备列表恢复查看。
|
|||
|
|
|
|||
|
|
## 6 激活支撑与现有路线差异
|
|||
|
|
|
|||
|
|
### 6.1 绑定与激活分别提交
|
|||
|
|
|
|||
|
|
附件要求:一台设备一个当前 activation_job,固定 activation_id 和供应商 device_name;每次实际调用有 attempt_id。绑定事务只写待办,后台再处理外部服务。现有通用 outbox 可复用,但当前 ClaimDevice 并未写入这一类激活待办。
|
|||
|
|
|
|||
|
|
至少需要以下业务状态:NOT_STARTED、RESERVED、CONTACT_POSSIBLE、REGISTERED_OBSERVED、READY、RECONCILE_REQUIRED、BLOCKED。绑定状态则单独使用 UNBOUND、CLAIM_PENDING、BOUND、TRANSFER_PENDING。
|
|||
|
|
|
|||
|
|
当前 FACTORY/CLAIMABLE/BOUND/PROVISIONING/ACTIVE/LOST/REVOKED 是另一组设备生命周期状态。不能仅靠一张枚举映射表就认定两套状态相同,特别是当前 ACTIVE 并没有附件要求的真实首音频验收含义。
|
|||
|
|
|
|||
|
|
### 6.2 外部结果未知时的恢复
|
|||
|
|
|
|||
|
|
外部调用前持久化“可能已调用”的记录;记录许可原始有效期和调用尝试。超时、断电、回包丢失进入 RECONCILE_REQUIRED,禁止自动换 device_name、释放可能占用的名额或并行再次激活。结果成功也应区分 SDK 注册成功和真实通话验证成功。
|
|||
|
|
|
|||
|
|
现有 Provision 在数据库事务和锁持有期间调用 registrar.Register,然后存储凭据并提交。如果供应商已处理但回包丢失,事务可能回滚,尚无附件所需的持久化未知结果和对账任务。确定性的 device_name 与已保存凭据复用可以减少重复身份,但不能替代完整的外部调用结果恢复。
|
|||
|
|
|
|||
|
|
### 6.3 实施前需要统一供应商凭据路线
|
|||
|
|
|
|||
|
|
附件第 8 章和 E.2 描述向设备下发 ProductSecret,由设备执行动态注册。当前代码把 ProductSecret 保留在 SaaS,由平台注册后只向设备下发 DeviceSecret。这是执行位置与凭据边界的差异,不能用增加几个返回字段掩盖。
|
|||
|
|
|
|||
|
|
实施建议:优先在现有平台代注册方案上补持久化任务、尝试记录和对账,并同步修订附件中的激活契约。若最终明确选择设备执行注册,则按该路线重新设计调用许可、配置封装和结果回执。两种路线的供应商行为都需要针对实际 SDK/接口版本验证,本文不据文档宣称其已通过实机验证。
|
|||
|
|
|
|||
|
|
代码中还有 License 内容导入、分配和 ACK 相关模块;当前主 router 未接入相应 License ACK/分配闭环,不能视为已有 ONBOARDING-1.1 的授权对账能力。附件采用权益或名额管理,也没有定义向设备交付 License 文件。应先统一授权模型,再确定复用范围。
|
|||
|
|
|
|||
|
|
## 7 附件明确要求的云端接口
|
|||
|
|
|
|||
|
|
下列 18 条均为附件规定的目标接口,当前没有同路径路由。生产登记、运维管理以及已有家庭/使用者管理接口不包含在这个数量中。
|
|||
|
|
|
|||
|
|
### 7.1 设备调用 SaaS
|
|||
|
|
|
|||
|
|
除 C01 使用专用时间签名协议外,均按附件 B 使用设备 HMAC 和 HTTPS。表中字段为 body,设备 ID、密钥版本和请求号等还须按契约放入认证头。
|
|||
|
|
|
|||
|
|
| 编号 | POST 路径 | 核心输入 | SaaS 负责输出或提交 |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| C01 | /api/v1/device/time-challenges | device_id、key_version、boot_id、client_nonce | 签名时间与短时 challenge_id |
|
|||
|
|
| C02 | /api/v1/device/register | challenge_id、boot_id、hardware_model、hardware_revision、firmware_version、sdk_version | 认证已有生产身份;返回当前状态和契约版本 |
|
|||
|
|
| C03 | /api/v1/device/setup-sessions | boot_id、local_setup_id、transport_profile=LOCAL_WEB | setup_id、期限、轮询间隔、状态 |
|
|||
|
|
| C04 | /api/v1/device/handoffs | setup_id、local_setup_id、code_challenge | 一次性 token、期限、固定 HTTPS 入口 |
|
|||
|
|
| C05 | /api/v1/device/poll | setup_id、boot_id、known_revision | 当前状态、有效流程命令、轮询间隔 |
|
|||
|
|
| C06 | /api/v1/device/claim-confirmations | claim_id、challenge、binding_digest、expected_binding_generation、press_event_id | 提交绑定或返回同一已提交结果 |
|
|||
|
|
| C07 | /api/v1/device/state-acks | device_revision、binding_generation、local_generation、state_hash | 保存设备落盘证据及可否收尾 |
|
|||
|
|
| C08 | /api/v1/device/activation-attempts | activation_id、config_version、attempt_id | 持久化可能调用状态,返回 30 秒执行许可 |
|
|||
|
|
| C09 | /api/v1/device/activation-results | activation_id、attempt_id、stage、sdk_result、outcome | 更新注册/通话验收状态或转入对账 |
|
|||
|
|
| C10 | /api/v1/device/activation-acks | activation_id、local_generation、config_version | 保存激活配置落盘回执 |
|
|||
|
|
| C11 | /api/v1/device/setup-close | setup_id、reason、final_revision | 关闭临时流程,保留绑定和激活任务 |
|
|||
|
|
|
|||
|
|
公共状态包含 device_id、device_revision、binding_generation、binding_state、activation_state、next_action、state_hash。C05 的状态恢复权限不能随手机 token 或原 setup 过期而消失;需要时先创建仅用于恢复的新 setup。
|
|||
|
|
|
|||
|
|
### 7.2 手机调用 SaaS
|
|||
|
|
|
|||
|
|
| POST 路径 | 核心输入或上下文 | 用途 |
|
|||
|
|
|---|---|---|
|
|||
|
|
| /api/v1/web/handoffs/exchange | token、verifier | 登录前兑换一次性入口,创建当前 setup 的浏览器会话 |
|
|||
|
|
| /api/v1/web/auth/sms/send | 手机号和当前流程;附件未完整定义字段 schema | 发送登录验证码并限流 |
|
|||
|
|
| /api/v1/web/auth/sms/verify | 手机号、验证码和当前流程;附件未完整定义字段 schema | 验证、登录或注册,更新会话并保留 setup |
|
|||
|
|
| /api/v1/web/claims | elder_id、expected_binding_generation、登录会话 | 创建待设备按键确认的绑定申请 |
|
|||
|
|
| /api/v1/web/setup/status | 浏览器当前 setup | 查询自己的绑定和激活进度 |
|
|||
|
|
| /api/v1/web/setup/ack | 浏览器当前 setup 及收到结果的上下文 | 确认页面已收到结果 |
|
|||
|
|
| /api/v1/web/claims/cancel | 当前 setup 的待确认申请 | 取消待确认申请;不解绑已经归属的设备 |
|
|||
|
|
|
|||
|
|
设备收到的 masked_account 只用于提示核对,不接受它作为认证依据。用户身份从登录会话取得;不能信任浏览器提交的 owner_user_id,也不能允许浏览器仅凭任意 device_id 查询其他家庭的状态。
|
|||
|
|
|
|||
|
|
### 7.3 可复用的当前入口
|
|||
|
|
|
|||
|
|
| 当前接口或模块 | 可复用范围 | 无法直接替代的部分 |
|
|||
|
|
|---|---|---|
|
|||
|
|
| POST /api/v1/ops/devices | 运维建档、初始平台凭据 | 生产 MAC 幂等登记和 C02 设备认证注册 |
|
|||
|
|
| POST /api/v1/ops/devices/{id}/credentials/rotate | 受控凭据更新 | ONBOARDING-1.1 按版本认证和产线恢复协议 |
|
|||
|
|
| GET /device/v2/bootstrap | 在线报告、当前绑定和固件兼容检查 | 首次时间挑战、setup、绑定代数与完整恢复状态 |
|
|||
|
|
| GET /device/v2/config | 配置查询与版本基础 | CFG1 配置、绑定代数和明确的本地保存 ACK |
|
|||
|
|
| POST /api/v1/device-claims | 家庭权限、绑定码、绑定写入与唯一约束 | 登录后的待确认申请及实体确认挑战 |
|
|||
|
|
| GET /device/v2/commands 及命令 ACK | 命令投递和回执基础 | 四种首次接入命令与具体绑定确认语义 |
|
|||
|
|
| POST /device/v3/hardware-agent-credentials:provision | 平台代注册、固定设备名、加密凭据及复用 | 独立激活任务、执行许可、未知结果对账和 READY 验收 |
|
|||
|
|
| binding-impact / binding-change | 当前家庭权限、解绑与变更前检查 | 新确认流程、绑定代数与所有旧入口失效策略 |
|
|||
|
|
| OIDC、家庭和使用者服务 | 账号认证、成员权限、档案管理 | 手机 handoff、setup Cookie、附件指定短信 schema |
|
|||
|
|
|
|||
|
|
## 8 数据模型和后台页面
|
|||
|
|
|
|||
|
|
以下是逻辑记录划分,可按现有结构扩展,不要求每一项都另建一张表。
|
|||
|
|
|
|||
|
|
| 逻辑记录 | 关键数据和约束 |
|
|||
|
|
|---|---|
|
|||
|
|
| 生产库存和凭据 | 唯一工厂 ID/MAC、内部设备 UUID、租户归属、型号、密钥引用及版本、生产/返修状态 |
|
|||
|
|
| 时间挑战 | 设备、版本、boot_id、client_nonce、签发/失效/消费时间及注册结果关联 |
|
|||
|
|
| 设备当前状态 | 独立绑定和激活状态、device_revision、binding_generation、当前任务、最后在线时间 |
|
|||
|
|
| 设置会话和交接入口 | setup/local_setup/boot 关联、模式、权限、绝对期限、token 哈希、verifier 摘要、消费状态 |
|
|||
|
|
| 绑定申请和绑定历史 | 目标账号/家庭/使用者、挑战、digest、按键事件、期限、代数;唯一有效申请和归属 |
|
|||
|
|
| 状态快照和回执 | 状态 hash、设备保存版本、页面看到的结果、ACK 时间;旧版本不能覆盖新版本 |
|
|||
|
|
| 激活任务和尝试 | 固定供应商身份、权益预留、attempt、许可期限、调用阶段、结果证据、待对账原因 |
|
|||
|
|
| 幂等结果和 outbox | 设备/接口/请求号作用域、原始 body 摘要、提交结果;长期业务唯一键;待办重试和消费去重 |
|
|||
|
|
| 审计记录 | 操作者、设备、setup、claim、activation/attempt、旧/新状态及错误码;不记录密钥和验证码 |
|
|||
|
|
|
|||
|
|
用户侧至少需要:入口恢复页、登录页、家庭/使用者选择页、等待按键确认页、绑定完成及设备保存状态、AI 服务进度、正常账号设备列表。
|
|||
|
|
|
|||
|
|
运维侧至少需要:按工厂编号/MAC 查库存与设备、出厂放行与凭据轮换、首次接入阶段诊断、当前绑定及历史代数、设备/页面 ACK 状态、激活异常与人工对账记录、停用和报失处置。
|
|||
|
|
|
|||
|
|
## 9 附件在当前 SaaS 中还需明确的设计点
|
|||
|
|
|
|||
|
|
1. **租户和 owner 映射。** 当前设备、家庭和档案受租户约束,归属主要通过 household/subject 表达。附件没有规定新手机号注册到哪个租户、能否认领其他租户库存,以及 owner 是家庭还是单一账号。建议按生产归属解析租户,并继续验证家庭管理权限;不要直接让手机号或 elder_id 决定租户。
|
|||
|
|
2. **身份编码迁移。** 外部 KP01 编号与现有 UUID 保持稳定映射;产线、认证、售后和旧客户端不得各自生成新身份。
|
|||
|
|
3. **绑定代数的变更规则。** 附件规定归属变化递增,但需要进一步固定“解绑后再绑定”和“一步转移”的递增及历史记录规则。所有写入口必须统一。
|
|||
|
|
4. **普通重新配网与恢复出厂。** 当前 /device/v3/factory-reset 会解除绑定并生成新绑定码。附件规定普通重配网保留 owner,转让走原账号授权。因此普通重配网不能调用此接口,完整恢复出厂的归属权限也需要单独定规则。
|
|||
|
|
5. **激活执行位置与授权模型。** 统一平台代注册还是设备 SDK 注册、ProductSecret 的位置、名额与供应商权益的对应关系,以及什么证据足以解除未知结果状态。
|
|||
|
|
6. **接口详细 schema。** 短信输入、取消目标、浏览器 ACK 的版本匹配、部分恢复错误及晚到结果规则仍需写入 OpenAPI。公共约定要求变更请求带 X-Request-ID,浏览器这些写操作也应明确其用法。
|
|||
|
|
7. **状态快照和 ACK。** 明确 device_revision 对应的历史状态保留策略;当前状态继续推进时,设备应同步最新版本,不能把旧 ACK 写成新版本已保存。
|
|||
|
|
8. **存量入口。** 现有绑定码、运维分配、解绑转移和恢复出厂均会影响归属。新协议不能只覆盖新页面而遗漏其他写入口。
|
|||
|
|
|
|||
|
|
## 10 建议开发顺序与验收
|
|||
|
|
|
|||
|
|
第一阶段先完成认证与绑定:生产身份映射 → 新鉴权与时间挑战 → 注册和公共状态 → setup/handoff → 登录与使用者选择 → 待确认申请 → 设备确认事务 → 两侧回执与收尾。此阶段可返回“已绑定,AI 服务待开通”,不阻塞于真实供应商联调。
|
|||
|
|
|
|||
|
|
第二阶段补齐激活:绑定 outbox → 固定激活任务与身份 → 调用尝试和许可 → 结果上报与对账 → 激活配置 ACK → 首音频验收后的 READY。
|
|||
|
|
|
|||
|
|
第三阶段完成运营闭环:停用和密钥轮换、返修、原账号解绑与新账号确认、旧代数隔离、失败恢复入口、诊断视图及生产环境限流监控。
|
|||
|
|
|
|||
|
|
必须覆盖的验收结果:
|
|||
|
|
|
|||
|
|
- 同 MAC/工厂 ID 重复生产登记和重复上线,不增加设备副本,也不清空已有绑定。
|
|||
|
|
- 错密钥、错版本、过期时间、重放 nonce 被拒绝;同请求号不同 body 返回冲突。
|
|||
|
|
- handoff 仅能兑换一次,过期不能复活;登录和浏览器切换后可恢复正确设备上下文。
|
|||
|
|
- 无设备确认不能绑定;双账号并发仅一条有效申请和一个有效归属。
|
|||
|
|
- 旧 challenge、旧按键、被取消 claim、旧绑定代数不能建立新归属。
|
|||
|
|
- 绑定提交后回包丢失,返回同一有效结果;设备保存失败只补写和 ACK,不撤销绑定。
|
|||
|
|
- 页面关闭、setup 到期或热点关闭后,设备仍能恢复原激活任务。
|
|||
|
|
- 供应商结果未知保留原任务、设备名和可能占用的权益;不自动释放后再次分配。
|
|||
|
|
- SDK 注册成功与真实通话 READY 分开;授权不足保留账号绑定。
|
|||
|
|
- 普通重配网保留归属;正式解绑或转移使旧会话、旧申请和旧用户配置失效。
|
|||
|
|
|
|||
|
|
## 11 当前代码依据
|
|||
|
|
|
|||
|
|
- [实际路由与设备鉴权分组](E:/Codex/story/platform/internal/httpapi/router.go:297)
|
|||
|
|
- [运维登记设备和生成平台凭据](E:/Codex/story/platform/internal/opsdevice/service.go:244)
|
|||
|
|
- [当前设备 HMAC 验证和签名正文](E:/Codex/story/platform/internal/deviceauth/verifier.go:69)
|
|||
|
|
- [设备凭据加密存储与轮换](E:/Codex/story/platform/internal/deviceauth/database_secret.go:115)
|
|||
|
|
- [bootstrap 的现有状态字段和报告](E:/Codex/story/platform/internal/device/repository.go:32)
|
|||
|
|
- [当前提交绑定码后直接绑定的逻辑](E:/Codex/story/platform/internal/saas/device_claim.go:27)
|
|||
|
|
- [有效设备绑定唯一约束](E:/Codex/story/platform/migrations/000005_device_conversation.up.sql:65)
|
|||
|
|
- [当前 claim 数据结构](E:/Codex/story/platform/migrations/000007_device_claim.up.sql:3)
|
|||
|
|
- [当前设备生命周期状态](E:/Codex/story/platform/internal/deviceactivation/state.go:15)
|
|||
|
|
- [当前解绑和转移事务](E:/Codex/story/platform/internal/saas/device_binding_service.go:67)
|
|||
|
|
- [当前命令类型约束](E:/Codex/story/platform/migrations/000011_device_command.up.sql:8)
|
|||
|
|
- [平台代注册与供应商凭据保存](E:/Codex/story/platform/internal/hardwareprovision/service.go:127)
|
|||
|
|
- [License 模块](E:/Codex/story/platform/internal/hardwarelicense/service.go:250)
|
|||
|
|
- [恢复出厂解除绑定](E:/Codex/story/platform/internal/devicereset/service.go:168)
|
|||
|
|
- [现有前端 OIDC 登录](E:/Codex/story/platform/web/src/auth/oidc.ts:6)
|
|||
|
|
- [通用 outbox 执行基础](E:/Codex/story/platform/internal/outbox/worker.go:1)
|