identity
identity
¶
This device's cryptographic identity in the mesh.
Every installation holds one Ed25519 key pair, created on first use. The public half is what other devices are told about; the private half never leaves this machine and never appears in a log, a payload or an error.
Why a key pair rather than the opaque mac-<hex> Succès already had: an
identifier a device simply asserts can be asserted by anyone. Section 5 of
the mesh specification rules out IP, hostname, user agent, MAC address and
non-revocable tokens for exactly that reason. A key is different in kind —
the device proves it holds the private half, and revocation is meaningful
because the public half is what was recorded.
Storage follows the local API key's hardened pattern (0700 directory, 0600 file, atomic O_EXCL creation, O_NOFOLLOW read): the same threat — a swapped symlink or a world-readable secret — applies identically here.
Classes¶
DeviceIdentity
dataclass
¶
Functions:¶
owner_id
¶
The identity every device of this fleet shares.
Chosen shape (user decision): a locally minted identity propagated by pairing, not an account on a server. No password, no e-mail, nothing to breach remotely — and it still gives commands the "same owner" check spec §9 requires, because a device only ever learns it by being paired.
Created once, then read; never regenerated silently, since a changed owner id would orphan every device already paired.
Source code in src/diapason/mesh/identity.py
adopt_owner_id
¶
Join an existing fleet: take the owner id our host handed us.
Refuses to overwrite a different established identity — a device cannot silently change fleets, which is how paired devices would lose each other.
remplacer_si_solitaire — constaté le 25 août 2026 en branchant enfin
cette fonction : elle était écrite pour un appareil VIERGE, et il n'en
existe aucun. owner_id() frappe un identifiant dès le premier appel,
et le serveur l'appelle à chaque démarrage pour publier son identité :
tout Diapason ayant tourné une fois portait donc déjà une flotte à lui,
et refusait d'en rejoindre une. La fonction était juste, mais
inatteignable.
La distinction qui manquait n'est pas « a-t-il un identifiant » mais « cet identifiant est-il partagé avec quelqu'un ». Un identifiant frappé tout seul et connu de personne est un nom de naissance, pas une appartenance : le remplacer ne coûte rien. Un identifiant qu'au moins un pair de confiance connaît est une vraie flotte, et l'écraser les perdrait tous d'un coup — c'est le danger que ce docstring nommait depuis le début. L'appelant tranche, et il ne le fait qu'après avoir CONSTATÉ la solitude, jamais par confort.
Source code in src/diapason/mesh/identity.py
device_identity
¶
device_identity(*, name: str = '') -> DeviceIdentity
This device's identity, creating the key pair on first call.
Idempotent: subsequent calls read what the first one wrote. The private key is generated once and never regenerated silently — a device whose key changed would be, to every peer, a different device.
Source code in src/diapason/mesh/identity.py
public_identity
¶
canonical_bytes
¶
The exact bytes both sides sign.
Signing a dict means agreeing on its serialisation first: sorted keys, no incidental whitespace, UTF-8 preserved. Succès already canonicalises its operation payloads this way — same rule, one place.
Source code in src/diapason/mesh/identity.py
sign_envelope
¶
Sign payload with this device's private key. Returns base64.
Source code in src/diapason/mesh/identity.py
verify_envelope
¶
True when signature_b64 is this payload, signed by public_key.