CoMatrix Gateway Developer Documentation
This section describes the purpose of the different resources that the CoMatrix gateway provides. Further, the structure of expected CoAP requests, and the corresponding CoAP responses are outlined.
RegistrationResource (/register
)
The RegistrationResource enables the registration of a new Matrix user at a specific Matrix-Synapse homeserver
via a CoAP request. It waits for CoAP POST requests (CoAPS is currently not supported by aiocoap on server-side).
These requests need to contain the CoAP options “Content-Format” and “Proxy-Uri”. The Content-Format needs to be set
to application/cbor
and the Proxy-Uri needs to contain the Matrix-Synapse homeserver URL. It is recommended to send
the CoAP request as Message type CONfirmable, to be sure the client receives the CoAP response (i.e. if the
registration was successful or not). Further a payload is required in the CoAP request. The information contained in
the Proxy-Uri option and the payload data are used to construct the HTTP request which conforms with the Matrix
CS-API to register a new user at the target Matrix-Synapse homeserver.
The homeserver URL may be supplied in short or full format via the Proxy-Uri CoAP option:
- Short URL format:
http(s)://IP_domain:PORT/4
=> e.g.http://localhost:8008/4
- The port is optional and only necessary if non-standard HTTP/HTTPS ports are used
- Short URLs are provided by the CoMatrix gateway to reduce the amount of data to be transferred via a constrained network (e.g. 802.15.4/6LoWPAN).
- This short URL is defined in “MSC3079: Low Bandwidth Client-Server API” in “Appendix B: CoAP Path Enums”.
- cf. https://github.com/matrix-org/matrix-doc/blob/7d20c1d9c19972fa63d1d9c124c3656928c28c29/proposals/3079-low-bandwidth-csapi.md#appendix-b-coap-path-enums
- Full URL format:
http(s)://IP_domain:PORT/_matrix/client/r0/register
=> e.g.http://localhost:8008/_matrix/client/r0/register
- cf. https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-register
To register a Matrix user at a Synapse homeserver there needs to be a payload in the following format in the CoAP request (encoded as CBOR):
{"username":"<username>", "password":"<password>", "auth": {"type":"m.login.dummy"}}
<username>
and<password>
can be freely chosen, but"auth": {"type":"m.login.dummy"}
is fixed.- Information regarding the JSON body parameter
"auth"
:-
“Additional authentication information for the user-interactive authentication API. Note that this information is not used to define how the registered user should be authenticated, but is instead used to authenticate the register call itself.” (cf. https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-register )
-
“Dummy authentication always succeeds and requires no extra parameters. Its purpose is to allow servers to not require any form of User-Interactive Authentication to perform a request.” (cf. https://matrix.org/docs/spec/client_server/r0.6.1#dummy-auth )
-
- Information regarding the JSON body parameter
Every CoAP request will be checked for the correct CoAP options and payload format. If incorrect, a CoAP response with a code from class 4 (client error) will be sent (e.g. 4.00/BAD_REQUEST). If options and payload are ok, a HTTP request will be sent to the Synapse homeserver based on the supplied data.
This HTTP request can be successful or unsuccessful. If it was successful, the CoAP response code is 2.04/CHANGED. The CoAP response payload looks as follows:
- The full payload of the HTTP response (sent by Synapse) after registering looks like this:
- e.g.
{"user_id":"@testuser:synapse.name","home_server":"synapse.name","access_token":"XXYYZZZ","device_id":"AXYHVGDE"}
- This contains information which is already available at the client (i.e. username and homeserver name are necessary to send a valid CoAP request) and is therefore filtered for the CoAP response. The relevant information for the client on a constrained device is the access token. Further this reduces the necessary packet size for the CoAP response.
- Device IDs are currently not used in CoMatrix. For more information regarding device IDs see:
- e.g.
- Therefore the CoAP response includes only the access token in the following format (encoded as CBOR):
- e.g.
{'access_token': 'XXXYYYZZZ'}
- e.g.
If the HTTP request was unsuccessful, the CoAP response code is 4.00/BAD_REQUEST. The payload contains the HTTP response JSON (from Synapse) encoded as CBOR.
LoginResource (/login
)
The LoginResource enables the registration of a new Matrix user at a specific Matrix-Synapse homeserver
via a CoAP request. It waits for CoAP POST requests (CoAPS is currently not supported by aiocoap on server-side).
These requests need to contain the CoAP options “Content-Format” and “Proxy-Uri”. The Content-Format needs to be set
to application/cbor
and the Proxy-Uri needs to contain the Matrix-Synapse homeserver URL. It is recommended to send
the CoAP request as Message type CONfirmable, to be sure the client receives the CoAP response (i.e. if the
login was successful or not). Further a payload is required in the CoAP request. The information of the
Proxy-Uri option and the payload data are used to construct the HTTP request which conforms with the Matrix CS-API
to login an existing user at the target Matrix-Synapse homeserver.
The homeserver URL may be supplied in short or full format via the Proxy-Uri CoAP option:
- Short URL format:
http(s)://IP_domain:PORT/1
=> e.g.http://localhost:8008/1
- The port is optional and only necessary if non-standard HTTP/HTTPS ports are used.
- This short URL is defined in “MSC3079: Low Bandwidth Client-Server API” in “Appendix B: CoAP Path Enums”
- cf. https://github.com/matrix-org/matrix-doc/blob/7d20c1d9c19972fa63d1d9c124c3656928c28c29/proposals/3079-low-bandwidth-csapi.md#appendix-b-coap-path-enums
- Full URL format:
http(s)://IP_domain:PORT/_matrix/client/r0/login
=> e.g.http://localhost:8008/_matrix/client/r0/login
- cf. https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-login
To login a Matrix user at a Synapse homeserver there needs to be a payload in the following format in the CoAP request (encoded as CBOR):
{"type":"m.login.password", "identifier": {"type":"m.id.user", "user":"<username>"}, "password":"<password>"}
<username>
and<password>
can be freely chosen, but"type":"m.login.password"
and"type":"m.id.user"
are fixed (only password-based login is supported currently).
Every CoAP request will be checked for the correct CoAP options and payload format. If incorrect, a CoAP response with a code from class 4 (client error) will be sent (e.g. 4.00/BAD_REQUEST). If options and payload are ok, a HTTP request will be sent to the Synapse homeserver based on the supplied data.
This HTTP request can be successful or unsuccessful. If it was successful, the CoAP response code is 2.04/CHANGED. The CoAP response payload looks as follows:
- The full payload of the HTTP response (sent by Synapse) after registering looks like this:
- e.g.
{"user_id":"@example:synapse.name","access_token":"XXXYYYZZZ","home_server":"synapse.name","device_id":"VJEHIKSYUX"}
- This contains information which is already available at the client (i.e. username and homeserver name are necessary to send a valid CoAP request) and is therefore filtered for the CoAP response. The relevant information for the client on a constrained device is the access token. Further this reduces the necessary packet size for the CoAP response.
- Device IDs are currently not used. For more information see:
- e.g.
- Therefore the response only includes the access token in the following format (encoded as CBOR):
- e.g.
{'access_token': 'XXXYYYZZZ'}
- e.g.
If the HTTP request was unsuccessful, the CoAP response code is 4.00/BAD_REQUEST. The payload contains the HTTP response JSON (from Synapse) encoded as CBOR.
JoinResource (/join
)
The JoinResource enables the joining of a new Matrix room at a specific Matrix-Synapse homeserver via a CoAP request
(after the user received an invitation for the room). It waits for CoAP POST requests (CoAPS is currently not
supported by aiocoap on server-side). These requests need to contain the CoAP option “Proxy-Uri” and (optionally)
a custom CoAP option with ID 256. The option with ID 256 is suggested by “MSC3079: Low Bandwidth CS API” and is
required because RFC7252 defines no option mapping for Authorization
headers (IDs 0-255 are reserved for IETF review).
The plain access token must be used in this CoAP option without a prefix (e.g. “Bearer “). If option 256 is not
contained in the CoAP request, the gateway will add a hardcoded access token for the HTTP request.
The Proxy-Uri needs to contain the Matrix-Synapse homeserver URL. It is recommended to send the CoAP request as
message type CONfirmable, to be sure the client receives the CoAP response (i.e. if the joining of the room was
successful or not). The information of the Proxy-Uri option is used to construct the HTTP request which conforms
with the Matrix CS-API to join a Matrix room after an invite from another user at the target Matrix-Synapse
homeserver.
The homeserver URL may be supplied in short or full format via the Proxy-Uri CoAP option:
- Short URL format:
http(s)://IP_domain:PORT/K/<room_id>
=> e.g.http://localhost:8008/K/!SdTxduioYPCZWsKsRC:synapse.name
- The port is optional and only necessary if non-standard HTTP/HTTPS ports are used.
- This short URL is defined in “MSC3079: Low Bandwidth Client-Server API” in “Appendix B: CoAP Path Enums”.
- cf. https://github.com/matrix-org/matrix-doc/blob/7d20c1d9c19972fa63d1d9c124c3656928c28c29/proposals/3079-low-bandwidth-csapi.md#appendix-b-coap-path-enums
- Full URL format:
http(s)://IP_domain:PORT/_matrix/client/r0/rooms/<room_id>/join
=> e.g.http://localhost:8008/_matrix/client/r0/rooms/!SdTxduioYPCZWsKsRC:synapse.name/join
- cf. https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-rooms-roomid-join
To join a Matrix room at a Synapse homeserver there is no payload required in the CoAP request.
Every CoAP request will be checked for the correct CoAP options. If incorrect, a CoAP response with a code from class 4 (client error) will be sent (e.g. 4.00/BAD_REQUEST). If the options are ok, a HTTP request will be sent to the Synapse homeserver based on the supplied data.
This HTTP request can be successful or unsuccessful. If it was successful, the CoAP response code is 2.04/CHANGED. The CoAP response payload looks as follows:
- The payload of the HTTP response (sent by Synapse) after registering looks like this:
- e.g.
{"room_id":"!SdTxduioYPCZWsKsRC:synapse.name"}
- e.g.
- The CoAP response contains the room ID encoded as CBOR:
- e.g.
{"room_id":"!SdTxduioYPCZWsKsRC:synapse.name"}
- e.g.
If the HTTP request was unsuccessful, the CoAP response code is 4.00/BAD_REQUEST. The payload contains the HTTP response JSON (from Synapse) encoded as CBOR.
MessagesResource (/getmsg
)
The MessagesResource enables the receiving of the last (text) message sent to a Matrix room at a specific
Matrix-Synapse homeserver via a CoAP request. It waits for CoAP GET requests (CoAPS is currently not supported by
aiocoap on server-side). These requests need to contain the CoAP option “Proxy-Uri” and (optionally) a custom CoAP
option with ID 256. The option with ID 256 is suggested by “MSC3079: Low Bandwidth CS API” and is required because
RFC7252 defines no option mapping for Authorization
headers (IDs 0-255 are reserved for IETF review). The plain access
token must be used in this CoAP option without a prefix (e.g. “Bearer “). If option 256 is not contained in the CoAP
request, the gateway will add a hardcoded access token for the HTTP request. The Proxy-Uri needs to contain the
Matrix-Synapse homeserver URL. It is recommended to send the CoAP request as message type CONfirmable, to be sure
the client receives the CoAP response (i.e. the message). The information of the Proxy-Uri option is used to
construct the HTTP request to receive the last message of a Matrix room, but the used URL is not completely
compliant with the Matrix CS-API (see below for more information).
The homeserver URL may be supplied in short or full format via the Proxy-Uri CoAP option:
- Short URL format:
http(s)://IP_domain:PORT/E/<room_id>
=> e.g.http://localhost:8008/E/!SdTxduioYPCZWsKsRC:synapse.name
- The port is optional and only necessary if non-standard HTTP/HTTPS ports are used.
- This short URL is defined in “MSC3079: Low Bandwidth Client-Server API” in “Appendix B: CoAP Path Enums”.
- cf. https://github.com/matrix-org/matrix-doc/blob/7d20c1d9c19972fa63d1d9c124c3656928c28c29/proposals/3079-low-bandwidth-csapi.md#appendix-b-coap-path-enums
- Full URL format:
http(s)://IP_domain:PORT/_matrix/client/r0/rooms/<room_id>/messages?dir=b&limit=1
=> e.g.http://localhost:8008/_matrix/client/r0/rooms/!SdTxduioYPCZWsKsRC:synapse.name/messages?dir=b&limit=1
limit=1
specifies to receive the last message. According to the Matrix CS-API specfrom
is required as query parameter, but Synapse seems to not enforce the usage offrom
. This behavior is used to reduce the overhead to just receive the last message of room. Otherwise it would be necessary to perform “syncing” and exfiltrate thefrom
field for the specified room from the extensive HTTP response JSON from Synapse on the gateway. This would make it necessary for the client to send a CoAP request to receive the currentfrom
for the room, to be able to send another CoAP request to receive the last message for this room.- cf. https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-rooms-roomid-messages
To receive the last message of a Matrix room there is no payload required in the CoAP request.
Every CoAP request will be checked for the correct CoAP options. If incorrect, a CoAP response with a code from class 4 (client error) will be sent (e.g. 4.00/BAD_REQUEST). If the options are ok, a HTTP request will be sent to the Synapse homeserver based on the supplied data.
This HTTP request can be successful or unsuccessful. If it was successful, the CoAP response code is 2.04/CHANGED. The CoAP response payload looks as follows:
- The full payload of the HTTP response (sent by Synapse) receiving the last message looks like this:
- e.g.
{"chunk":[{"type":"m.room.message","room_id":"!MauTnKoZREb:synapse.name", "sender":"@testuser:synapse.name","content":{"msgtype":"m.text","body":"Temp: 27.8"}, "origin_server_ts":1620302891950,"unsigned":{"age":83203254},"event_id":"$eCSmJ0", "user_id":"@test_account:matrix.localhost","age":83203254}],"start":"s273_0_0_0_0_0_0_0_0","end":"t221-272_0_0_0_0_0_0_0_0"}
- Currently only textual messages are supported, i.e. events of type
m.room.message
and of message typem.text
. Therefore the response JSON is checked to be of event typem.room.message
and message typem.text
.- Other event types would be e.g.
m.room.name
andm.room.avatar
. - Other message types would be e.g.
m.emote
andm.image
- Other event types would be e.g.
- e.g.
- The CoAP response contains the sender and body of the message encoded as CBOR:
- e.g.
{'sender': '@test_account:matrix.localhost', 'body': 'Temp: 27.8'}
- To reduce the necessary packet size for the CoAP response, only the sender and the body of the last message are included.
- e.g.
If the HTTP request was unsuccessful, the CoAP response code is 4.00/BAD_REQUEST. The payload contains the HTTP response JSON (from Synapse) encoded as CBOR.
SendResource (/send
)
The SendResource enables the sending of a (text) message to a Matrix room via a CoAP request. It waits for CoAP
PUT requests (CoAPS is currently not supported by aiocoap on server-side).
These requests need to contain the CoAP option “Proxy-Uri” and (optionally) a custom CoAP option with ID 256. The
option with ID 256 is suggested by “MSC3079: Low Bandwidth CS API” and is required because RFC7252 defines no option
mapping for Authorization
headers (IDs 0-255 are reserved for IETF review). The plain access token must be used
in this CoAP option without a prefix (e.g. “Bearer “). If option 256 is not contained in the CoAP request, the
gateway will add a hardcoded access token for the HTTP request. The Proxy-Uri needs to contain the Matrix-Synapse
homeserver URL. It is recommended to send the CoAP request as message type NON-confirmable (e.g. in case of sensor
data being sent). Further a payload is required in the CoAP request which contains the message type (m.text
) and
the message body (the actual message). The information of the Proxy-Uri option and the playload are used to
construct the HTTP request to send a text message to a Matrix room (compliant with the Matrix CS-API).
The homeserver URL may be supplied in short or full format via the Proxy-Uri CoAP option:
- Short URL format:
http(s)://IP_domain:PORT/9/<room_id>/m.room.message/<txnId>
=> e.g.http://localhost:8008/9/!MauTnKoZRE%synapse.name/m.room.message/1234
- The port is optional and only necessary if non-standard HTTP/HTTPS ports are used.
- The
<txnId>
is optional and will be added by the gateway if it is not included in the request. Background is, that it may be hard to generate uniquetnxIds
on a microcontroller.- “The transaction ID for this event. Clients should generate an ID unique across requests with the same access token; it will be used by the server to ensure idempotency of requests.” cf. https://matrix.org/docs/spec/client_server/r0.6.1#put-matrix-client-r0-rooms-roomid-send-eventtype-txnid
- This short URL is defined in “MSC3079: Low Bandwidth Client-Server API” in “Appendix B: CoAP Path Enums” cf. https://github.com/matrix-org/matrix-doc/blob/7d20c1d9c19972fa63d1d9c124c3656928c28c29/proposals/3079-low-bandwidth-csapi.md#appendix-b-coap-path-enums
- Full URL format:
http(s)://IP_domain:PORT/_matrix/client/r0/rooms/<room_id>/send/m.room.message/<txnId>
=> e.g.http://localhost:8008/_matrix/client/r0/rooms/!MauTnKoZRE%synapse.name/send/m.room.message/123456789
- cf. https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-rooms-roomid-messages
To send a message to a Matrix room there needs to be a payload in the following format in the CoAP request (encoded as CBOR):
{"msgtype":"m.text", "body":"<message content>"}
- The message body can be freely chosen, but
"msgtype":"m.text"
is fixed. Currently only textual messages are supported.
- The message body can be freely chosen, but
Every CoAP request will be checked for the correct CoAP options and payload. If incorrect, a CoAP response with a code from class 4 (client error) will be sent (e.g. 4.00/BAD_REQUEST). If the options are ok, a HTTP request will be sent to the Synapse homeserver based on the supplied data.
This HTTP request can be successful or unsuccessful. If it was successful, the CoAP response code is 2.04/CREATED. The full payload of the HTTP response (sent by Synapse) receiving the last message looks like this:
{"event_id":"$mYfzjPJgmfZeTxgyIDMVMafsZlZZ2LZ7p5jPITZozn8"}
The CoAP response contains no payload.
If the HTTP request was unsuccessful, the CoAP response code is 4.00/BAD_REQUEST. The payload contains the HTTP response JSON (from Synapse) encoded as CBOR.
UnixTimeResource (/time
)
The UnixTimeResource provides the current Unix timestamp.
It can be used by the client to generate idempotent transaction IDs (txnId
) based on the timestamp for sending
messages to a Matrix room.
LogoutResource (logout
)
The LogoutResource enables the logout of a Matrix user at a specific Matrix-Synapse homeserver via a CoAP request.
It waits for CoAP POST requests (CoAPS is currently not supported by aiocoap on server-side).
These requests need to contain the CoAP option “Proxy-Uri” and a mandatory custom CoAP option with ID 256.
The option with ID 256 is suggested by “MSC3079: Low Bandwidth CS API” and is required because RFC7252 defines no
option mapping for Authorization
headers (IDs 0-255 are reserved for IETF review). The plain access token must be
used in this CoAP option without a prefix (e.g. “Bearer “). In case of the LogoutResource the access token needs to
be provided and the hardcoded access token cannot be used. This is in place to prevent the client to invalidate the
access token for other clients using the same (hardcoded) access token. The Proxy-Uri needs to contain the Matrix-Synapse
homeserver URL. It is recommended to send the CoAP request as message type CONfirmable, to be sure the client
receives the CoAP response (i.e. if the logout of the user was successful or not). The information of the
Proxy-Uri option is used to construct the HTTP request which conforms with the Matrix CS-API to logout an existing
user at the target Matrix-Synapse homeserver and therefore invalidate the provided access token.
The homeserver URL may be supplied in short or full format via the Proxy-Uri CoAP option:
- Short URL format:
http(s)://IP_domain:PORT/3
=> e.g.http://localhost:8008/3
- The port is optional and only necessary if non-standard HTTP/HTTPS ports are used.
- This short URL is defined in “MSC3079: Low Bandwidth Client-Server API” in “Appendix B: CoAP Path Enums”.
- cf. https://github.com/matrix-org/matrix-doc/blob/7d20c1d9c19972fa63d1d9c124c3656928c28c29/proposals/3079-low-bandwidth-csapi.md#appendix-b-coap-path-enums
- Full URL format:
http(s)://IP_domain:PORT/_matrix/client/r0/logout
=> e.g.http://localhost:8008/_matrix/client/r0/logout
- cf. https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-logout
- OPTIONAL URL format: http://localhost:8008/_matrix/client/r0/logout/all
- Invalidates all access tokens for a user, so that they can no longer be used for authorization.
/logout/all
is only possible via full URL, there is no short URL defined in MSC3079.- cf. https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-logout-all
To logout a Matrix user at a Synapse homeserver there is no payload required in the CoAP request.
Every CoAP request will be checked for the correct CoAP options. If incorrect, a CoAP response with a code from class 4 (client error) will be sent (e.g. 4.00/BAD_REQUEST). If the options are ok, a HTTP request will be sent to the Synapse homeserver based on the supplied data.
This HTTP request can be successful or unsuccessful. If it was successful, the CoAP response code is 2.04/CHANGED. The CoAP response contains no payload.
If the HTTP request was unsuccessful, the CoAP response code is 4.00/BAD_REQUEST. The payload contains the HTTP
response JSON (from Synapse) encoded as CBOR (e.g. {"errcode":"M_UNKNOWN_TOKEN","error":"Invalid macaroon passed.","soft_logout":false}
).
Future Work
- Adding application or transport layer security (currently the CoAP packets need to be sent in cleartext, incl.
the access token):
- Implement DTLS in aiocoap (server-side) or reimplement the CoMatrix gateway with Eclipse Californium 1
(which support DTLS)
- Information/issues regarding DTLS in Python and aiocoap:
- Add DTLS server support #98: https://github.com/chrysn/aiocoap/issues/98
- Discussion regarding DTLS in aiocoap: https://github.com/chrysn/aiocoap/issues/67
- Add credentials framework #97: https://github.com/chrysn/aiocoap/issues/97
- Information on python3-dtls: https://github.com/rbit/pydtls/issues/11#issuecomment-814747232
- Discussion regarding python3-dtls: https://github.com/chrysn/aiocoap/issues/230
- Information/issues regarding DTLS in Python and aiocoap:
- Implement OSCORE (application-layer protection of CoAP) 2
- Implement DTLS in aiocoap (server-side) or reimplement the CoMatrix gateway with Eclipse Californium 1
(which support DTLS)
- Evaluate if it’s feasible to manage homeserver data via gateway instead of CoMatrix client (currently the information is contained in the Proxy-Uri option). This would further reduce CoAP request packet sizes transferred via a constrained network.
- Return error codes instead of textual messages in error cases (e.g. missing option in CoAP request; NON Synapse error cases!)
- Add Python Unittests
- Evaluation: Add support for other CS-API eventtypes besides
m.room.message
(e.g.m.room.name
)?
Resources
- Matrix Client-Server API
- MSC3079: Low Bandwidth Client-Server API
- Blog announcement: https://matrix.org/blog/2021/04/01/this-week-in-matrix-2021-04-01#msc-status
- Pull request: https://github.com/matrix-org/matrix-doc/pull/3079
- Markdown file: https://github.com/matrix-org/matrix-doc/blob/7d20c1d9c19972fa63d1d9c124c3656928c28c29/proposals/3079-low-bandwidth-csapi.md