docs: rename integration name from matrix_e2ee to matrix_e2e

- Rename runbook: matrix-e2ee-update.md -> matrix-e2e-update.md
- Update all references in AGENTS.md, hass.windy.lan.md,
  home-assistant-matrix.md to use the short name matrix_e2e
- The code domain stays matrix_e2ee (E2EE) in source; all
  doc prose and command references now use matrix_e2e
This commit is contained in:
windyboy
2026-08-18 13:31:15 +08:00
parent 343c5db415
commit 7cedba7f51
4 changed files with 303 additions and 0 deletions
+134
View File
@@ -4,6 +4,13 @@ Reference for wiring the Home Assistant [Matrix integration](https://www.home-as
to the self-hosted Matrix homeserver at [`synapse.chans.xyz`](../hosts/synapse.chans.xyz.md).
Deliberately contains no Matrix passwords, access tokens, or room encryption material.
> **Status (2026-08-15, W1N-139):** the built-in `matrix` integration has been
> **retired** on `hass.windy.lan` and replaced by the custom \*\*\`matrix_e2e\`\*\*
> integration. The sections below on the built-in integration are kept for
> reference only. See [matrix_e2e](#matrix-e2e-custom-e2e-integration) for the
> active setup and [Device verification (SAS) model](#device-verification-sas-model)
> for how device trust works.
## Purpose
The integration lets Home Assistant send messages to Matrix rooms and react to
@@ -169,6 +176,133 @@ automation:
message: "It looks like you wrote !testword"
```
## matrix_e2e (custom E2E integration)
Custom integration [`windyboy/ha-matrix-e2e`](https://github.com/windyboy/ha-matrix-e2e),
release **v0.2.6** (W1N-173/W1N-174), deployed on `hass.windy.lan`
2026-08-16 (upgraded from v0.2.4; v0.2.0 was the first Config Flow release, W1N-154).
Runs a dedicated bot with a **persistent E2EE device identity**.
- Domain `matrix_e2e`; Config Flow (UI) with YAML import migration, not in HACS. Does **not**
override the built-in `matrix` integration.
- Dependencies are declared **explicitly** in `manifest.json` to work around Home
Assistant's `is_installed` dropping the `[e2e]` extra (W1N-140):
`matrix-nio[e2e]==0.26.0` + `vodozemac` + `peewee` + `cachetools` + `atomicwrites`.
- **v0.2.0 migration:** YAML `matrix_e2e:` block was auto-imported into a Config Entry
(`source: import`) on first startup, then removed. All settings now managed via
**Settings → Devices & Services → Matrix E2EE → Configure**.
See [hosts/hass.windy.lan.md](../hosts/hass.windy.lan.md) for the deployed state.
### Services & events
- Services (all admin-only since v0.1.4):
- `send_message` (`message`, `room_id`)
- `start_verification` (`user_id`, `device_id`)
- `confirm_verification` (`transaction_id`)
- `cancel_verification` (`transaction_id`)
- `reauthenticate` (`password`) — soft-logout only
- `get_fingerprint` (no fields; returns bot's own `ed25519`/`curve25519` keys; added v0.1.3)
- `verify_device_by_fingerprint` (`user_id`, `device_id`, `ed25519`; added v0.1.3,
renamed from `verify_device` in v0.1.4; requires exact `ed25519` match)
- Events:
- `matrix_e2e_command` (`room_id`, `sender`, `command`, `args` only —
never the raw body)
- `matrix_e2e_error` (codes, no secrets)
- `matrix_e2e_verification` (`stage`, `transaction_id`, `user_id`, `device_id`,
optional `emojis`, optional `expires_at`; `expires_at` added v0.1.3)
- `matrix_e2e_fingerprint` (`user_id`, `device_id`, `ed25519`, `curve25519`
public keys only; added v0.1.3)
- `notify.matrix_e2e` is **not implemented** (upstream deferred) — notifications
must call `matrix_e2e.send_message` (message + room_id).
- Commands fire Home Assistant events only; the integration never calls
`domain.service` itself. Map commands in automations.
- Encrypted rooms fail-closed on unverified devices.
- Since v0.1.4: `start_verification`, `confirm_verification`, `cancel_verification`,
`verify_device_by_fingerprint`, and `reauthenticate` are enforced as HA admin-only
via `async_register_admin_service`; non-admin users cannot call them.
### Storage & recovery
- `.storage/matrix_e2e_session.json` (`user_id`, `device_id`, `access_token`,
`pickle_key`) and `.storage/matrix_e2e_store/` (Olm/Megolm, device trust,
sync token). Both stay on the HA persistent volume and are in HA backups.
- Soft logout → `matrix_e2e.reauthenticate` (keeps `device_id` + crypto store;
rejected outside soft-logout state since v0.1.3).
- Hard logout / store loss → delete session + store, restart with password, re-SAS
(a **new device**; old history not decryptable).
## Device verification (SAS + fingerprint) model
Researched 2026-08-15 (W1N-139 stage-6 pre-study), updated for v0.1.3/v0.1.4.
Sources: matrix.org
[cross-signing guide](https://matrix.org/docs/guides/implementing-more-advanced-e-2-ee-features-such-as-cross-signing/),
matrix-nio [examples](https://matrix-nio.readthedocs.io/en/latest/examples.html),
[element-android#6832](https://github.com/vector-im/element-android/issues/6832),
Element [device-verification](https://element.io/features/device-verification).
`matrix_e2e` supports two verification paths:
### 1. SAS (mutual, manual confirmation since v0.1.4)
- SAS is device-to-device: exchange ephemeral keys → derive emojis → **a human on
each side compares and confirms** (`m.key.verification.mac`).
- Matrix distinguishes two cases (spec uses *should*, not *must*):
- **same user, two devices** → to-device messages (SAS);
- **two different users** → **in-room (DM) messages**, verifying the *user*
(cross-signing master key), not a specific device.
- Cross-signing: each user has master / self-signing / user-signing keys. A device
looks "verified" to another user via the chain
`my master → my user-signing → their master → their self-signing → their device`.
- Element's "Verify" button only starts **in-DM user verification**; it has no
"verify a specific device of another user via to-device" flow (matrix.org
recommends hiding per-device verification for other users).
- `matrix_e2e` implements **raw to-device device SAS** (`start_verification`/
`confirm_verification`), **no cross-signing / in-room**. This is a non-standard
cross-user path: works with matrix-nio + Element Web/Desktop (reported in
element-android#6832), **not** on Element Android/X.
- **v0.1.3**: inbound SAS auto-complete was added; SAS events include `expires_at`.
- **v0.1.4 (breaking)**: auto-confirm was removed. **Every** device — including
another device of the bot's own account — requires explicit `confirm_verification`
after emoji comparison. Only the bot's own account or users in `allowed_users`
may initiate SAS (`verification_peer_denied` otherwise).
- **v0.2.1**: storage I/O moved off the event loop (`asyncio.to_thread`,
W1N-167); own-keys query on startup so inbound SAS can build a session (W1N-166).
- **v0.2.2** (not deployed): intermediate version.
- **v0.2.3**: sync loop runs as a background task (fixes bootstrap setup timeout,
W1N-168); SAS double-send of key and MAC fixed (W1N-169).
- **v0.2.6**: `_log_verification_state()` tracks SAS state transitions with
`async_write_ha_state` for diagnosis (W1N-174);
`_bridge_verification_request()` handles inbound
`m.key.verification.request``m.key.verification.ready` since nio lacks a
`request` framework (W1N-173).
- **v0.2.5**: bridge `m.key.verification.request``ready` (nio lacks
request framework, W1N-173).
- **v0.2.4**: `_patch_nio_sas_timeout()` works around nio 0.26.0
`_last_event_time` bug (SAS timed out at 60s regardless of activity — now uses
`_max_age` 5 min); `_repair_dropped_start()` recovers SAS `start` events nio
dropped when the peer device was unknown (W1N-170/W1N-172);
`VERIFICATION_TIMEOUT_SECONDS` 600→240 (fires before nio's `_max_age`).
- Inbound SAS is gated to `allowed_users` (v0.1.3).
### 2. One-sided fingerprint (added v0.1.3, hardened v0.1.4)
- Call `matrix_e2e.get_fingerprint` to get the bot's own `ed25519` device key
(read it from the `matrix_e2e_fingerprint` event).
- In Element, open the bot user's sessions and use "Manually verify by text".
Compare the session key with the fingerprint.
- To trust another device from the bot's side, call
`matrix_e2e.verify_device_by_fingerprint` with the peer's `user_id`, `device_id`,
and `ed25519` key. The match is exact (since v0.1.4's rename from `verify_device`).
Feed the **peer** key, not the bot's own key.
- This trusts from one side only; the peer still trusts the bot independently.
- Both `get_fingerprint` and `verify_device_by_fingerprint` are HA admin-only.
### Consequence
Whether `@zhiqiang`'s device can be verified depends on which Element client
they use. Open options recorded in W1N-139 (A: Web SAS test; B: upstream
in-room/cross-signing; C: unencrypted-room downgrade).
## References
- Home Assistant Matrix integration: <https://www.home-assistant.io/integrations/matrix>