Trust and safety¶
This capability note describes runtime-wired trust-and-safety behavior.
Included now¶
- Registration policy checks in the runtime registration path.
- Account lock/suspension policy checks in the runtime login path.
- Room policy checks in the runtime room creation path.
- Media policy checks in the runtime client and federation download paths and persisted moderation rules in the admin workflow. Federation's production provider now invokes the same media decision before repository lookup or byte reads (MED-7, ADR-0144); a denied item yields 403 without media bytes or a successful multipart envelope. The existing media-surface policy-server hook and its configured unavailable-result policy are reused, not replaced by a separate federation-only rule evaluator. The new regression uses real SQLite, admin PUT/DELETE, genuine federation signatures and the production dispatcher; configured-unavailable-hook coverage has no injected callback. The bounded admission repair passes independent review and a fresh normal full suite (56 OK, all return codes zero, 1,026 unchanged frozen files). Live remote-hook responses and strict mid-request policy revocation are not claimed, nor is whole-audit or release acceptance.
- Federation request policy checks in the runtime federation path.
- Authenticated client event reporting through
POST /_matrix/client/v3/rooms/{roomId}/report/{eventId}. The reporter must be joined to the room and the event must be in it and visible to them under the room's history visibility, otherwise404 M_NOT_FOUND(spec: "The event was not found or you are not joined to the room where the event resides"). A repeat report of the same event by the same reporter is acknowledged without a second audit row (CSAZ-12, ADR-0127). - Admin report listing through
GET /_matrix/client/v3/admin/safety/reports. - Admin review actions through
POST /_matrix/client/v3/admin/safety/review/{targetType}/{targetId}. - Admin policy-rule management through
GET /_matrix/client/v3/admin/safety/policy_rules,PUT /_matrix/client/v3/admin/safety/policy_rules/{scope}/{entity}, andDELETE /_matrix/client/v3/admin/safety/policy_rules/{scope}/{entity}. A rule's action is one ofallow,deny,quarantine,lock_accountorsuspend_account; any other value is rejected. The engine'sPolicyActionalso hasaccept_report, used only for event-report decisions. - Remote policy-server transport through
security.trust_safety.policy_server_urland the fail-closedPolicyServerHookpath. - Durable policy audit rows, admin action rows, and persisted
policy_rulesfor report/review decisions. - User-level ignore enforcement (Matrix v1.19 CS API §Ignoring Users):
merovingian::trust_safety::ignore_listresolves a user'sm.ignored_user_listaccount-data once per request and suppresses delivery of non-state events, room invites, and ephemeral typing/receipt entries from an ignored sender acrossGET /sync, MSC4186 sliding sync,GET /messages,GET /context/{eventId}, and push notification delivery. This is a delivery-side, per-recipient filter, not a moderation action: unlike the policy-engine controls above (which are operator- or admin-driven and block content server-wide), an ignore list is set by the ignoring user themselves and only changes what that user's clients are shown. See "Deliberately not included" below for what it does not protect against.
Security posture¶
The runtime routes fail closed on missing authentication, missing admin
authorization, malformed report bodies, malformed review bodies, and unknown
review targets. When trust-safety transport is enabled, a missing or malformed
policy-server decision blocks the guarded workflow unless
security.trust_safety.policy_server_allow_without_result=true. Policy audit
rows store event type, actor, target, and reason code rather than free-form
event content.
Deliberately not included¶
- Full Matrix v1.19 trust-and-safety conformance fixtures.
- Moderator queues beyond the current audit/admin action summaries.
- Multipart or streaming moderation inputs beyond the current request-local transport contract.
- User reporting,
POST /_matrix/client/v3/users/{userId}/report(Matrix v1.19 CS API). Only event reporting is routed.
What ignoring a user does NOT protect against¶
Per spec, ignoring is purely a client-delivery filter, not an access-control mechanism, and Merovingian implements exactly that scope:
- It does not prevent the ignored user from sending into a shared room.
Their events are still authorized, persisted, and included in the room's
event graph and state resolution, exactly as if they were not ignored — an
ignoring user with room-moderation power must still
/kickor/banto stop the sender, ignoring alone has no effect on that. - It does not hide history already delivered to the client. The spec is explicit that the server "should not send events that were missed while the user was ignored" going the other way (on un-ignore) either — un-ignoring does not retroactively deliver what was suppressed; the client must start a fresh sync to see it. Merovingian never rewrites or deletes anything from the event graph to implement ignoring.
- State events from an ignored sender are still delivered (spec MUST), so ignoring a room's only power-level holder does not hide power-level, membership, or room-metadata changes they make.
- It is not federation- or auth-visible. An ignored sender's PDUs are verified, authorized, and accepted from federation exactly as any other sender's; the ignore list is consulted only at the point Merovingian serializes a response for the ignoring user's own clients.
- It offers no protection against a determined abuser with multiple accounts — ignoring is per-mxid, not per-person.