Skip to content

fix(matrix): multi-account identity routing, voice message support, and security hardening#33350

Closed
efe-arv wants to merge 7 commits into
openclaw:mainfrom
efe-arv:fix/matrix-multi-account
Closed

fix(matrix): multi-account identity routing, voice message support, and security hardening#33350
efe-arv wants to merge 7 commits into
openclaw:mainfrom
efe-arv:fix/matrix-multi-account

Conversation

@efe-arv

@efe-arv efe-arv commented Mar 3, 2026

Copy link
Copy Markdown
Contributor

fix(matrix): multi-account identity routing, voice message support, and security hardening

Context

Matrix is the only open-protocol, self-hostable channel in OpenClaw. For deployments operating on local infrastructure — home labs, air-gapped networks, VPN meshes, or multi-agent architectures where each agent requires a distinct identity — Matrix with a self-hosted homeserver is the canonical choice. No vendor lock-in, no cloud dependency, no recurring API costs.

OpenClaw's Matrix plugin supports multi-account configuration via channels.matrix.accounts, enabling multiple bot identities on a single homeserver. However, during comprehensive testing of a production multi-account deployment, we identified that several code paths fail to propagate per-account context correctly. Additionally, voice message support (MSC3245) is fully implemented in the send layer but unreachable from every upstream caller. This PR resolves those routing deficiencies and introduces security hardening measures identified through a systematic audit of the Matrix plugin source.

Changes

Bug Fixes

1. Add missing keyed-async-queue build entry to tsdown.config.ts

package.json declares the subpath export ./plugin-sdk/keyed-async-queue mapping to dist/plugin-sdk/keyed-async-queue.js, and extensions/matrix/src/matrix/send-queue.ts imports from this path at runtime. However, tsdown.config.ts contains no corresponding entry for src/plugin-sdk/keyed-async-queue.ts, so the build pipeline never emits the output artifact. This produces a deterministic runtime import failure when the Matrix plugin initializes its send queue.

The fix adds an entry block following the identical pattern established by the existing account-id.ts entry. The source file and its vitest test alias both already exist upstream.

Files: tsdown.config.ts

2. Resolve agentId for buildMentionRegexes in Matrix monitor initialization

In extensions/matrix/src/matrix/monitor/index.ts, the monitor startup invokes buildMentionRegexes(cfg) without supplying an agentId argument. Consequently, per-agent mentionPatterns — configured via agents.list[].groupChat.mentionPatterns — are never resolved: the function cannot determine which agent's pattern set to compile into the regex cache.

The Discord monitor handler correctly resolves the bound agent ID from channel bindings before constructing mention regexes. The Matrix monitor omits this resolution step entirely.

The fix resolves boundAgentId by performing a binding lookup against the current account's monitored rooms, then passes the result to buildMentionRegexes(cfg, boundAgentId). This enables plain-text mention detection (e.g., @agent-name) in shared multi-agent rooms configured with requireMention: true.

Files: extensions/matrix/src/matrix/monitor/index.ts

3. Propagate accountId through the complete tool action dispatch chain

When an agent invokes the message tool to perform channel actions (react, edit, delete, send, pin, read, etc.), the execution path traverses actions.tshandleMatrixAction() in tool-actions.ts → individual action functions. The ChannelMessageActionContext provided by the core runtime includes accountId, but actions.ts never destructures this field and handleMatrixAction never accepts it as a parameter.

The consequence: all tool-initiated actions resolve to resolveActionClient() with undefined accountId, which deterministically selects the primary (default) account. In a multi-account deployment, this means every agent's tool actions — reactions, edits, deletions, message sends — execute under the default bot identity regardless of the originating agent.

The fix comprises three coordinated changes:

  • actions.ts: Destructures accountId from the action context and forwards it to all nine handleMatrixAction invocations
  • tool-actions.ts: Accepts accountId as an optional third parameter and propagates it to every downstream action function
  • matrix/send.ts: Extends reactMatrixMessage to accept an options object containing { client?, accountId? } alongside the existing MatrixClient parameter. Backward compatibility is preserved via runtime type detection ("doRequest" in clientOrOpts)

Note: Typing indicators, read receipts, and outbound reply delivery are unaffected by this deficiency — the monitor handler passes the per-account client instance directly for those operations, bypassing the action dispatch chain entirely.

Files: extensions/matrix/src/actions.ts, extensions/matrix/src/tool-actions.ts, extensions/matrix/src/matrix/send.ts

4. Forward audioAsVoice and accountId through the sendMatrixMessage wrapper

The Matrix plugin implements full MSC3245 voice message support in its send layer: sendMessageMatrix() in matrix/send.ts accepts audioAsVoice, resolves voice compatibility via resolveMatrixVoiceDecision(), and emits the required org.matrix.msc3245.voice and org.matrix.msc1767.audio event content fields. However, this capability is unreachable from any upstream caller due to three independent gaps in the call chain:

  1. actions/messages.ts — The sendMatrixMessage convenience wrapper explicitly enumerates which options to forward to sendMessageMatrix. The allowlist includes mediaUrl, replyToId, threadId, client, and timeoutMs — but omits both audioAsVoice and accountId. Any caller passing these fields has them silently discarded.

  2. actions.ts — The send action handler reads the media parameter but does not check the alternative parameter names (mediaUrl, filePath, path) that agents may use depending on their tool call conventions. It also does not read asVoice or audioAsVoice from the incoming params.

  3. tool-actions.ts — The sendMessage case does not read or forward audioAsVoice from the action params object.

The fix addresses all three layers:

  • actions/messages.ts: Extends the opts type to include audioAsVoice?: boolean and accountId?: string, and forwards both to sendMessageMatrix
  • actions.ts: Reads asVoice/audioAsVoice from params, resolves media from mediamediaUrlfilePathpath (matching the convention used by Telegram and Discord handlers), and passes audioAsVoice to handleMatrixAction
  • tool-actions.ts: Reads audioAsVoice from the action params and forwards it to sendMatrixMessage

Verified end-to-end: voice messages sent via the message tool now arrive with correct MSC3245 metadata across OGG/Opus and MP3 formats.

Files: extensions/matrix/src/matrix/actions/messages.ts, extensions/matrix/src/actions.ts, extensions/matrix/src/tool-actions.ts

Security Hardening

5. Apply SSRF-guarded fetch to directory API calls

directory-live.ts issues HTTP requests to the configured homeserver URL using the unguarded fetch() API. The authentication flow in client/config.ts correctly employs fetchWithSsrFGuard from the plugin SDK, but the directory search and room listing endpoints do not.

If an attacker can influence the homeserver configuration value — or if a misconfigured deployment points at an internal service URL (e.g., a cloud instance metadata endpoint) — the bot will transmit authenticated HTTP requests bearing the Matrix access token to that endpoint.

The fix replaces fetch() with fetchWithSsrFGuard in fetchMatrixJson(), consistent with the pattern established in the login flow, specifying auditContext: "matrix.directory" for traceability.

Files: extensions/matrix/src/directory-live.ts

6. Restrict file permissions on credentials and storage metadata

credentials.ts and client/storage.ts persist sensitive files (credentials.json, storage-meta.json) using fs.writeFileSync without specifying an explicit file mode. This inherits the process umask (typically 0o022), yielding 0o644 permissions — world-readable on standard Linux configurations.

These files contain homeserver URLs, user IDs, and access token hashes. While not full-entropy tokens, they reveal which credentials are active and can facilitate targeted credential-stuffing or session hijacking attacks when combined with other information disclosure vectors.

The fix enforces restrictive permissions:

  • fs.mkdirSync calls specify mode: 0o700 (owner-only directory traversal)
  • fs.writeFileSync calls specify mode: 0o600 (owner-only read/write)
  • Applied to saveMatrixCredentials, touchMatrixCredentials in credentials.ts
  • Applied to writeStorageMeta and the legacy migration path in storage.ts

Files: extensions/matrix/src/matrix/credentials.ts, extensions/matrix/src/matrix/client/storage.ts

7. Change default autoJoin policy from "always" to "allowlist"

In auto-join.ts, the fallback behavior when autoJoin is omitted from the configuration defaults to "always", which registers the SDK's AutojoinRoomsMixin — causing the bot to unconditionally accept every room invitation.

For isolated local deployments where the homeserver exists on a trusted network segment, this may be acceptable. However, for any deployment where the bot's Matrix user ID is discoverable (federated homeservers, public directories, leaked room invitations), an adversary can create a room, invite the bot, and — if groupPolicy is also at its default value of "open" — interact directly with the agent.

The fix changes the default to "allowlist". Existing deployments that explicitly configure autoJoin: "always" are entirely unaffected — the new default only governs installations where the field is absent from the configuration.

Files: extensions/matrix/src/matrix/monitor/auto-join.ts

8. Sanitize login error responses in exception messages

In client/config.ts, when a Matrix login request returns a non-success HTTP status, the raw response body is interpolated directly into the thrown Error:

const errorText = await loginResponse.text();
throw new Error(`Matrix login failed: ${errorText}`);

Depending on the homeserver implementation (Synapse, Conduit, Dendrite), this response body may contain internal diagnostic messages, partial stack traces, rate-limit metadata, or session identifiers. These error messages propagate through the exception chain and are typically persisted in application logs.

The fix replaces the raw error body with a deterministic status-based message: "invalid credentials" for HTTP 403, "rate limited" for HTTP 429, or "HTTP {statusCode}" for all other failure modes.

Files: extensions/matrix/src/matrix/client/config.ts

9. Add TTL and size bounds to the room info cache

room-info.ts employs an unbounded Map as an in-memory cache for room name and alias lookups. Entries are inserted but never evicted. On long-running gateway processes with exposure to many rooms (multi-account deployments, rooms with frequent renames, or federated environments), this cache exhibits two pathological behaviors:

  1. Unbounded memory growth — The cache grows monotonically with the number of unique room IDs encountered over the process lifetime.
  2. Stale data persistence — Room renames, alias changes, and permission updates are never reflected until the gateway process is restarted.

The fix introduces:

  • A 5-minute TTL (ROOM_INFO_CACHE_TTL_MS = 300_000) with staleness checks on read
  • A maximum cache capacity of 500 entries with FIFO eviction on write
  • A CachedRoomInfo type wrapping entries with a cachedAt timestamp

Files: extensions/matrix/src/matrix/monitor/room-info.ts

Summary of Changed Files

# File Fix
1 tsdown.config.ts Build entry for keyed-async-queue
2 extensions/matrix/src/matrix/monitor/index.ts agentId → buildMentionRegexes
3a extensions/matrix/src/actions.ts accountId + audioAsVoice + media fallbacks
3b extensions/matrix/src/tool-actions.ts accountId + audioAsVoice propagation
3c extensions/matrix/src/matrix/send.ts reactMatrixMessage backward-compat opts
4 extensions/matrix/src/matrix/actions/messages.ts Forward audioAsVoice + accountId
5 extensions/matrix/src/directory-live.ts SSRF guard on fetch
6a extensions/matrix/src/matrix/credentials.ts File permission hardening
6b extensions/matrix/src/matrix/client/storage.ts File permission hardening
7 extensions/matrix/src/matrix/monitor/auto-join.ts Default "allowlist"
8 extensions/matrix/src/matrix/client/config.ts Sanitized login errors
9 extensions/matrix/src/matrix/monitor/room-info.ts Cache TTL + size bounds

Related Issues

Testing

All fixes were verified on a live multi-account deployment with a self-hosted homeserver, multiple bot identities, and shared rooms using mention-based routing.

Fix Verification
1 CI passed on prior PR #32901 (build-artifacts, install-smoke). Closed in favor of this combined PR.
2 Five agents in a shared room with requireMention: true — plain-text @agent-name mentions correctly routed to the addressed agent only. Verified with autonomous multi-agent conversation chain.
3 Agent-triggered reaction: before fix, sender=@default-bot; after fix, sender=@correct-agent. Verified for reactions, sends, and edits.
4 Voice message E2E: message(action=send, media=file.ogg, asVoice=true) → Matrix event contains org.matrix.msc3245.voice and org.matrix.msc1767.audio with correct duration. Triple-tested across OGG/Opus and MP3 formats — 4/4 success after fix, 0/3 before fix.
5 Directory search operational after migration to fetchWithSsrFGuard.
6 All storage-meta.json written at 0o600; parent directories at 0o700.
7 Bot ignores room invitations when autoJoin is absent from config. Explicit "always" configs continue to function.
8 Malformed login attempts produce sanitized error messages; raw server responses no longer appear in logs.
9 Room info resolution functions correctly; stale entries expire after 5 minutes.

@openclaw-barnacle openclaw-barnacle Bot added channel: matrix Channel integration: matrix size: S labels Mar 3, 2026
@efe-arv efe-arv marked this pull request as ready for review March 3, 2026 18:39

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cf9064bea4

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/matrix/src/matrix/monitor/index.ts Outdated

@efe-arv efe-arv left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good observation. You're correct that the current approach resolves boundAgentId once per account at monitor startup, which means all rooms on that account share one set of mention regexes.

Why this is acceptable for now: The multi-account architecture (channels.matrix.accounts) maps each account to a single agent identity — the 1:1 account→agent pattern is the intended usage. The boundAgentId resolution picks the first matching binding, which in practice is the only binding for that account's agent.

Where it would break: If someone binds the same Matrix account to multiple agents with different mentionPatterns across different rooms. In that edge case, non-first bindings would get the wrong regex set and messages could be incorrectly dropped as no-mention before routing runs.

Proper fix (out of scope for this PR): Move mention regex resolution into the per-event handler, after resolveAgentRoute() returns the actual agentId for that specific room+message. This would require buildMentionRegexes to accept the routed agentId and a per-agent regex cache. Filed as a follow-up concern — happy to address it in a subsequent PR if the maintainers want it.

@greptile-apps

greptile-apps Bot commented Mar 3, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR is a well-structured multi-fix bundle addressing multi-account identity routing, voice message delivery, and several security hardening measures in the Matrix plugin. The vast majority of changes are correct and well-reasoned.

Two correctness issues were identified:

  • Incomplete accountId propagation in tool-actions.ts — The editMessage and deleteMessage switch cases within handleMatrixAction do not forward the newly-accepted accountId parameter to editMatrixMessage and deleteMatrixMessage. Both of those functions accept MatrixActionClientOpts (which includes accountId) and pass it to resolveActionClient, so the plumbing exists — it was simply missed. As a result, agent-triggered message edits and deletions will continue to execute under the default bot identity in multi-account deployments, contrary to the stated goal of Fix 3.

  • Spurious FIFO eviction when refreshing a stale cache entry in room-info.ts — When getRoomInfo is called for a roomId that is already in the cache but has a stale TTL, the eviction check roomInfoCache.size >= ROOM_INFO_CACHE_MAX_SIZE evaluates to true (the stale entry still occupies the slot). The oldest entry (a potentially valid, recently-accessed entry for a different room) is then evicted before the stale entry is overwritten via set. Since Map.set on an existing key does not grow the map, no eviction was needed. The condition should be gated on !roomInfoCache.has(roomId).

The security hardening changes (SSRF guard, file permission modes, login error sanitization, autoJoin default, cache bounds) are all correctly implemented. The tsdown.config.ts build entry, audioAsVoice forwarding, and reactMatrixMessage backward-compat signature are also correct.

Confidence Score: 3/5

  • Safe to merge with caveats — two correctness gaps remain that partially undercut the stated goals of the PR.
  • The security hardening and voice message fixes are correct and well-implemented. However, the multi-account identity routing fix is incomplete: editMessage and deleteMessage in tool-actions.ts still call their underlying action functions without accountId, so those operations continue using the default account. Additionally, the new room-info cache evicts valid entries unnecessarily on stale TTL refreshes. Neither issue is data-loss critical, but the identity routing gap directly contradicts the PR's primary correctness claim.
  • extensions/matrix/src/tool-actions.ts (incomplete accountId propagation for edit/delete actions) and extensions/matrix/src/matrix/monitor/room-info.ts (eviction logic when refreshing stale entries).

Last reviewed commit: cf9064b

@efe-arv efe-arv left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both issues addressed in 5b09183:

  1. tool-actions.ts — accountId propagation for edit/delete: Added { accountId: accountId ?? undefined } to both editMatrixMessage and deleteMatrixMessage calls. Good catch — these were the only two message actions missing the propagation.

  2. room-info.ts — spurious eviction on stale refresh: Changed the eviction guard from roomInfoCache.size >= ROOM_INFO_CACHE_MAX_SIZE to !roomInfoCache.has(roomId) && roomInfoCache.size >= ROOM_INFO_CACHE_MAX_SIZE. When refreshing a stale entry for an existing key, Map.set overwrites in-place without growing the map, so eviction is unnecessary.

Thanks for the thorough review.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

13 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Comment thread extensions/matrix/src/matrix/monitor/room-info.ts Outdated
@greptile-apps

greptile-apps Bot commented Mar 3, 2026

Copy link
Copy Markdown
Contributor
Additional Comments (2)

extensions/matrix/src/tool-actions.ts, line 109
accountId not forwarded to editMatrixMessage and deleteMatrixMessage

The PR adds accountId as a parameter to handleMatrixAction and correctly propagates it to reactMatrixMessage (line 64) and sendMatrixMessage (line 91), but the editMessage and deleteMessage switch cases do not pass accountId to their underlying action functions.

Looking at messages.ts, editMatrixMessage and deleteMatrixMessage both accept opts: MatrixActionClientOpts, and resolveActionClient in client.ts consults opts.accountId to look up the correct per-account Matrix client. Without this, both editMessage and deleteMessage will continue to resolve to the default account identity in multi-account deployments — exactly the bug this PR intends to fix.

      case "editMessage": {
        const roomId = readRoomId(params);
        const messageId = readStringParam(params, "messageId", { required: true });
        const content = readStringParam(params, "content", { required: true });
        const result = await editMatrixMessage(roomId, messageId, content, {
          accountId: accountId ?? undefined,
        });
        return jsonResult({ ok: true, result });
      }
      case "deleteMessage": {
        const roomId = readRoomId(params);
        const messageId = readStringParam(params, "messageId", { required: true });
        const reason = readStringParam(params, "reason");
        await deleteMatrixMessage(roomId, messageId, {
          reason: reason ?? undefined,
          accountId: accountId ?? undefined,
        });
        return jsonResult({ ok: true, deleted: true });
      }

extensions/matrix/src/matrix/monitor/room-info.ts, line 47
Unnecessary cache eviction when refreshing a stale entry

The FIFO eviction check does not account for the case where roomId is already present in the map (i.e., the entry exists but its TTL has expired). When a stale entry is being refreshed:

  1. The stale entry is still in the map, so roomInfoCache.size >= ROOM_INFO_CACHE_MAX_SIZE evaluates to true
  2. The oldest entry (which may be a valid, non-stale entry for a different room) is evicted
  3. roomInfoCache.set(roomId, info) then updates the existing key — the map size does not increase

The net effect is the map shrinks from 500 to 499, having unnecessarily evicted a valid entry. The eviction guard should only trigger when a genuinely new key is being inserted. The condition should be: !roomInfoCache.has(roomId) && roomInfoCache.size >= ROOM_INFO_CACHE_MAX_SIZE

Comment thread extensions/matrix/src/matrix/monitor/index.ts Outdated
@efe-arv

efe-arv commented Mar 3, 2026

Copy link
Copy Markdown
Contributor Author

Re: codex-connector P1 (mention regexes per route)

Acknowledged — known limitation. The 1:1 account→agent mapping means compiled regexes are correct today. Per-event resolution (after resolveAgentRoute) is the proper fix for multi-agent-per-account setups — tracking as follow-up.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ab71a5eb55

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/matrix/src/matrix/monitor/index.ts Outdated
@efe-arv

efe-arv commented Mar 3, 2026

Copy link
Copy Markdown
Contributor Author

Re: codex-connector P1 (restore fallback mention regexes)

Fixed in e3e4234. When boundAgentIds is empty (no bindings resolve for this account), we now fall back to buildMentionRegexes(cfg) — the global pattern set without an agentId filter. This preserves the original behavior for configs using open routing or rooms not listed in groups.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e3e4234fe7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/matrix/src/directory-live.ts
@efe-arv

efe-arv commented Mar 3, 2026

Copy link
Copy Markdown
Contributor Author

Re: codex-connector P1 (allow trusted private homeservers)

Fixed in 7c83aa4. Added policy: { allowPrivateNetwork: true } to the fetchWithSsrFGuard call in fetchMatrixJson. The homeserver URL is operator-configured and trusted — blocking RFC1918/localhost would break every self-hosted Matrix deployment (Conduit, Synapse on LAN, etc.). The SSRF guard still protects against redirect-based attacks since it validates the final resolved address, but the initial target is trusted config.

@efe-arv efe-arv force-pushed the fix/matrix-multi-account branch from 7c83aa4 to 57f1a4d Compare March 4, 2026 11:33

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 57f1a4d1c1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/matrix/src/tool-actions.ts
Comment thread tsdown.config.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9c8494b298

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/matrix/src/matrix/monitor/index.ts
@efe-arv efe-arv force-pushed the fix/matrix-multi-account branch from 419bc22 to ce3ace8 Compare March 4, 2026 18:05

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ce3ace8e7c

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/matrix/src/tool-actions.ts
Comment thread extensions/matrix/src/matrix/monitor/auto-join.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f31f996ac4

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/matrix/src/matrix/monitor/index.ts
Comment thread extensions/matrix/src/matrix/monitor/auto-join.ts
liri-ha added 6 commits March 4, 2026 23:33
…nd security hardening

Rebased on upstream main. Squashed all prior fixup commits.

Changes:
- Add keyed-async-queue build entry to tsdown.config.ts
- Resolve agentId for buildMentionRegexes in monitor init
- Propagate accountId through complete tool action dispatch chain
- Forward audioAsVoice and accountId through sendMatrixMessage wrapper
- Apply SSRF-guarded fetch to directory API calls
- Restrict file permissions on credentials and storage metadata
- Change default autoJoin from 'always' to 'allowlist'
- Sanitize login error responses
- Add TTL and size bounds to room info cache
…entry

- P1: reaction remove path now forwards accountId so non-default
  accounts can remove their own reactions
- P2: keyed-async-queue explicit build entry removed — already
  covered by pluginSdkEntrypoints array since upstream update
Pass accountId to readMessages, listReactions, pinMessage, unpinMessage,
listPins, memberInfo, and channelInfo — not just send/edit/delete/react.

All action helpers accept MatrixActionClientOpts which includes accountId,
but the dispatch was only forwarding it to a subset of actions.
… binding match

- Merge accountConfig.autoJoin and autoJoinAllowlist into the resolved
  cfg so registerMatrixAutoJoin reads per-account settings, not just
  the top-level value
- Support '*' wildcard in binding accountId filter, aligning with
  resolve-route.ts routing semantics
@efe-arv efe-arv force-pushed the fix/matrix-multi-account branch from d688a0d to f5ddeb8 Compare March 4, 2026 20:33

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f5ddeb88cf

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/matrix/src/matrix/monitor/index.ts
@gumadeiras

Copy link
Copy Markdown
Member

OpenClaw now uses a new Matrix plugin built on the official matrix-js-sdk. The older Matrix implementation is no longer supported.

Closing this as potentially fixed in the new plugin. If this still reproduces after migrating, please open a new issue/PR against the new Matrix plugin and link back here.

Migration/docs:
https://docs.openclaw.ai/channels/matrix
https://docs.openclaw.ai/install/migrating-matrix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: matrix Channel integration: matrix size: S

Projects

None yet

4 participants