MQTT Topic Structure Migration Guide
Overview
This document describes the unified MQTT topic structure for Roboticks fleet device communication and the migration from the old structure to the new one.New Topic Structure
All device communication now uses the consistent pattern:roboticks/fleet/{device_id}/*
Device → Backend (Publish Topics)
| Topic | QoS | Description |
|---|---|---|
roboticks/fleet/{device_id}/heartbeat | 0 | Device status updates (metrics, location) |
roboticks/fleet/{device_id}/sessions | 1 | Session lifecycle (create/complete) |
roboticks/fleet/{device_id}/logs | 1 | Batched log messages |
roboticks/fleet/{device_id}/file_upload/request | 1 | Request presigned URLs for S3 uploads |
Backend → Device (Subscribe Topics)
| Topic | QoS | Description |
|---|---|---|
roboticks/fleet/{device_id}/session/response | 1 | Session creation responses with UUID |
roboticks/fleet/{device_id}/file_upload/response | 1 | Presigned URL responses |
roboticks/fleet/commands | 1 | Broadcast commands (all devices) |
Old vs New Structure
Before (Mixed Structure)
After (Unified Structure)
Security Enhancement
The new structure enables certificate-based device verification:- Topic-based Device ID: Device ID is extracted from topic path using
topic(3)in IoT Rules - Certificate-based Verification: Lambda functions verify the device_id from topic matches the certificate
- Defense Against Spoofing: A device cannot publish to another device’s topic without the correct certificate
Lambda Verification Pattern
Session Creation Workflow
New Request/Response Flow
1. Device Publishes Session Create (WITHOUT session_id)- Lambda validates certificate matches device_id
- Inserts session into database WITHOUT session_id
- PostgreSQL generates UUID automatically via default value
- Lambda retrieves generated UUID using RETURNING clause
- Store session_id for all subsequent operations
- Include in log messages
- Include in file upload requests
- Send in completion message
Old Flow (Deprecated)
S3 Path Structure
New Simplified Structure
Old Structure (Deprecated)
- Session UUIDs are globally unique
- Device info preserved in session metadata
- Simpler path structure
- Works even if device is deleted
Migration Steps
Backend Infrastructure (✅ Completed)
-
IoT Policy Updated
- File:
infrastructure/lib/roboticks-stack.ts:146-190 - All topics now use
roboticks/fleet/{device_id}/*pattern - Removed legacy topic permissions
- File:
-
IoT Rules Updated
- All rules extract
device_idusingtopic(3) - DeviceHeartbeatRule:
roboticks/fleet/+/heartbeat - SessionRule:
roboticks/fleet/+/sessions - DeviceLogsRule:
roboticks/fleet/+/logs
- All rules extract
-
Lambda Functions Updated
- Added device_id verification in all handlers
- session-handler publishes responses back to device
- presigned-url-handler uses UUID session_id
-
Database Schema Updated
- Added
session_idUUID column with auto-generation - Changed S3 paths to
sessions/{session_id}/ - Device info stored in metadata
- Added
Device SDK (🔄 In Progress)
Required changes in roboticks-sdk:-
Update MQTT Topics (DeviceManager.cpp lines 43-48)
-
Subscribe to Session Response
-
Remove Manual UUID Generation
- Delete code that generates session_id on device
- Remove session_id from create payload
- Wait for backend response
-
Handle Session Response
-
Use Received UUID
- Tag all logs with received session_id
- Include in file upload requests
- Send in completion message
IoT Policy Changes
Before
After
Deployment
Backend Deployment
SDK Updates
Testing Checklist
- Device can connect with new topic structure
- Heartbeats publish to correct per-device topic
- Session create receives UUID response from backend
- Logs include backend-provided session_id
- File uploads use backend-provided session_id
- Session completion works with UUID
- Security verification blocks mismatched device_id
Rollback Plan
If issues arise:- Backend: Previous CDK stack can be redeployed
- IoT Policy: Reverts automatically with CDK
- SDK: Keep old binary version available
- Database: Migration has downgrade script
References
- Infrastructure Stack:
infrastructure/lib/roboticks-stack.ts - Lambda Functions:
infrastructure/lambda/session-handler/index.py - SDK Device Manager:
roboticks-sdk/packages/roboticks-device/src/DeviceManager.cpp - Architecture Design:
docs/ARCHITECTURE_DESIGN.md