PMIS Federation Matrix
Odoo integrates with an existing Matrix Synapse service. Matrix may run on the same host or a remote host; this addon does not deploy, start, configure, or back up the server. Verified federation people and reviewed organization memberships control which identities and rooms Odoo manages.
Features
Company-owned Matrix configuration and restricted access tokens in Settings.
Direct verified HTTPS calls to existing Matrix client and Synapse admin APIs.
Permanent reviewed Matrix identities and optional Synapse OIDC account provisioning.
Organization-owned encrypted private rooms and invite-only Spaces.
Independently approved room and Space memberships with scoped withdrawal.
Durable Odoo jobs and remote membership ownership/revision evidence for retries.
Element navigation and recovery reminders without collecting recovery keys.
Complete Element Web client embedded in Odoo, including its encrypted chat and calling UI.
Reviewed encrypted text relay between Matrix rooms and private Discuss groups.
Exact device fingerprint verification, protected device keys, and durable ciphertext replay evidence.
Separately installed Element Web frontend with distribution-managed assets and updates.
Browser media delegation to explicitly configured Element and Element Call origins.
US English source strings and Slovenian translations.
Configuration
The external frontend dependency is Element Web. On Arch Linux, use the official extra/element-web binary package and serve its installed web root through HTTPS. The package owns its JavaScript, WebAssembly, and updates; this addon contains no copied client assets, npm dependencies, or frontend build tools. See Element Web setup and updates.
Python dependencies
Install the repository's requirements.txt alongside Odoo 18's requirements in the Python environment used by Odoo. This module requires matrix-nio[e2e]>=0.26.0. The encryption extra supplies vodozemac>=0.9.0.post2, peewee~=3.14, atomicwrites~=1.4, and cachetools>=5.3. These packages are also declared explicitly in the manifest because Odoo checks package versions but does not validate the dependencies of an extra.
Matrix-nio 0.26 uses the Rust-based vodozemac encryption bindings. It does not require the libolm or python-olm packages used by older matrix-nio versions. See the matrix-nio 0.26 dependency definitions.
For example, on an Arch Linux host using the PMISuite18 Odoo virtual environment, run the following as the environment's owner before installing the addon:
/srv/pmiverse/_pmisuite18/venv/bin/python -m pip install \
-r /srv/pmiverse/_pmisuite18/repos/pmiverse/federation/requirements.txt
Adjust the paths for another installation. Arch system Python packages are not automatically visible inside an isolated Odoo virtual environment. Element Web remains a separate Arch extra/element-web package served through HTTPS. After installing the dependencies, configure and review a dedicated bridge device as described below. Personal Element sessions remain independent of the relay.
Company and client settings
For native Arch Linux deployment in an existing Odoo LXC behind a separate Nginx reverse proxy, see the step-by-step deployment guide. It covers the existing PostgreSQL cluster, Synapse, Element Web, HTTPS routing, and the conferencing backend.
Create a Matrix target under Federation > Matrix. Supply its actual Matrix server name, homeserver HTTPS origin, client HTTPS origin, and reviewed instance. No server addresses or deployment locations are supplied by default.
Select the target's Directory Owner company and open Settings > Matrix.
Enable the integration and select that company's target. Enter the full Matrix integration user ID and its client access token. Use a dedicated integration identity rather than an ordinary person's session.
Supply a separate Synapse administrator token and the exact existing Synapse OIDC provider ID only when account provisioning is needed. These do not grant Odoo access to host administration. Odoo does not configure Synapse's OIDC.
Save the settings and choose Test Saved Connection. The token owner must match the configured integration user. Room and membership operations use the client token; Synapse account administration uses the administrator token.
For the in-Odoo client, configure Element Web on a separate HTTPS origin. Set Element Call Origin on the target if its calling widget uses a different origin. The browser delegates microphone, camera, screen sharing, fullscreen, and autoplay only to these configured origins. This field does not deploy or configure a calling service.
The Element deployment must permit embedding by the exact Odoo origin through its Content-Security-Policy: frame-ancestors response header. A conflicting X-Frame-Options: DENY or SAMEORIGIN header prevents cross-origin embedding. Keep an explicit embedding allowlist. Odoo's deployment must also permit these frames and media features in its own content-security and permissions policies. Element, its nested calling widget, the browser, and the enclosing Odoo page must all allow the relevant media permissions. Use HTTPS for Odoo as well as Matrix. See Element Web deployment guidance.
Configure MatrixRTC transport discovery, the authorization service, and the SFU for the existing Element deployment. Conferencing requires a working transport; Synapse account/room administration does not supply it. See Element Call hosting. Browser storage and authentication policies may require signing in through Open Element first; the embedded view provides this option.
Credentials belong to the selected company and are accessible only to Odoo administrators. They are stored in the Odoo database, not encrypted by this addon; protect database access and Odoo backups accordingly. Tokens are not placed in integration jobs, browser navigation URLs, status messages, or HTTP error reports.
TLS certificate verification is mandatory. Redirects are not followed. DNS results are pinned for each request. Private or loopback destinations require explicit, comma-separated approved IP addresses; optionally use the same field to pin a public destination. Link-local, multicast, and unspecified destinations are refused.
Credentials are bound to the original Odoo database UUID. After a database copy, restore, or deliberate credential rotation, an administrator must explicitly configure the company connection again before jobs can execute.
Usage
Encrypted Discuss bridge
Provision the reviewed encrypted room and its Matrix memberships. On each peer, identify the same verified Matrix target and room resource UUIDs and shared room; preserve each database's own directory and operating-company mappings.
Under Federation > Matrix > Reviewed Discuss Bridges, create the exact peer connection, room, counterpart bridge UUID, and verification reference. Enable Approve Readable Discuss History only after reviewing this plaintext boundary.
Create a dedicated non-admin Matrix service account for this bridge. Obtain a client token for a fresh device through the homeserver's supported login workflow. Enter Bridge Matrix User, Bridge Device ID, and Bridge Device Access Token. The token must identify this exact user and device through Matrix's whoami API. Do not reuse a personal Element device: the relay generates its own encryption keys.
Set Peer Bridge Matrix User when importing attributed text from the counterpart relay. Independently verify both public device fingerprints for every approved participant device and counterpart relay device. Enter them in Verified Device Fingerprints as a JSON list, using the format below. New and changed devices are denied until their exact fingerprints have been reviewed.
Choose Approve Bridge, then run its management job. The company integration account records privileged Matrix room ownership, invites the dedicated account, and the relay joins with its own device token. Initial synchronization establishes a baseline; it does not import existing Matrix history.
Approve Reviewed Matrix Participants separately against their current source memberships and applied room memberships. Discuss comments queue text-only jobs up to 4096 UTF-8 bytes. Incoming verified encrypted text is imported into this exact Discuss group once. Attachments and plaintext Matrix events are excluded.
The fingerprint JSON format is:
[
{
"user_id": "@pmis_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:example.com",
"device_id": "ALICE_DEVICE",
"ed25519": "VERIFIED_ED25519_PUBLIC_KEY",
"curve25519": "VERIFIED_CURVE25519_PUBLIC_KEY"
}
]
Replace these synthetic values with independently verified public keys. Fingerprints can be inspected through Matrix device-key discovery; identity names alone do not verify a device. Participants must also verify the bridge device in their own Matrix clients so those clients can share encrypted room keys with it. The relay does not automatically trust new devices or forward room keys on request. Each new bridge approval establishes a new baseline. Historical Megolm indices are rejected even if replayed under a new event ID or timestamp. Existing sessions without an observed baseline are excluded; their senders must rotate to a fresh room-key session rather than sharing old history with the bridge.
Outgoing Matrix messages appear from the dedicated bridge account, with the original reviewed Matrix sender ID in the body and encrypted attribution metadata. A peer relay accepts this attribution only from its configured verified counterpart device, for the exact reversed instance pair and counterpart bridge UUID. It does not create an Odoo user or grant company membership from Matrix authentication.
Incoming ciphertext and its sync cursor are journaled together. Discuss receipts commit before native inbox acknowledgment. Outbound retries reuse immutable ciphertext and the same Matrix transaction ID, and later jobs wait for earlier unsettled text on the same bridge. Missing room keys hold subsequent messages in order; Relay State becomes Unavailable until synchronization can proceed. Last Sync At shows the latest successful synchronization. Timeline gaps are recovered through bounded pagination; unresolved gaps stop delivery instead of silently skipping text.
Choose Withdraw Bridge to stop local relay authorization immediately and queue removal of its dedicated Matrix account from this room. Withdraw Participant ends only that participant's Discuss and relay scope. Queued text whose original recipient or consent scope changed is superseded, and newly encrypted text uses a fresh room-key session. Independently approved Matrix memberships and accounts remain intact. Withdrawal cannot erase text or keys already received by an authorized party.
Withdraw the bridge before rotating its token or changing verified fingerprints, then explicitly approve the new scope and participants. The bridge's user and device identities are permanent. To replace a device after unrecoverable key loss, retire the old bridge and review a new dedicated device and room instead of resetting keys under the old identity.
Key custody and recovery
Device keys, a random pickle-encryption key, encrypted inbox/outbox journals, sync cursors, and replay tombstones live under <Odoo data_dir>/matrix_crypto/<database UUID>/<bridge UUID>. The bridge directory is owner-private; keys are not stored in Odoo records or exposed to the browser. Device access tokens are stored in administrator-only bridge fields in the Odoo database; protect database access and backups as well as the device directory. All Odoo workers executing relay jobs must access the same persistent store with working SQLite locking and durability. Matrix may run on a separate remote host.
Protect and back up the complete device directory together with the Odoo database. Restore them consistently before enabling delivery. Losing part of this store blocks the relay; it never silently generates replacement keys for an established device. Credentials and the journal are bound to the original database, target, room, user, and device. A copied database needs explicit configuration and a separately reviewed device; these bindings do not isolate credentials or key files copied by a host administrator. Preserve replay evidence through restore and reinstallation.
Matrix rooms and Element
Provision a reviewed person identity if account administration is configured. Create an organization-owned room with its verified operating-company mapping, then choose Provision. For a Space, choose Organization Space and provision it before selecting it as a child room's parent. Approve Space and child-room memberships separately; Space membership grants no child-room access.
Choose Approve or Revoke on the exact reviewed room membership. The integration records ownership in privileged Matrix room state before an invitation. Interrupted replies can be retried without adopting unrelated existing participation. Revocation withdraws only participation owned by that Odoo decision. It never disables the independent Matrix account or removes other relationships.
Inspect immutable jobs and use Run / Retry when needed. Health checks verify the integration token's identity and the existing service's client API. Ordinary users can open My Matrix Identity and My Matrix Rooms through their current verified native account mappings and approved room access.
Choose Matrix Client in the Odoo app menu, or Open in Odoo on your identity or an approved membership. One current identity opens immediately; multiple identities require explicit selection. Sign in to Element as the displayed Matrix identity. Matrix authentication is independent of Odoo authentication: Odoo does not exchange a company integration token for a personal session or inspect the cross-origin client's signed-in account. Matrix's own authentication and room membership control access inside Element.
Element's complete interface handles encrypted conversations, invitations, history, attachments, device verification, recovery, and supported voice/video and conference calls within the Odoo page. The actual supported calling features depend on the Element version and configured MatrixRTC deployment. This interface does not copy decrypted messages into Discuss.
Room membership controls calling access. Use Element's call and moderation controls inside the approved room; no separate Odoo call approval or invitation lease is required. On a reviewed Discuss bridge, Open in Odoo opens its exact room through the current personal identity and room membership checks. Withdrawing a Discuss participant leaves independently approved Matrix room access intact. Revoke that room membership separately when its access must also end. Room withdrawal does not guarantee immediate disconnection of an already connected SFU participant.
Odoo rechecks current identity/company authorization every 30 seconds and on window focus. Failed checks unload the client frame; configuration changes require reopening it. Pause Client unloads the frame and Resume / Retry reauthorizes before reconnecting. Navigating away unloads the frame and its active media UI. Browser background throttling can delay periodic checks; remote membership and admission revocation remain owned by the Matrix deployment. Unloading does not sign out of the independent Matrix account or revoke a running participant at the SFU. Use Element's sign-out and call controls for those actions.
On first navigation, the recovery reminder asks the user to save their recovery key elsewhere and confirm exactly I saved my recovery key. Only acknowledgment, identity, user, time, and policy version are retained. The entered phrase is transient; no recovery key is collected. Choose Renew Recovery Reminder after changing devices or recovery material. Element owns sessions and encrypted history.
Integration boundary
There is no PMIVerse Matrix daemon, Unix socket, systemd unit, local Synapse API, or Matrix host filesystem dependency. The relay's private device journal belongs to the Odoo runtime and is separate from Matrix server administration.
The direct connector supports health, accounts, rooms, Spaces, and managed membership. The nio device client implements reviewed encrypted Discuss text relay over the same pinned HTTPS transport. It has no plaintext fallback. The embedded Element client supplies personal encrypted messaging and the deployment's calling interface. Odoo does not implement a MatrixRTC admission/focus service; calls use the Matrix deployment's admission and moderation policy, without separate Odoo call leases.
See the integration contract for authorization, ownership, supported APIs, and recovery boundaries.


