diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-30 21:04:39 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-30 21:04:39 +0200 |
| commit | 0378e8e0912a1a7e6cea4424e69d524e7afecbf8 (patch) | |
| tree | 4ae94e32d6638b4c2cc1ae4f74cbe5d00c940636 /packages/meshbay-common/src/meshbay_common/device.py | |
| parent | 0ed56d3a1b4f71cf622d3e27edc87a15ef33c185 (diff) | |
| download | meshbay-0378e8e0912a1a7e6cea4424e69d524e7afecbf8.tar.gz | |
fix: an identity signs a named kind, and a device approval answers a request
The desktop main process builds every transcript itself from fields
(transcripts.js) and signs no raw bytes; the page's identity has the same
contract (crypto.js transcriptFor). The keyring seals no bundle while browser
access is off. On the node, device_add must redeem a pending request filed by
the same keys, and device_revoke is signed under its own prefix
(meshbay:device_revoke:v1), so a retirement signature admits nothing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-common/src/meshbay_common/device.py')
| -rw-r--r-- | packages/meshbay-common/src/meshbay_common/device.py | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/packages/meshbay-common/src/meshbay_common/device.py b/packages/meshbay-common/src/meshbay_common/device.py index 3a598d0..2d6747f 100644 --- a/packages/meshbay-common/src/meshbay_common/device.py +++ b/packages/meshbay-common/src/meshbay_common/device.py @@ -37,6 +37,7 @@ import hashlib DEVICE_REQUEST_PREFIX = b"meshbay:device_req:v1" DEVICE_ADD_PREFIX = b"meshbay:device_add:v1" DEVICE_HELLO_PREFIX = b"meshbay:device_hello:v1" +DEVICE_REVOKE_PREFIX = b"meshbay:device_revoke:v1" # Same as the join and admin transcripts: interactive exchanges that complete in # milliseconds, so anything older is a replay. @@ -126,6 +127,30 @@ def device_add_transcript( ]) +def device_revoke_transcript( + node_pk_b64: str, + user_id: str, + pk_ed25519_b64: str, + nonce_node: bytes, + ts: int, +) -> bytes: + """ + Signed by a pinned device, retiring one of the account's devices. + + A prefix of its own, never the admission transcript: a signature given to + retire a key would otherwise admit that same key on a node where it is not + pinned yet, and whoever asks a device to sign a retirement could turn it + into an addition. + """ + return _pack(DEVICE_REVOKE_PREFIX, [ + node_pk_b64.encode(), + user_id.encode(), + pk_ed25519_b64.encode(), + nonce_node, + str(ts).encode(), + ]) + + def device_hello_transcript( node_pk_b64: str, group_id: str, |