From 8792db942489e9e2ca6560902ef8b05ce5301039 Mon Sep 17 00:00:00 2001 From: damocles Date: Wed, 10 Jun 2026 19:03:16 +0200 Subject: [PATCH] feat(#551): gate server-side e2ee behind opt-in matrix.allowEncryption (default off) --- docs/matrix.md | 13 ++++++++++--- nix/modules/hive-matrix.nix | 23 ++++++++++++++++++++++- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/docs/matrix.md b/docs/matrix.md index b4f95f23..7e3dd972 100644 --- a/docs/matrix.md +++ b/docs/matrix.md @@ -119,9 +119,16 @@ Initial rollout settings: engage). The absent `yes_i_am_very_very_sure_…_open_registration_…` flag keeps the server closed to anyone without the token. -- `allow_encryption = true` — E2EE enabled. Agent clients use the - `e2e-encryption` feature of `matrix-sdk`; crypto keys are stored in - the per-agent sqlite store under the state dir and persist across +- `allow_encryption` — server-side E2EE switch, sourced from + `services.hyperhive.matrix.allowEncryption` (**default `false`**, opt-in). + Off by default because on the hive-internal homeserver the operator + already controls the transport; turn it on for encrypted rooms on + external / federated homeservers or to keep contents opaque to the + homeserver admin. **The agent matrix client always supports decryption + regardless of this flag** — it uses the `e2e-encryption` feature of + `matrix-sdk` so it can read encrypted rooms it is invited to even when + this homeserver doesn't permit room encryption. Crypto keys are stored + in the per-agent sqlite store under the state dir and persist across restarts (lost on `--purge`). `read_room` decrypts via `room.messages()` — UTD events surface as `event_type = "m.room.encrypted"` with `body = "[unable to decrypt]"`. diff --git a/nix/modules/hive-matrix.nix b/nix/modules/hive-matrix.nix index d147323b..ca287a7b 100644 --- a/nix/modules/hive-matrix.nix +++ b/nix/modules/hive-matrix.nix @@ -241,6 +241,25 @@ in ''; }; + allowEncryption = lib.mkOption { + type = lib.types.bool; + default = false; + description = '' + Server-side switch for matrix end-to-end encryption — sets + tuwunel's `allow_encryption`. Off by default: on the hive-internal + homeserver the operator already controls the transport, so server + E2EE adds key-management overhead (cross-signing, device + verification, undecryptable-message recovery) without a clear + threat-model win for the common single-hive case. Turn on when + agents join encrypted rooms on external / federated homeservers, + or when the operator wants message contents opaque to the + homeserver admin. Independent of the agent matrix client, which + always supports decryption so it can read encrypted rooms it is + invited to regardless of this flag; this option only governs + whether THIS homeserver permits room encryption. + ''; + }; + gui = { enable = lib.mkOption { type = lib.types.bool; @@ -403,7 +422,9 @@ in # LoadCredential below copies the host file into a # 0400 dynamic-user-owned path; tuwunel reads from there. registration_token_file = "/run/credentials/tuwunel.service/registration_token"; - allow_encryption = true; + # Server-side E2EE is opt-in (default off); the agent matrix + # client always supports decryption regardless. + allow_encryption = cfg.allowEncryption; # Tuwunel's default suffix is " 💕" — suppress it so agent # display names are clean (just the agent name, no emoji). new_user_displayname_suffix = "";