AOVIS AWS IoT / KVS Config Skeleton
本文档面向 AI 工具 + 开发者,记录样机/ODM 联调前的 AWS IoT Core + KVS 配置骨架。 不是最终生产 IaC,不替代 AWS SA PDF(
~/Library/CloudStorage/OneDrive-Personal/IP Camera/AWS KVS/AOVIS — AWS 技术快速上手指南.pdf)。 相关架构权威文档:docs/aws-ai-architecture.md
1. Scope
本文档定位:
- 当前阶段的 config skeleton,供样机联调、ODM 协议对齐、预生产检查用
- 记录 repo-local 已实现的 app-side endpoint 和 AWS 命名约定
- 列出 AWS 侧需要手动或脚本创建的配置项(IoT Rule / Credentials Provider / Fleet Provisioning)
- 提供 preflight checklist,确保 env / naming / endpoint / policy 齐全后再启动联调
本文档不涉及:
- 实际创建或修改 AWS 资源(见
scripts/deploy/下的脚本和 AWS Console 操作) - 替代 AWS SA PDF(架构 source of truth)
- 替代 ODM 固件协议文档
- 包含任何密钥、证书、token 明文
2. Current Implemented App-Side Endpoints
以下 endpoint 已在本仓库实现:
| Endpoint | Method | 职责 | 文件 |
|---|---|---|---|
/api/internal/aws/iot-event | POST | 接收 IoT 事件 webhook;HMAC 签名校验;timestamp skew 检查;dedup;写 IotEvent 表;按 event type 触发 push processing worker | app/api/internal/aws/iot-event/route.ts |
/api/devices/[id]/stream | GET | KVS HLS 播放回放(KVS GetHLSStreamingSessionURL 返回 HLS session URL) | app/api/devices/[id]/stream/route.ts |
/api/devices/[id]/webrtc | GET | KVS WebRTC signaling endpoints + ICE server 信息(供客户端 SDK 建联) | app/api/devices/[id]/webrtc/route.ts |
/api/devices/[id]/clip | POST | KVS GetClip 生成视频片段并返回 video/mp4 二进制流 | app/api/devices/[id]/clip/route.ts |
/api/internal/push/register | POST | PushToken 注册(APNS / FCM device token → SNS Platform Endpoint) | app/api/internal/push/register/route.ts |
/api/cron/daily-summary | GET | Daily Summary 定时任务(EventBridge / Vercel Cron 触发) | app/api/cron/daily-summary/route.ts |
设备 push token 注册链路:
App → POST /api/internal/push/register
→ upsert PushToken 表
→ SNS createPlatformEndpoint
→ 回填 endpointArn
IoT 事件推送链路:
设备 MQTT → AWS IoT Rule → /api/internal/aws/iot-event
→ HMAC 校验 + dedup + 写 IotEvent
→ processEventForPush (fire-and-forget)
→ S3 下载缩略图
→ Bedrock Nova Lite classifyThumbnails
→ 写 CloudEvent
→ SNS sendPushToEndpoint
3. Naming Rules
命名规则定义在 lib/aws/resource-names.ts,通过 env 配置前缀。
| 资源 | 模式 | 默认前缀 | 示例 |
|---|---|---|---|
| IoT Thing | ${AWS_IOT_THING_PREFIX}${aoviseDeviceId} | aovis-dev- | aovis-dev-n4k-000001 |
| KVS Stream | ${KVS_STREAM_PREFIX}${aoviseDeviceId} | aovis-stream- | aovis-stream-n4k-000001 |
| KVS WebRTC Channel | ${KVS_CHANNEL_PREFIX}${aoviseDeviceId} | aovis-webrtc- | aovis-webrtc-n4k-000001 |
生产检查项:
- AWS_IOT_THING_PREFIX:生产应改为
aovis-(去掉-dev后缀),避免与 staging 冲突 - KVS_STREAM_PREFIX:同上
- KVS_CHANNEL_PREFIX:同上
aoviseDeviceId是设备唯一硬件标识符(由 ODM/供应商在烧录时确定,与 serial number 映射关系待 ODM 确认)
4. IoT Rule Skeleton
4.1 目标
设备 MQTT event → AWS IoT Rule → app webhook endpoint。
当前阶段推荐 IoT Rule 不直接调用 webhook,走 IoT Rule → Lambda adapter → webhook 的架构,因为 IoT Rule 无法直接添加 HMAC 签名 header。
4.2 推荐方案
设备 MQTT topic: aovis/{aoviseDeviceId}/event
→ IoT Rule (SQL: SELECT * FROM 'aovis/+/event')
→ Lambda (Python/Node.js, 加 HMAC header)
→ HTTP POST /api/internal/aws/iot-event
Payload 字段约定(IotEventPayload 类型):
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
thing_name | string | ✅ | IoT Thing name |
event_type | string | ✅ | motion, alarm, human_detected, vehicle_detected, pet_detected, package_detected |
timestamp | number | 推荐 | Unix epoch seconds,webhook 端会做 300s skew 校验 |
event_id | string | 推荐 | 设备生成的事件 UUID,用于 dedup |
thumbnail_s3_key | string | Type 1 push | 缩略图 S3 key,格式:thumbnails/{aoviseDeviceId}/{eventId}.jpg |
4.3 HMAC 签名要求
webhook endpoint 强制校验 x-iot-signature header:
- 算法:HMAC-SHA256
- secret:
IOT_EVENT_WEBHOOK_SECRET(env 配置) - 签名内容:raw request body
重要:AWS IoT Rule 的 Lambda 或 HTTP action 无法直接添加自定义 header。如果使用 IoT Rule 的 HTTP action,必须:
- 方案 A(推荐):IoT Rule → Lambda(Python/Node.js,在代码中计算 HMAC →
x-iot-signatureheader)→ HTTP POST webhook - 方案 B:IoT Rule → Lambda → SQS → app lambda handler(增加延迟和复杂度,不推荐)
无论哪种方案,不要关闭 webhook 端的 HMAC 校验。
4.4 当前实现中的 webhook 校验
app/api/internal/aws/iot-event/route.ts 会校验:
x-iot-signatureheader 存在且 HMAC-SHA256 匹配timestamp在 ±300s 窗口内(防止重放)dedupKey在 DB 中不重复(幂等)
4.5 现阶段(Lambda 未部署时)
Lambda 抽取不在本次范围。联调期间可用以下方式模拟 IoT Rule:
# 本地 mock
curl -X POST https://{domain}/api/internal/aws/iot-event \
-H "content-type: application/json" \
-H "x-iot-signature: $(echo -n '{"thing_name":"aovis-dev-n4k-000001","event_type":"motion","timestamp":'$(date +%s)',"event_id":"test-001"}' | openssl dgst -sha256 -hmac "$IOT_EVENT_WEBHOOK_SECRET" -hex | awk '{print $2}')" \
-d '{"thing_name":"aovis-dev-n4k-000001","event_type":"motion","timestamp":'$(date +%s)',"event_id":"test-001"}'
5. IoT Credentials Provider Skeleton
5.1 目标
设备用 X.509 证书通过 IoT Credentials Provider 获取临时 AWS credentials,用于直传:
- KVS Streams:putMedia(H.265 视频直传)
- KVS WebRTC Signaling:Connect / SendSessionInitiationMessage / etc
- S3 PutObject:事件缩略图上传(
thumbnails/prefix)
5.2 架构
设备 (X.509 证书)
↓ MQTT / HTTPS
IoT Core Credentials Provider
↓ AssumeRoleWithCertificate
临时 AWS credentials (1-12h TTL)
↓
直传 KVS / S3
5.3 需要创建的 AWS 资源
| 资源 | 说明 | 状态 |
|---|---|---|
| IAM Role | Credentials Provider 扮演的 role,信任策略指定 credentials.iot.amazonaws.com | ❌ 需手动/脚本创建 |
| IAM Policy for Role | 权限:kinesisvideo:PutMedia / kinesisvideo:ConnectAsMaster / s3:PutObject | ❌ 需手动/脚本创建 |
| IoT Role Alias | Credentials Provider 的 role alias(如 AovisCameraCredentialRole) | ❌ 需手动/脚本创建 |
5.4 权限范围(推荐)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kinesisvideo:PutMedia",
"kinesisvideo:DescribeStream",
"kinesisvideo:GetDataEndpoint"
],
"Resource": "arn:aws:kinesisvideo:us-east-1:${account}:stream/${prefix}*"
},
{
"Effect": "Allow",
"Action": [
"kinesisvideo:ConnectAsMaster",
"kinesisvideo:DescribeSignalingChannel",
"kinesisvideo:GetSignalingChannelEndpoint"
],
"Resource": "arn:aws:kinesisvideo:us-east-1:${account}:channel/${prefix}*"
},
{
"Effect": "Allow",
"Action": ["s3:PutObject"],
"Resource": "arn:aws:s3:::aovis-video-storage/thumbnails/${aoviseDeviceId}/*"
}
]
}
5.5 待 ODM/固件确认
- Certificate provisioning 流程:claim certificate 还是 per-device cert?
- Role alias 名称:约定一致
- Credentials TTL:建议 6h(与 KVS stream 生命周期匹配)
- IoT Policy 是否需要附加
iot:Connect和iot:Subscribe到 Credentials Provider topic
6. Fleet Provisioning Skeleton
6.1 目标
量产时自动注册 IoT Thing + 颁发证书,无需人工调用 registerDevice()。
6.2 流程
设备烧录 claim certificate
↓ 首次启动
MQTT 请求 Fleet Provisioning
↓ CreateKeysAndCertificate + CreateThing
设备收到新证书 + Thing Name
↓
后续都用新证书通信
6.3 需创建的 AWS 资源
| 资源 | 说明 | 状态 |
|---|---|---|
| Fleet Provisioning Template | 定义 Thing Name 生成规则、IoT Policy 附件、Attributes | ❌ 等待 ODM |
| Claim Certificate | 允许 iot:CreateKeysAndCertificate 和 iot:CreateThing 的证书 | ❌ 等待 ODM |
6.4 待 ODM/固件确认
| 项 | 说明 |
|---|---|
| 烧录方式 | claim certificate 在工厂烧录,还是通过 bootloader 注入 |
| aoviseDeviceId 映射 | serial number → aoviseDeviceId 规则(或 MQTT 消息中协商) |
| Thing Name 生成规则 | IoT Core 端随机生成还是设备指定 |
| Certificate 管理模式 | per-device cert 还是 1:1 claim->delivery cert 切换 |
| MQTT topic | Fleet Provisioning 标准 topic 还是自定义 topic |
| 设备属性 | Thing Attributes 中包含 model / firmware / mac 等 |
6.5 当前阶段
Fleet Provisioning 模板暂不落地。样机联调阶段先用手动 registerDevice() 创建 Thing。
7. Preflight Checklist
7.1 AWS 账户 / 区域
- AWS account ID:
288669178338 - 主要区域:
us-east-1 - AWS CLI profile 可用:
aws sts get-caller-identity - Bedrock Nova Lite 可用:
aws bedrock list-inference-profiles --region us-east-1
7.2 Env 配置(本地 staging / 生产)
| 变量 | 默认值 | 生产预期值 | 检查要点 |
|---|---|---|---|
AWS_REGION | us-east-1 | us-east-1 | |
AWS_IOT_ENDPOINT | 空 | xxxxxxxxxxxxx-ats.iot.us-east-1.amazonaws.com | 必须设为 ATS endpoint |
AWS_IOT_POLICY_NAME | AovisCameraThingPolicyV1 | AovisCameraThingPolicyV1 | 确认 IoT Policy 已在 AWS 创建 |
AWS_IOT_THING_PREFIX | aovis-dev- | aovis- | 生产去掉 -dev |
KVS_STREAM_PREFIX | aovis-stream- | aovis-stream- | |
KVS_CHANNEL_PREFIX | aovis-webrtc- | aovis-webrtc- | |
KVS_DATA_RETENTION_HOURS | 720 | 720 | 不得小于 entitlement 最大 retention |
KVS_MEDIA_TYPE | video/h265 | video/h265 | 必须,否则 Console 预览异常 |
IOT_EVENT_WEBHOOK_SECRET | 空 | 已设置 | HMAC 签名用 |
SNS_APNS_PLATFORM_ARN | 空 | 已创建 | 通过 setup-sns-platform-apps.sh 创建 |
SNS_FCM_PLATFORM_ARN | 空 | 已创建 | 同上 |
BEDROCK_MODEL_ID | us.amazon.nova-pro-v1:0 | us.amazon.nova-pro-v1:0 | 必须带 us. 前缀 |
BEDROCK_LITE_MODEL_ID | us.amazon.nova-lite-v1:0 | us.amazon.nova-lite-v1:0 | 必须带 us. 前缀 |
BEDROCK_DAILY_MODEL_ID | us.amazon.nova-lite-v1:0 | us.amazon.nova-lite-v1:0 | 必须带 us. 前缀 |
S3_BUCKET_NAME | aovis-video-storage | aovis-video-storage | |
CRON_SECRET | 空 | 已设置 | cron endpoint 鉴权 |
7.3 非 env 配置
- IoT Policy:
AovisCameraThingPolicyV1已创建,包含iot:Connect/iot:Publish/iot:Subscribe/iot:Receive - KVS MediaType:
lib/aws/kvs.ts从env.kvsMediaType读取,lib/env.ts默认值video/h265。生产应显式确认该值为video/h265 - SNS Platform Apps:APNS + FCM 已创建(
scripts/deploy/setup-sns-platform-apps.sh) - IoT Role Alias:Credentials Provider role alias 已创建
- CORS(如需要 web 端直传 KVS):已配置
- S3 lifecycle:
thumbnails/前缀配置自动过期(建议 7 天)
7.4 生产运行时 NOT 设置
-
AWS_BEARER_TOKEN_BEDROCK:不要在 production runtime 设置(测试床遗留变量,会干扰 AWS SDK 正常鉴权)
8. Explicit Non-Goals
以下内容不在本文档范围内,也不在当前阶段实施:
- ❌ Amazon Rekognition — AOVIS 架构不使用此服务(参见
docs/aws-ai-architecture.md §3.1) - ❌ Claude on Bedrock — AOVIS 账户 geo-restricted,无法使用(参见 §3.7)
- ❌ Lambda 抽取 — IoT Rule → Lambda adapter 是未来 sprint 工作,不在本文档范围
- ❌ device binding 新流程 — 设备绑定已在 Sprint 0 预埋,不扩展新流程
- ❌ mobile App push client — 本文档只覆盖 server-side 配置,不覆盖 iOS/Android push client
- ❌ Cognito 认证集成 — 设备临时凭证走 IoT Credentials Provider,不走 Cognito
- ❌ Fleet Provisioning template 实际创建 — 本文档只保留 checklist,等待 ODM 确认后实施
文档版本: v1.0 (2026-05-17)
关联文档: docs/aws-ai-architecture.md | docs/ai-push-pipeline-implementation-plan.md | lib/aws/resource-names.ts | lib/env.ts