mirror of
https://github.com/matrix-org/matrix-spec
synced 2026-05-02 07:04:09 +02:00
Compare commits
1 commit
577f981d67
...
2a3a0d8862
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a3a0d8862 |
|
|
@ -1 +0,0 @@
|
||||||
Add a "Policy Servers" module, as per [MSC4284](https://github.com/matrix-org/matrix-spec-proposals/pull/4284).
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Add a concept of "Policy Servers", as per [MSC4284](https://github.com/matrix-org/matrix-spec-proposals/pull/4284).
|
|
||||||
|
|
@ -469,8 +469,6 @@ The flow for auto-discovery is as follows:
|
||||||
|
|
||||||
{{% http-api spec="client-server" api="support" %}}
|
{{% http-api spec="client-server" api="support" %}}
|
||||||
|
|
||||||
{{% http-api spec="client-server" api="policy_server" %}}
|
|
||||||
|
|
||||||
### API Versions
|
### API Versions
|
||||||
|
|
||||||
Upon connecting, the Matrix client and server need to negotiate which version of the specification
|
Upon connecting, the Matrix client and server need to negotiate which version of the specification
|
||||||
|
|
@ -1687,7 +1685,7 @@ For a client to be considered fully OAuth 2.0 aware it MUST:
|
||||||
then the client MUST redirect users to manage their account at the [account
|
then the client MUST redirect users to manage their account at the [account
|
||||||
management URL](#oauth-20-account-management), if available, instead of
|
management URL](#oauth-20-account-management), if available, instead of
|
||||||
providing a native UI using the legacy API endpoints.
|
providing a native UI using the legacy API endpoints.
|
||||||
|
|
||||||
* If the user wishes to deactivate their account then the client MUST refer
|
* If the user wishes to deactivate their account then the client MUST refer
|
||||||
them to the account management URL.
|
them to the account management URL.
|
||||||
* If the user wishes to sign out a device other than its own then the client
|
* If the user wishes to sign out a device other than its own then the client
|
||||||
|
|
@ -4277,7 +4275,6 @@ that profile.
|
||||||
| [Read and Unread Markers](#read-and-unread-markers) | Optional | Optional | Optional | Optional | Optional |
|
| [Read and Unread Markers](#read-and-unread-markers) | Optional | Optional | Optional | Optional | Optional |
|
||||||
| [Guest Access](#guest-access) | Optional | Optional | Optional | Optional | Optional |
|
| [Guest Access](#guest-access) | Optional | Optional | Optional | Optional | Optional |
|
||||||
| [Moderation Policy Lists](#moderation-policy-lists) | Optional | Optional | Optional | Optional | Optional |
|
| [Moderation Policy Lists](#moderation-policy-lists) | Optional | Optional | Optional | Optional | Optional |
|
||||||
| [Policy Servers](#policy-servers) | Optional | Optional | Optional | Optional | Optional |
|
|
||||||
| [OpenID](#openid) | Optional | Optional | Optional | Optional | Optional |
|
| [OpenID](#openid) | Optional | Optional | Optional | Optional | Optional |
|
||||||
| [Recently used emoji](#recently-used-emoji) | Optional | Optional | Optional | Optional | Optional |
|
| [Recently used emoji](#recently-used-emoji) | Optional | Optional | Optional | Optional | Optional |
|
||||||
| [Reference Relations](#reference-relations) | Optional | Optional | Optional | Optional | Optional |
|
| [Reference Relations](#reference-relations) | Optional | Optional | Optional | Optional | Optional |
|
||||||
|
|
@ -4380,7 +4377,6 @@ systems.
|
||||||
{{% cs-module name="Room Upgrades" filename="room_upgrades" %}}
|
{{% cs-module name="Room Upgrades" filename="room_upgrades" %}}
|
||||||
{{% cs-module name="Server Notices" filename="server_notices" %}}
|
{{% cs-module name="Server Notices" filename="server_notices" %}}
|
||||||
{{% cs-module name="Moderation policy lists" filename="moderation_policies" %}}
|
{{% cs-module name="Moderation policy lists" filename="moderation_policies" %}}
|
||||||
{{% cs-module name="Policy Servers" filename="policy_servers" %}}
|
|
||||||
{{% cs-module name="Spaces" filename="spaces" %}}
|
{{% cs-module name="Spaces" filename="spaces" %}}
|
||||||
{{% cs-module name="Event replacements" filename="event_replacements" %}}
|
{{% cs-module name="Event replacements" filename="event_replacements" %}}
|
||||||
{{% cs-module name="Event annotations and reactions" filename="event_annotations" %}}
|
{{% cs-module name="Event annotations and reactions" filename="event_annotations" %}}
|
||||||
|
|
|
||||||
|
|
@ -1,98 +0,0 @@
|
||||||
### Policy Servers
|
|
||||||
|
|
||||||
{{% added-in v="1.18" %}}
|
|
||||||
|
|
||||||
A Policy Server is a homeserver in the room designated to proactively check events
|
|
||||||
before they are sent to the room/users. Rooms are not required to use a Policy
|
|
||||||
Server (PS). Rooms which do use a Policy Server can prevent unwanted events from
|
|
||||||
reaching users.
|
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
Room operators might prefer to use a "moderation bot" instead of a Policy Server.
|
|
||||||
Moderation bots are reactive because they typically [redact](#redactions) events
|
|
||||||
after they've already been sent.
|
|
||||||
|
|
||||||
Room operators might also prefer to layer a moderation bot with a Policy Server
|
|
||||||
for added protection.
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
|
|
||||||
A room's Policy Server is designated by the [`m.room.policy`](#mroompolicy) state
|
|
||||||
event described below. If the state event is not set in the room or is missing
|
|
||||||
required fields, the room does *not* use a Policy Server. Similarly, if the server name in the state
|
|
||||||
event has zero joined users in the room, the room also does *not* use a Policy
|
|
||||||
Server.
|
|
||||||
|
|
||||||
When the room is using a Policy Server, *all* events except for the `m.room.policy`
|
|
||||||
state event itself are checked by that Policy Server. This includes membership
|
|
||||||
events, power level changes, events from before the Policy Server was enabled,
|
|
||||||
and non-state or non-empty `state_key` `m.room.policy` events.
|
|
||||||
|
|
||||||
What a Policy Server checks for on an event is left as an implementation detail.
|
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
More information about how a Policy Server operates precisely is available in
|
|
||||||
the [Server-Server API](/server-server-api/#policy-servers). Most notably, not
|
|
||||||
every homeserver is a Policy Server, and not every Policy Server is a full
|
|
||||||
homeserver.
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
|
|
||||||
{{% event event="m.room.policy" %}}
|
|
||||||
|
|
||||||
#### Client behaviour
|
|
||||||
|
|
||||||
Clients do not interact with the Policy Server directly, but may need enough
|
|
||||||
information to be able to set the `m.room.policy` state event. For this, a client
|
|
||||||
can attempt to call [`/.well-known/matrix/policy_server`](#getwell-knownmatrixpolicy_server)
|
|
||||||
on a user-provided server name. The returned information can then be used to
|
|
||||||
populate the `m.room.policy` state event.
|
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
Clients are *not* required to use `/.well-known/matrix/policy_server` to populate the
|
|
||||||
`m.room.policy` state event. If they have the required information from elsewhere,
|
|
||||||
they can simply send the state event.
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
|
|
||||||
#### Server behaviour
|
|
||||||
|
|
||||||
See the [Policy Servers section of the Server-Server API](/server-server-api/#policy-servers).
|
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
If implementing your own Policy Server, see [MSC4284: Policy Servers](https://github.com/matrix-org/matrix-spec-proposals/blob/main/proposals/4284-policy-servers.md)
|
|
||||||
for additional security, implementation, and safety considerations.
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
|
|
||||||
#### Security considerations
|
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
Portions of this section rely on context from the [Policy Servers section of the Server-Server API](/server-server-api/#policy-servers).
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
|
|
||||||
By nature of being a proactive tool for a room, Policy Server can expect to be
|
|
||||||
Denial of Service (DoS) targets. Policy Servers MUST be tolerant to DoS attacks.
|
|
||||||
The scale of attack they need to tolerate is left as an implementation/deployment
|
|
||||||
detail. A Policy Server dedicated to a small community might not have the same
|
|
||||||
requirements as a Policy Server available for many communities to use.
|
|
||||||
|
|
||||||
To help ensure that rooms can be used when their chosen Policy Server is inaccessible,
|
|
||||||
the `m.room.policy` state event can be set *without* consulting the Policy Server.
|
|
||||||
This in effect allows users with appropriate power levels to wipe the content of
|
|
||||||
`m.room.policy`, disabling the Policy Server immediately.
|
|
||||||
|
|
||||||
Policy Servers MUST have a joined user in the room to prevent rooms overloading
|
|
||||||
or forcing a given server to act as a Policy Server. The Policy Server can evict
|
|
||||||
itself from the room to also disable usage immediately.
|
|
||||||
|
|
||||||
Events sent "before" the Policy Server was enabled can end up being recommended
|
|
||||||
for exclusion by the Policy Server. This is expected behaviour to ensure new policies
|
|
||||||
apply to events which took a while to send.
|
|
||||||
|
|
||||||
Homeservers might not ask a Policy Server for a signature on an event before sending
|
|
||||||
it to the room. Other compliant homeservers will request that signature instead,
|
|
||||||
and layered tooling (like "moderation bots") can help remove events which bypass
|
|
||||||
the room's Policy Server, if desirable.
|
|
||||||
|
|
||||||
Homeservers might request and receive a valid signature for an event, but delay
|
|
||||||
or never send the event. "Moderation bots" can monitor for clock drift on signed
|
|
||||||
events, if desirable. A Policy Server implementation might also monitor for clock
|
|
||||||
drift, though does need to consider that events can be backdated in ways beyond
|
|
||||||
`origin_server_ts`.
|
|
||||||
|
|
@ -473,9 +473,6 @@ server must ensure that the event:
|
||||||
otherwise it is rejected.
|
otherwise it is rejected.
|
||||||
6. Passes authorization rules based on the current state of the room,
|
6. Passes authorization rules based on the current state of the room,
|
||||||
otherwise it is "soft failed".
|
otherwise it is "soft failed".
|
||||||
7. {{% added-in v="1.18" %}} Is [validated](#validating-policy-server-signatures)
|
|
||||||
by the Policy Server, if the room is [using a Policy Server](#determining-if-a-policy-server-is-enabled-in-a-room),
|
|
||||||
otherwise it is "soft failed".
|
|
||||||
|
|
||||||
Further details of these checks, and how to handle failures, are
|
Further details of these checks, and how to handle failures, are
|
||||||
described below.
|
described below.
|
||||||
|
|
@ -692,11 +689,6 @@ then any new event `D'` will not reference `C`:
|
||||||
|
|
|
|
||||||
D'
|
D'
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
{{% added-in v="1.18" %}}
|
|
||||||
Events can also be soft failed if they fail [Policy Server checks](#validating-policy-server-signatures).
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
|
|
||||||
#### Retrieving event authorization information
|
#### Retrieving event authorization information
|
||||||
|
|
||||||
The homeserver may be missing event authorization information, or wish
|
The homeserver may be missing event authorization information, or wish
|
||||||
|
|
@ -1285,171 +1277,6 @@ endpoint MUST be protected as follows:
|
||||||
room ID MUST be ignored if the sending server is denied access to
|
room ID MUST be ignored if the sending server is denied access to
|
||||||
the room identified by that ID.
|
the room identified by that ID.
|
||||||
|
|
||||||
The following endpoints MAY be protected:
|
|
||||||
|
|
||||||
- [`/_matrix/policy/v1/sign`](#post_matrixpolicyv1sign) - {{< added-in v="1.18" >}}
|
|
||||||
Protected if the server is tracking the DAG and chooses to enforce the ACL.
|
|
||||||
|
|
||||||
|
|
||||||
## Policy Servers
|
|
||||||
|
|
||||||
{{% added-in v="1.18" %}}
|
|
||||||
|
|
||||||
Policy Servers are an available tool for rooms to add proactive protections. Rooms
|
|
||||||
which use a Policy Server (PS) can prevent unwanted events from reaching users. Rooms
|
|
||||||
are not required to use a Policy Server, and can disable it any time after enabling
|
|
||||||
it.
|
|
||||||
|
|
||||||
For a homeserver to be a Policy Server, it MUST implement the following functionality
|
|
||||||
of the Server-Server API:
|
|
||||||
|
|
||||||
* [Normal server name resolution](#resolving-server-names).
|
|
||||||
* [Publishing a signing key](#publishing-keys).
|
|
||||||
* [Request authentication](#authentication).
|
|
||||||
* Being able to [make and send join requests](#joining-rooms).
|
|
||||||
* Receiving and processing [`POST /_matrix/policy/v1/sign`](#post_matrixpolicyv1sign)
|
|
||||||
requests.
|
|
||||||
|
|
||||||
All other functionality and endpoints are optional for a Policy Server.
|
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
Though a Policy Server is not required to implement the full Server-Server API
|
|
||||||
surface, some functionality may be desirable to implement anyway:
|
|
||||||
|
|
||||||
* Receiving [invites](#inviting-to-a-room) can make it easier to add the Policy
|
|
||||||
Server to a room.
|
|
||||||
* Receiving [transactions](#transactions) is recommended to avoid remote servers
|
|
||||||
flagging the Policy Server as "offline", even if the contents are discarded.
|
|
||||||
* Receiving [device lookups](#get_matrixfederationv1userdevicesuserid) can also
|
|
||||||
help reduce remote servers flagging the Policy Server as "offline".
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
Policy Servers are *not* required to track the DAG for a room. Policy Servers
|
|
||||||
might be optimized for content moderation and therefore do not need knowledge of
|
|
||||||
the DAG.
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
|
|
||||||
### Determining if a Policy Server is enabled in a room
|
|
||||||
|
|
||||||
For a room to be considered as "using" a Policy Server, *all* of the following
|
|
||||||
conditions MUST be true:
|
|
||||||
|
|
||||||
* The *current state* for the room has a valid [`m.room.policy`](/client-server-api/#mroompolicy)
|
|
||||||
state event with empty state key. Valid means `content` contains at least:
|
|
||||||
* A string value for `via`.
|
|
||||||
* An object value for `public_keys` containing at least a string value for
|
|
||||||
`ed25519`.
|
|
||||||
* The server name denoted by the `m.room.policy` state event's `via` has at least
|
|
||||||
one joined user in the room in *current state*. The user does not need any
|
|
||||||
special permissions or power levels in the room.
|
|
||||||
|
|
||||||
If a room has enabled a Policy Server, *all* servers in that room MUST [ask that
|
|
||||||
Policy Server](#asking-for-a-policy-server-signature-on-an-event) for a signature
|
|
||||||
before sending an event. If the Policy Server refuses to sign the event being
|
|
||||||
sent, servers SHOULD fail to send that event as per the [validation rules](#validating-policy-server-signatures).
|
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
"Current state" shares the same definition as [soft failure](#soft-failure).
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
Policy Servers MUST have at least one joined user in the room to give the Policy
|
|
||||||
Server agency in whether it serves that role for the room. Otherwise, a room
|
|
||||||
would be able to force a Policy Server to participate and then overwhelm it.
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
|
|
||||||
### Validating Policy Server signatures
|
|
||||||
|
|
||||||
Policy Servers use signatures to indicate whether an event was checked and is
|
|
||||||
recommended for inclusion in a room. The Policy Server's recommendation does *not*
|
|
||||||
affect the authorization rules for an event, but does affect whether homeservers
|
|
||||||
[soft fail](#soft-failure) or refuse to actually go forward with sending an event.
|
|
||||||
|
|
||||||
If a room has disabled (or never enabled) a Policy Server, events are recommended
|
|
||||||
for inclusion and subject to normal authorization rules.
|
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
Because the Policy Server is not asked to sign [`m.room.policy`](/client-server-api/#mroompolicy)
|
|
||||||
state events with empty string `state_key`s, those events will not have a Policy
|
|
||||||
Server signature. Those events are by default recommended for inclusion and still
|
|
||||||
subject to normal authorization rules.
|
|
||||||
|
|
||||||
All other events SHOULD have a valid Policy Server signature when a Policy Server
|
|
||||||
is enabled in the room, including non-state `m.room.policy` events and `m.room.policy`
|
|
||||||
state events with non-empty `state_key`s. This also includes state events like
|
|
||||||
membership and power level changes.
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
|
|
||||||
If a room has enabled a Policy Server, the Policy Server's signature appears
|
|
||||||
alongside the normal [event signatures](#signing-events), though uses a public
|
|
||||||
key from the room's `m.room.policy` state event.
|
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
Currently, only Ed25519 keys are supported by homeservers. The Key ID for the
|
|
||||||
`ed25519` key in `m.room.policy` is *always* `ed25519:policy_server`.
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
By embedding the Policy Server's public key into room state, the Policy Server
|
|
||||||
does not need to be online or have its keys cached by a notary in order to validate
|
|
||||||
an event.
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
|
|
||||||
{{% boxes/warning %}}
|
|
||||||
The Policy Server's [published signing key](#publishing-keys) SHOULD NOT be the
|
|
||||||
same key contained in the `m.room.policy` state event. This is to keep "can send
|
|
||||||
federation traffic" and "can recommend events for inclusion" separate, and to
|
|
||||||
allow rooms to revoke the Policy Server's key without cooperation of the Policy
|
|
||||||
Server.
|
|
||||||
|
|
||||||
If the Policy Server is acting as a normal homeserver and attempting to send an
|
|
||||||
event, that event will require a signature from the server's published signing
|
|
||||||
key alongside the Policy Server signature described in this section.
|
|
||||||
{{% /boxes/warning %}}
|
|
||||||
|
|
||||||
If the Policy Server's signature is valid, the event is recommended for inclusion
|
|
||||||
in the room, and is still subject to normal authorization rules.
|
|
||||||
|
|
||||||
If the Policy Server's signature is invalid or missing, the homeserver SHOULD
|
|
||||||
[ask for a new signature](#asking-for-a-policy-server-signature-on-an-event). If
|
|
||||||
the event still does not have a valid Policy Server signature, the event is *not*
|
|
||||||
recommended for inclusion and the homeserver SHOULD:
|
|
||||||
|
|
||||||
* If applicable, reject the Client-Server API request which was generating the
|
|
||||||
event. If the Policy Server returned an error, that error SHOULD be provided
|
|
||||||
to the client verbatim. The event the client was attempting to send SHOULD be
|
|
||||||
discarded and not processed/sent any further.
|
|
||||||
* If the event was received over federation or the homeserver sends a local client's
|
|
||||||
event anyway, [soft fail](#soft-failure) the event.
|
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
For clarity, an event which lacks a valid Policy Server signature is still subject
|
|
||||||
to normal authorization rules.
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
When a Policy Server's signature is invalid, a new one is requested because the
|
|
||||||
Policy Server's key may have rotated between the event being signed and the event
|
|
||||||
being checked.
|
|
||||||
|
|
||||||
Because the key is contained in the `m.room.policy` state event, if the Policy
|
|
||||||
Server rotates its key without the room also updating the state event, events
|
|
||||||
will be flagged as not recommended for inclusion. This is expected behaviour.
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
|
|
||||||
### Asking for a Policy Server signature on an event
|
|
||||||
|
|
||||||
Per [above](#determining-if-a-policy-server-is-enabled-in-a-room), if a room has
|
|
||||||
a Policy Server enabled, *all* servers in the room MUST ask the Policy Server to
|
|
||||||
sign their events before sending them to clients and servers.
|
|
||||||
|
|
||||||
After asking for a signature, homeservers SHOULD [validate](#validating-policy-server-signatures)
|
|
||||||
the returned signature before continuing to send events. If the Policy Server
|
|
||||||
returns an error, the event SHOULD NOT be sent to clients and servers.
|
|
||||||
|
|
||||||
{{% http-api spec="server-server" api="room_policy" %}}
|
|
||||||
|
|
||||||
## Signing Events
|
## Signing Events
|
||||||
|
|
||||||
Signing events is complicated by the fact that servers can choose to
|
Signing events is complicated by the fact that servers can choose to
|
||||||
|
|
@ -1473,12 +1300,6 @@ The signature is then copied back to the original event object.
|
||||||
For an example of a signed event, see the [room version
|
For an example of a signed event, see the [room version
|
||||||
specification](/rooms).
|
specification](/rooms).
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
{{% added-in v="1.18" %}}
|
|
||||||
Events sent in rooms with [Policy Servers](#policy-servers) MUST [ask](#asking-for-a-policy-server-signature-on-an-event)
|
|
||||||
the Policy Server for a signature too.
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
|
|
||||||
### Validating hashes and signatures on received events
|
### Validating hashes and signatures on received events
|
||||||
|
|
||||||
When a server receives an event over federation from another server, the
|
When a server receives an event over federation from another server, the
|
||||||
|
|
@ -1513,12 +1334,6 @@ only been given a redacted version of the event. To enforce this, the
|
||||||
receiving server should use the redacted copy it calculated rather than
|
receiving server should use the redacted copy it calculated rather than
|
||||||
the full copy it received.
|
the full copy it received.
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
{{% added-in v="1.18" %}}
|
|
||||||
Events sent in rooms with [Policy Servers](#policy-servers) have [additional](#validating-policy-server-signatures)
|
|
||||||
signature validation requirements.
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
|
|
||||||
### Calculating the reference hash for an event
|
### Calculating the reference hash for an event
|
||||||
|
|
||||||
The *reference hash* of an event covers the essential fields of an
|
The *reference hash* of an event covers the essential fields of an
|
||||||
|
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
||||||
# Copyright 2026 The Matrix.org Foundation C.I.C.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
openapi: 3.1.0
|
|
||||||
info:
|
|
||||||
title: Matrix Client-Server Policy Server Discovery API
|
|
||||||
version: 1.0.0
|
|
||||||
paths:
|
|
||||||
/matrix/policy_server:
|
|
||||||
get:
|
|
||||||
summary: Gets information about a Policy Server's configuration, if available.
|
|
||||||
description: |-
|
|
||||||
Gets public key information for a [Policy Server](/client-server-api/#policy-servers).
|
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
Like the [well-known discovery URI](/client-server-api/#well-known-uris),
|
|
||||||
this endpoint should be accessed with the hostname of the Policy Server's
|
|
||||||
[server name](/appendices/#server-name) by making a
|
|
||||||
GET request to `https://hostname/.well-known/matrix/policy_server`.
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
|
|
||||||
Note that this endpoint is not necessarily handled by the homeserver or
|
|
||||||
Policy Server. It may be served by another webserver.
|
|
||||||
operationId: getWellknownPolicy
|
|
||||||
x-addedInMatrixVersion: "1.18"
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: |-
|
|
||||||
Public keys for the Policy Server. Can be supplied to the [`m.room.policy`](/client-server-api/#mroompolicy)
|
|
||||||
state event.
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
public_keys:
|
|
||||||
type: object
|
|
||||||
description: |-
|
|
||||||
The unpadded base64-encoded public keys for the Policy Server. MUST contain
|
|
||||||
at least `ed25519`.
|
|
||||||
properties:
|
|
||||||
ed25519:
|
|
||||||
type: string
|
|
||||||
description: The unpadded base64-encoded ed25519 public key for the Policy Server.
|
|
||||||
required: ['ed25519']
|
|
||||||
additionalProperties:
|
|
||||||
type: string
|
|
||||||
description: The unpadded base64-encoded public key for the key algorithm.
|
|
||||||
required: ["public_keys"]
|
|
||||||
examples:
|
|
||||||
response:
|
|
||||||
value:
|
|
||||||
{
|
|
||||||
"public_keys": {
|
|
||||||
"ed25519": "6yhHGKhCiXTSEN2ksjV7kX_N6rBQZ3Xb-M7LlC6NS-s"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"404":
|
|
||||||
description: No policy server information available.
|
|
||||||
tags:
|
|
||||||
- Server administration
|
|
||||||
servers:
|
|
||||||
- url: "{protocol}://{hostname}{basePath}"
|
|
||||||
variables:
|
|
||||||
protocol:
|
|
||||||
enum:
|
|
||||||
- https
|
|
||||||
default: https
|
|
||||||
hostname:
|
|
||||||
default: localhost:8008
|
|
||||||
basePath:
|
|
||||||
default: /.well-known
|
|
||||||
|
|
@ -1,172 +0,0 @@
|
||||||
# Copyright 2026 The Matrix.org Foundation C.I.C.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
openapi: 3.1.0
|
|
||||||
info:
|
|
||||||
title: Matrix Federation Room Policy API
|
|
||||||
version: 1.0.0
|
|
||||||
paths:
|
|
||||||
"/sign":
|
|
||||||
post:
|
|
||||||
summary: Asks the Policy Server to sign an event.
|
|
||||||
description: |-
|
|
||||||
A server is a Policy Server if it implements this endpoint, among
|
|
||||||
[other requirements](/server-server-api/#policy-servers). This endpoint
|
|
||||||
is otherwise optional. See [Unsupported Endpoints](/server-server-api/#unsupported-endpoints)
|
|
||||||
for details on how to exclude implementation of this endpoint.
|
|
||||||
|
|
||||||
This endpoint MUST NOT be called for events which have a type of `m.room.policy`
|
|
||||||
and an empty string `state_key`. All other events, including state events,
|
|
||||||
non-state `m.room.policy` events, and `m.room.policy` state events with
|
|
||||||
non-empty string `state_key`s are processed by this endpoint.
|
|
||||||
|
|
||||||
Whether a signature is required by a Policy Server further depends on whether
|
|
||||||
the room has [enabled a Policy Server](#determining-if-a-policy-server-is-enabled-in-a-room).
|
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
The Policy Server MAY respond with *any* of the defined errors to indicate
|
|
||||||
failure. For example, if it wishes to hide whether it knows about a room,
|
|
||||||
it MAY return `400 M_FORBIDDEN` instead (or, it MAY sign the event anyway).
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
|
|
||||||
What the Policy Server checks for when calling this endpoint is left as an
|
|
||||||
implementation detail.
|
|
||||||
operationId: askPolicyServerToSign
|
|
||||||
security:
|
|
||||||
- signedRequest: []
|
|
||||||
parameters: []
|
|
||||||
requestBody:
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
title: PDU
|
|
||||||
description: |-
|
|
||||||
The [PDU](/server-server-api/#pdus) to request a signature for. The event format
|
|
||||||
varies depending on the room version - check the [room version specification](/rooms)
|
|
||||||
for precise event formats.
|
|
||||||
properties: {}
|
|
||||||
example:
|
|
||||||
$ref: examples/minimal_pdu.json
|
|
||||||
required: true
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: |-
|
|
||||||
The Policy Server has signed the event, indicating that it recommends the event for
|
|
||||||
inclusion in the room. Only the Policy Server's signature is returned. This signature
|
|
||||||
is to be added to the event before sending or processing the event further.
|
|
||||||
|
|
||||||
`ed25519:policy_server` is *always* used for Ed25519 signatures.
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties: {}
|
|
||||||
required: []
|
|
||||||
example: {
|
|
||||||
"policy.example.org": {
|
|
||||||
"ed25519:policy_server": "zLFxllD0pbBuBpfHh8NuHNaICpReF/PAOpUQTsw+bFGKiGfDNAsnhcP7pbrmhhpfbOAxIdLraQLeeiXBryLmBw"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"429":
|
|
||||||
$ref: '#/components/responses/rateLimited'
|
|
||||||
"400":
|
|
||||||
description: |-
|
|
||||||
The request is invalid or the Policy Server refuses to sign the event.
|
|
||||||
|
|
||||||
Error codes include:
|
|
||||||
* `M_BAD_JSON` - The supplied PDU-formatted event was improperly formatted. For example,
|
|
||||||
missing keys required for the room version.
|
|
||||||
* `M_NOT_JSON` - The body wasn't JSON.
|
|
||||||
* `M_FORBIDDEN` - The Policy Server refuses to sign the event.
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
# XXX: We should move error definitions into a more generic place.
|
|
||||||
$ref: ../client-server/definitions/errors/error.yaml
|
|
||||||
examples:
|
|
||||||
response:
|
|
||||||
value: {
|
|
||||||
"errcode": "M_FORBIDDEN",
|
|
||||||
"error": "The message appears to contain possible spam"
|
|
||||||
}
|
|
||||||
"403":
|
|
||||||
description: |-
|
|
||||||
The calling server is [ACL'd](/server-server-api/#server-access-control-lists-acls).
|
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
This endpoint is optionally affected by server ACLs. The Policy Server
|
|
||||||
MAY NOT apply an ACL to the request, especially if the Policy Server
|
|
||||||
is not tracking the room DAG.
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
allOf:
|
|
||||||
# XXX: We should move error definitions into a more generic place.
|
|
||||||
- $ref: ../client-server/definitions/errors/error.yaml
|
|
||||||
- type: object
|
|
||||||
properties:
|
|
||||||
errcode:
|
|
||||||
description: "The `M_FORBIDDEN` error code."
|
|
||||||
required: [errcode]
|
|
||||||
examples:
|
|
||||||
response:
|
|
||||||
value: {
|
|
||||||
"errcode": "M_FORBIDDEN",
|
|
||||||
"error": "Your server is not allowed to request a signature."
|
|
||||||
}
|
|
||||||
"404":
|
|
||||||
description: |-
|
|
||||||
The server is not a Policy Server, or the room is unknown/not protected by the Policy Server.
|
|
||||||
|
|
||||||
Error codes include:
|
|
||||||
* `M_NOT_FOUND` - The room is not known or is not protected by the Policy Server.
|
|
||||||
* `M_UNRECOGNIZED` - The server is not a Policy Server. See [Unsupported Endpoints](/server-server-api/#unsupported-endpoints)
|
|
||||||
for more detail.
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
# XXX: We should move error definitions into a more generic place.
|
|
||||||
$ref: ../client-server/definitions/errors/error.yaml
|
|
||||||
examples:
|
|
||||||
response:
|
|
||||||
value: {
|
|
||||||
"errcode": "M_NOT_FOUND",
|
|
||||||
"error": "Unknown room"
|
|
||||||
}
|
|
||||||
servers:
|
|
||||||
- url: "{protocol}://{hostname}{basePath}"
|
|
||||||
variables:
|
|
||||||
protocol:
|
|
||||||
enum:
|
|
||||||
- http
|
|
||||||
- https
|
|
||||||
default: https
|
|
||||||
hostname:
|
|
||||||
default: localhost:8448
|
|
||||||
basePath:
|
|
||||||
default: /_matrix/policy/v1
|
|
||||||
components:
|
|
||||||
securitySchemes:
|
|
||||||
signedRequest:
|
|
||||||
$ref: definitions/security.yaml#/signedRequest
|
|
||||||
responses:
|
|
||||||
rateLimited:
|
|
||||||
description: This request was rate-limited.
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
# XXX: We should move error definitions into a more generic place.
|
|
||||||
$ref: ../client-server/definitions/errors/rate_limited.yaml
|
|
||||||
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
{
|
|
||||||
"$ref": "core/state_event.json",
|
|
||||||
"type": "m.room.policy",
|
|
||||||
"state_key": "",
|
|
||||||
"content": {
|
|
||||||
"via": "policy.example.org",
|
|
||||||
"public_keys": {
|
|
||||||
"ed25519": "6yhHGKhCiXTSEN2ksjV7kX_N6rBQZ3Xb-M7LlC6NS-s"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
---
|
|
||||||
$schema: https://json-schema.org/draft/2020-12/schema
|
|
||||||
|
|
||||||
allOf:
|
|
||||||
- $ref: core-event-schema/state_event.yaml
|
|
||||||
description: |-
|
|
||||||
A [Policy Server](/client-server-api/#policy-servers) configuration. If invalid
|
|
||||||
or not set, the room does not use a Policy Server.
|
|
||||||
properties:
|
|
||||||
content:
|
|
||||||
properties:
|
|
||||||
via:
|
|
||||||
description: |-
|
|
||||||
The server name to use as a Policy Server. MUST have a joined user in
|
|
||||||
the room.
|
|
||||||
type: string
|
|
||||||
public_keys:
|
|
||||||
description: |-
|
|
||||||
The unpadded base64-encoded public keys for the Policy Server. MUST contain at
|
|
||||||
least `ed25519`.
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
ed25519:
|
|
||||||
type: string
|
|
||||||
description: The unpadded base64-encoded ed25519 public key for the Policy Server.
|
|
||||||
required: ['ed25519']
|
|
||||||
additionalProperties:
|
|
||||||
description: The unpadded base64-encoded public key for the key algorithm.
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- via
|
|
||||||
- public_keys
|
|
||||||
state_key:
|
|
||||||
description: An empty string.
|
|
||||||
type: string
|
|
||||||
type:
|
|
||||||
enum:
|
|
||||||
- m.room.policy
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
Loading…
Reference in a new issue