diff --git a/docs/enrollment-and-activation.md b/docs/enrollment-and-activation.md index 23279b1..ec2b683 100644 --- a/docs/enrollment-and-activation.md +++ b/docs/enrollment-and-activation.md @@ -46,13 +46,13 @@ sequenceDiagram participant G as Go backend B->>B: random Client ID, X25519 keypair (b, B), nonce n1 B->>M: CONNECT (TLS, anonymous, clientId=random) - B->>G: enroll/request/ {B, n1, mac} + B->>G: enroll/request/{cid} {B, n1, mac} G->>G: create FN record, ephemeral (s, S) - G->>G: shared = X25519(s, B); pw = HKDF(shared, FN, n1) + G->>G: shared = X25519(s, B), pw = HKDF(shared, FN, n1) G->>M: Dynamic Security: create client FN, pw, role board-bootstrap - G->>B: enroll/response/ {FN, S, sig} (not retained) + G->>B: enroll/response/{cid} {FN, S, sig} (not retained) B->>B: verify sig with pinned public key - B->>B: shared = X25519(b, S); same pw + B->>B: shared = X25519(b, S), same pw B->>B: persist FN + pw to flash B->>M: reconnect as FN / pw ``` @@ -94,13 +94,13 @@ sequenceDiagram participant G as Go backend participant M as Mosquitto participant B as Board (FN) - B->>G: board//activation/request + B->>G: board/{FN}/activation/request O->>G: pick SN, confirm code and short string - G->>M: ensure role machine- (literal ACLs device//...) - G->>M: add roles machine- + capability roles to client FN - G->>B: board//activation/response {SN, sig} + G->>M: ensure role machine-{SN} (literal ACLs device/{SN}/...) + G->>M: add roles machine-{SN} + capability roles to client FN + G->>B: board/{FN}/activation/response {SN, sig} B->>B: store SN, reconnect as FN - B->>M: use device//... topics + B->>M: use device/{SN}/... topics ``` - **Roles:** one assignment role per machine, `machine-`, with **literal** topics such as `device/SN000123/sales/report`. `%u` cannot express the SN here because the username is the FN. Plus shared capability roles (`vending`, `news`, `updates`). @@ -119,12 +119,12 @@ sequenceDiagram participant M as Mosquitto participant B as Board (FN) B->>B: new ephemeral X25519 keypair (b2, B2) - B->>G: board//activation/request {B2, n2} + B->>G: board/{FN}/activation/request {B2, n2} O->>G: pick SN, confirm code and short string - G->>G: ephemeral (s2, S2); shared = X25519(s2, B2) + G->>G: ephemeral (s2, S2), shared = X25519(s2, B2) G->>G: pw = HKDF(shared, SN, n2, generation) G->>M: create or update client SN: pw, clientId bound to board, role vending-device - G->>B: board//activation/response {SN, S2, sig} + G->>B: board/{FN}/activation/response {SN, S2, sig} B->>B: verify sig, derive same pw, store SN + pw B->>M: reconnect as SN / pw G->>M: disable FN client (or keep for rescue / re-enrollment) diff --git a/docs/sn-as-username-process.md b/docs/sn-as-username-process.md index 8e9de66..af3a08b 100644 --- a/docs/sn-as-username-process.md +++ b/docs/sn-as-username-process.md @@ -118,13 +118,13 @@ sequenceDiagram participant G as Go backend B->>B: random Client ID, X25519 pair (b, B), nonce n1 B->>M: CONNECT anonymous, clientId=random (TLS) - B->>M: SUBSCRIBE enroll/response/ (own topic only) - B->>G: enroll/request/ {B, n1, mac} - G->>G: reserve , assign FN, ephemeral (s, S) - G->>G: shared = X25519(s, B); pw = HKDF(shared, salt=n1, info=label|FN) + B->>M: SUBSCRIBE enroll/response/{cid} (own topic only) + B->>G: enroll/request/{cid} {B, n1, mac} + G->>G: reserve {cid}, assign FN, ephemeral (s, S) + G->>G: shared = X25519(s, B), pw = HKDF(shared, salt=n1, info=label|FN) G->>M: dynsec createClient FN, pw, clientid=FN, role board-bootstrap - G->>B: enroll/response/ {FN, S, sig} (not retained) - B->>B: verify sig; shared = X25519(b, S); same pw + G->>B: enroll/response/{cid} {FN, S, sig} (not retained) + B->>B: verify sig, shared = X25519(b, S), same pw B->>B: persist FN + pw to flash, then reconnect as FN ``` @@ -162,17 +162,17 @@ sequenceDiagram participant M as Mosquitto participant B as Board (FN session) B->>B: fresh X25519 pair (b2, B2), nonce n2, SAS = digits(hash(B2 || n2 || FN)) - B->>G: board//activation/request {B2, n2} + B->>G: board/{FN}/activation/request {B2, n2} G->>O: pending request FN, MAC label, SAS, time O->>G: choose SN, enter activation code, confirm SAS matches the board G->>G: DB: ACTIVATING (FN, SN, generation g+1), unique constraint - G->>G: ephemeral (s2, S2); shared2; pw_sn = HKDF(shared2, salt=n2, info=label|SN|g+1) + G->>G: ephemeral (s2, S2), shared2, pw_sn = HKDF(shared2, salt=n2, info=label|SN|g+1) G->>M: dynsec create or update client SN: pw_sn, role vending-device, clientid = FN - G->>B: board//activation/response {SN, g+1, S2, sig} + G->>B: board/{FN}/activation/response {SN, g+1, S2, sig} B->>B: verify sig, derive pw_sn, persist SN + pw_sn + generation, reconnect B->>M: CONNECT username=SN, clientId=FN, password=pw_sn - M-->>G: first message on device//... (or presence) - G->>G: DB: ACTIVE; disable the FN client; audit + M-->>G: first message on device/{SN}/... (or presence) + G->>G: DB: ACTIVE, disable the FN client, audit ``` ### 9.3 Rules that make it safe