daef7ea190
Helper functions (matrix-mas capability group): - mas_client_register_bash_infra: register/sync OAuth clients via mas-cli - mas_syn2mas_migration_bash_infra: dry-run + apply user migration to MAS - synapse_msc3861_enable_go_infra: edit homeserver.yaml MSC3861 block (with diff) - wellknown_oidc_patch_go_infra: patch well-known JSON with msc2965.authentication - synapse_login_flows_check_go_infra: health-check post-migration login flows Flows + issues for custom Matrix clients (PC + Android): - 0010 matrix-client-pc: Wails + React+Mantine (issues 0147-0153) - 0011 matrix-client-android: Kotlin + Compose (issues 0154-0161) - 0162 enable MAS as auth provider (Synapse delegate) — EXECUTED on VPS - 0163 custom admin panel propio (sustituye synapse-admin) Production state (organic-machine.com): - Synapse migrated SQLite -> Postgres - MSC3861 active, password_config disabled - 21 users + 41 access_tokens migrated via syn2mas - 4 MAS clients registered (element, matrix_pc, matrix_android, admin_panel) - synapse-admin container removed + Coolify route deleted - well-known patched with org.matrix.msc2965.authentication Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3.8 KiB
3.8 KiB
id, title, status, priority, created, related_flows, related_issues, dependencies, tags
| id | title | status | priority | created | related_flows | related_issues | dependencies | tags | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0150 | matrix-client-pc E2EE: cross-signing, SAS verification, recovery | pending | critical | 2026-05-24 |
|
|
|
|
Objetivo
Encriptacion end-to-end con mautrix-go (Olm/Megolm). Cross-signing keys (master/self-signing/user-signing), SAS verification de devices (emoji + decimal), recovery passphrase + key backup en Synapse, manejo de devices no verificados con warning visible. Mensajes en rooms encriptados se envian y descifran correctamente.
Tareas
- Backend Go:
MatrixService.BootstrapCrossSigning(passphrase)— genera master/self/user keys, sube a Synapse cifradas con passphrase-derived key.MatrixService.RecoverFromPassphrase(passphrase)— descarga keys de Synapse y descifra.MatrixService.StartVerification(userID, deviceID) -> *VerificationSession.MatrixService.VerifyEmoji(sessionID, accepted bool).MatrixService.ListDevices() -> []Device(con verified flag).MatrixService.BackupMegolmKeys()— key backup server-side.- Crypto store SQLite separado del state store (mejor para integridad).
- Frontend React:
- Wizard onboarding E2EE: pasos (1) generar passphrase, (2) backup, (3) verificar device.
- Panel
Settings > Security & Privacy:- Lista devices propios con verified state.
- Boton "Verify new device" + dialog SAS con emoji grid.
- "Reset cross-signing" (destructive, requiere confirmacion).
- "Restore from passphrase" (login en device nuevo).
EventBubblemuestra shield: green (verified), amber (encrypted, device unverified), red (decryption failed).- Banner room: "X devices are not verified" si algun miembro tiene devices unverified.
- Tests:
e2e/test_e2ee_send_receive.sh— msg enviado en room encriptado se descifra en Element Web.e2e/test_cross_signing.sh— bootstrap + verificar device desde Element Web.e2e/test_recovery.sh— login en device nuevo + recover keys con passphrase.e2e/test_unverified_warning.sh— device nuevo aparece como warning en otros clientes.
Funciones del registry a crear
matrix_e2ee_bootstrap_go_infra— wrapper cross-signing bootstrap.matrix_device_verify_go_infra— SAS verification flow.matrix_key_backup_go_infra— server-side key backup wrapper.passphrase_derive_key_go_infra— PBKDF2/scrypt para derivar key de passphrase.VerificationDialog_ts_ui— componente emoji grid SAS.
Acceptance
- Bootstrap cross-signing crea 3 keys + las sube a Synapse cifradas.
- Msg enviado a room encriptado se descifra en Element Web (y al reves).
- SAS verification con emoji grid funciona contra Element Web (ambos lados muestran 7 emojis iguales).
- Login en device nuevo + restore con passphrase recupera msgs historicos.
- Device no verificado dispara shield amber en EventBubble.
- Decryption failure (key no disponible) muestra shield rojo + boton "Request key".
Notas
Critico — anti-criterio:
- NO marcar done si E2EE silent-falla (msg muestra "** Unable to decrypt **" sin shield rojo claro).
- NO marcar done si recovery passphrase queda en plain text en disco (debe vivir solo en keyring/memoria).
Decisiones:
- Olm/Megolm via
mautrix-go/crypto(Go port estable de libolm). - Alternativa rust-crypto via CGo: descartada, mantiene complejidad build.
- Passphrase format: 4 palabras Diceware o 12-byte base32. Usuario elige al bootstrap.
Gotchas:
- Key rotation: rooms encriptados rotan megolm cada 1 semana o 100 msgs (default). Manejar refresh.
- Olm sessions max 100 mensajes: rotar prekey bundles automaticamente.
- Cuando arrancas device nuevo sin passphrase, los msgs pre-existentes NO se descifran — UI debe ser clara.