ZeroStream
Offboard vehicle-data streaming
Offboard vehicle-data streaming
ZeroStream carries live vehicle data from a device on a rig to the Customer Zero back-office. The device publishes MQTT 5 over TLS to AWS IoT Core, and IoT Core turns the values into CloudWatch metrics per device and signal.
A device's identity is a certificate from ZeroPKI (Offboard Issuing CA). IoT Core trusts only that CA and registers a device the first time it connects, so no one adds devices to IoT Core by hand.
…8883 (MQTT 5 over TLS 1.2+)zero_stream_device. Present the full chain (leaf plus intermediates).A device is called device- followed by six lowercase hex characters, for example device-0a0001. The same name is the cert CN, the IoT thing name, the MQTT client id, the topic segment and the Device dimension. ZeroPKI signs no other form for this service, and IoT Core accepts no other client id for the cert.
Later, the physical id of the hardware (a UUID, or chassis number plus serial number) is recorded against the device name. The name itself never changes.
| Topic | Direction | Carries |
|---|---|---|
… | device → cloud | one signal value, {"value": <number>, "ts": "<ISO 8601>"} |
… | device → cloud | lifecycle: connected, graceful shutdown, last will |
… | cloud → device | a request, e.g. ping |
… | device → cloud | the answer to that request |
A device can publish and receive only under its own name. Signals that become metrics: …. Anything else published under tele/ is dropped, and event is never a signal.
| Namespace | Metric | Dimensions |
|---|---|---|
… | Value | Device, Signal |
… | ConnectionState (1 connected, 0 disconnected) | Device |
CloudWatch buckets at one minute. Only cert-authenticated clients count as devices, so the console MQTT client never shows up.
The key is made on the device and never leaves it; only the CSR travels.
device-0cf12e.NAME=device-0cf12e openssl ecparam -name secp384r1 -genkey -noout -out $NAME.key.pem openssl req -new -key $NAME.key.pem -subj "/CN=$NAME" -out $NAME.csr openssl req -in $NAME.csr -outform DER | shasum -a 256 # compare with the rig page
$NAME.fullchain.pem and copy it to the device, next to its key.NAME=device-$(openssl rand -hex 3) openssl ecparam -name secp384r1 -genkey -noout -out $NAME.key.pem openssl req -new -key $NAME.key.pem -subj "/CN=$NAME" -out $NAME.csr
$NAME.csr to an operator, who submits it to ZeroPKI from the zero-backoffice repo:
sesh CustomerZeroDev cz-developer DevAccess python3 iac-internal/zero-pki-aws/scripts/request_cert.py zero_stream_device --csr $NAME.csrThis writes
coretura-pki-certs/zero_stream_device/$NAME.fullchain.pem and verifies the chain.$NAME.fullchain.pem back to the device, next to its key.Connect to the endpoint with the full chain as client cert, the key, Amazon Root CA 1 as server trust, and the device name as client id. The very first connection is dropped while IoT Core registers the device; reconnect and it streams. The reference publisher does both:
curl -sO https://www.amazontrust.com/repository/AmazonRootCA1.pem
shasum -a 256 AmazonRootCA1.pem
# expect 2c43952ee9e000ff2acc4e2ed0897c0a72ad5fa72c3d934e81741cbd54f05bd1
pip install "paho-mqtt>=2"
python3 iac-internal/zero-stream-aws/scripts/publish.py \
--endpoint … \
--cert $NAME.fullchain.pem --key $NAME.key.pem
On a real device, the Coretura Linux connectivity image carries Paho C/C++ and a trust store with Amazon Root CA 1. Point it at the same endpoint, cert and topics.
aws iot list-thing-principals --thing-name $NAME aws iot update-certificate --certificate-id <old-id> --new-status INACTIVE
On the rig in ZeroTwin, Remove device revokes all its certs and deletes it; adding the hardware again gives it a new name. An operator can instead set one cert to REVOKED (permanent) or INACTIVE (can be undone). The device is refused on its next connect, and a reconnect never switches the cert back on.
aws iot list-thing-principals --thing-name $NAME aws iot update-certificate --certificate-id <id> --new-status REVOKED
ZeroPKI does not publish a CRL yet, so the cert status in IoT Core is the only way to block a device.
With an AWS SSO session in cz-dev, open the IoT Core MQTT test client and subscribe to …. No cert is needed.
In CloudWatch (cz-dev, eu-north-1), graph Value from … per Device and Signal, and ConnectionState from … per Device.
An external Grafana (e.g. in the Coretura account) reads these through CloudWatch cross-account observability (OAM), which shares only the chosen namespaces. A read role cannot be limited to a namespace. OAM is regional: the sink lives in eu-north-1 of the monitoring account, and Grafana queries that region.