デバイスのライフサイクル
Raiznetにおけるデバイスとは、Ed25519鍵ペアとプライバシーポリシーでプロビジョニングされた任意のESP32です。そのアイデンティティは公開鍵です — MACでも名前でもありません。
状態
[製造済] → [プロビジョニング済] → [active] → [inactive] → [lost]
↑ ↓
└────────────┘| 状態 | 意味 |
|---|---|
active | デバイスが正常にテレメトリを報告している |
inactive | デバイスが設定された期間報告していない |
lost | 所有者がデバイスを回復不能とマークした(ハードウェアの破壊または盗難) |
プロビジョニング(実装通り)
リファレンスファームウェアは キャプティブポータル で自身をプロビジョニングします。
- 初回起動時(またはリセット後)、ESP32は一時的なWi-Fiアクセスポイントを作成します。
- 所有者が接続すると、キャプティブポータルが Identity Setup フローを開きます。
- デバイスはハードウェアTRNGから自身のEd25519鍵ペアを生成しNVSに保存します — 秘密鍵はデバイスから決して出ません。
- ポータルは 所有者アイデンティティ 用に新しいBIP-39ニーモニック(12語)を、所有者の言語(PT、EN、ES)で生成するか、既存のものをインポートします。所有者はフレーズを書き留めます。
- 所有者は
publish_to、サーバーアドレス、Wi-Fi認証情報を設定します。 - ESP32はすべてをNVSに書き込み、本番モードで再起動します。
- 遅延登録(lazy): デバイスはセットアップ中に設定済みサーバーへ
POST /v1/devicesを呼び、自身のpubkey、MAC、所有者pubkey、初期プライバシーポリシーを送ります。409(登録済み)は成功としてカウントされます。
アプリ経由のプロビジョニング 計画中
アプリ主導のフローはその上に追加します。フィールドごとのプライバシーポリシー、ネットワーク選択、地図でのH3位置選択、アクティブなSafraのCropをデバイスへ送信。
DeviceClaim 設計
デバイスがプロビジョニングされたとき、所有者の公開イベントログに公開されます。
device_pubkey: bytes(32)
device_mac: bytes(6)
claimed_at: uint64
signature: bytes(64) // 所有者のユーザー鍵で署名任意のピアが所有権チェーンを検証できます。デバイスのテレメトリはデバイス鍵で署名されます; その鍵の所有権は、ユーザー鍵で署名されたDeviceClaimで宣言されます。
所有権の移転(販売) 設計
- 売り手がアプリで「デバイスを移転」を開き、買い手のユーザーpubkeyを入力します。
- 売り手が
DeviceTransferイベントに署名します。 - 買い手が自分のアプリでリクエストを受け取り、受諾を確認して署名します。
- 最終イベント(両方の署名)が買い手の公開イベントログに公開されます。
- ネットワークは新しい
owner_pubkeyを認識し、新しい所有者からのみ設定変更を受け付けます。
device_pubkey: bytes(32)
from_user_pubkey: bytes(32)
to_user_pubkey: bytes(32)
transferred_at: uint64
signature_from: bytes(64) // 売り手
signature_to: bytes(64) // 買い手履歴の読み取りはデバイス鍵で署名されたままです。売り手による古い DeviceClaim は、彼が所有者だった期間の有効な記録としてログに残ります。
ハードウェアの紛失(焼損デバイス)
失効フローはありません。デバイスが破壊された場合:
- 所有者がアプリでそれを
lostとマークします(ローカル状態のみ)。 - 新しいESP32を買い、まったく新しいデバイスとしてプロビジョニングします(新しいpubkey、新しいMAC)。
- グラフでの視覚的連続性を望む場合、アプリは古いデバイスと新しいデバイスを、遷移点に視覚的マーカーを付けた統合シリーズとして表示できます。
- 古いデバイスの履歴データは所有者のサーバーに残り、別途照会できます。
デバイスの秘密鍵はハードウェアとともに失われました — これは望ましいことです。デバイスのクローンには秘密鍵の複製が必要ですが、フラッシュへの物理的アクセスなしには不可能です。
対称鍵のローテーション
各デバイスは ENCRYPTED フィールドに使う対称鍵を持ちます。鍵バージョンは Device.encryption_key_version とすべての TelemetryBlock で追跡されます。
ローテーションフロー:
- 所有者がアプリでローテーションを開始します。
- アプリが新しい対称鍵を生成し、バージョンをインクリメントします。
- 次の接続で新しい鍵をESP32へ送ります。
- ESP32は以降のすべての読み取りに新しい鍵を使います。
- 古い鍵は履歴データの復号のために所有者のアプリの鍵リングに保持されます。
以前に暗号化されたblobを受け取ったピアは、新しい鍵でそれを復号できません — その逆も同様です。ローテーションは鍵が漏れた場合の露出を限定しますが、古い鍵のコピーを持っていた任意の第三者(例: 農学者)に対する復号アクセスを失う代償があります。
Cropの更新
ESP32はアクティブなCropをフラッシュにローカル保存します。アプリはデバイスがサーバーに接続したときに更新を送ります。オフラインなら、デバイスは再接続まで保存版を使い続けます。
Crop更新フロー:
- ネットワークまたは所有者がCropCatalogで更新されたCropを公開する。
- サーバーがカタログから更新をダウンロードする。
- 次のデバイス接続時、サーバーが更新されたCropをESP32へ送る。
- ESP32がフラッシュに書き込み、次の読み取りサイクルから新しい値を使う。