You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
274 lines
11 KiB
Markdown
274 lines
11 KiB
Markdown
# Grammars for identifiers in the Matrix protocol
|
|
|
|
## Background
|
|
|
|
Matrix uses client- or server-generated identifiers in a number of
|
|
places. Historically the grammars for these have been underspecified, which
|
|
leads to confusion about what is or is not a valid identifier with the
|
|
possibility of incompatability between implementations.
|
|
|
|
This proposal presents tightly-specified grammars for a number of
|
|
identifiers.
|
|
|
|
## Common Identifiers
|
|
|
|
[Spec](https://matrix.org/docs/spec/appendices.html#common-identifier-format)
|
|
|
|
Proposal:
|
|
|
|
> `localpart` may not include `:`. When parsing a Common Identifier, it should
|
|
> be split at the *leftmost* `:`.
|
|
|
|
Rationale: server names may contain multiple `:`s (think IPv6 literals), so the
|
|
first colon is the only sane place to split them. This is a Known Thing, but I
|
|
don't think we spell it out anywhere in the spec.
|
|
|
|
## User IDs
|
|
|
|
User IDs are
|
|
[well-specified](https://matrix.org/docs/spec/appendices.html#user-identifiers),
|
|
however we should consider dropping `/` from the list of allowed characters,
|
|
because HTTP proxies might rewrite
|
|
`/_matrix/client/r0/profile/@foo%25bar:matrix.org/displayname` to
|
|
`/_matrix/client/r0/profile/@foo/bar:matrix.org/displayname`, messing things
|
|
up.
|
|
|
|
History: `/` was introduced with the intention of acting as a hierarchical
|
|
namespacing character, particularly with consideration to the gitter protocol
|
|
which uses it as a hierarchical separator. However, this was not as effective
|
|
as hoped because `@foo/bar:example.com` looks like the ID is partitioned into
|
|
`@foo` and `bar:example.com`.
|
|
|
|
Proposal:
|
|
|
|
> Remove `/` from the list of allowed characters in User IDs.
|
|
|
|
`/` will of course be maintained under the grammar of "historical user
|
|
IDs". Sorting out that mess is a longer-term project.
|
|
|
|
## Room IDs and Event IDs
|
|
|
|
[Issue](https://github.com/matrix-org/matrix-doc/issues/667)
|
|
[Spec](https://matrix.org/docs/spec/appendices.html#room-ids-and-event-ids)
|
|
|
|
These currently have similar formats, though it is likely that event ids will
|
|
be replaced with something else due to
|
|
[#1127](https://github.com/matrix-org/matrix-doc/issues/1127).
|
|
|
|
Currently they are both specified as ``?opaque_id:domain``, without clues as to
|
|
what the opaque_id should be.
|
|
|
|
Synapse uses: `[A-Za-z]{18}`.
|
|
[Dendrite](https://github.com/matrix-org/dendrite/blob/b71d922/src/github.com/matrix-org/dendrite/clientapi/routing/createroom.go#L125)
|
|
uses (I think) `[A-Za-z0-9]{16}` via
|
|
[json.go](https://github.com/matrix-org/util/blob/master/json.go#L185). However,
|
|
some server implementations/forks are known to generate event IDs (and possibly
|
|
room IDs) using a wide alphabet, which means that there exist rooms that
|
|
include unusual event IDs.
|
|
|
|
Proposal:
|
|
|
|
> The opaque_id part must not be empty, and must consist entirely of the
|
|
> characters `[0-9a-zA-Z.=_-]`.
|
|
>
|
|
> The total length (including sigil and domain) must not exceed 255 characters.
|
|
>
|
|
> This is only enforced for v2 rooms - servers and clients wishing to support
|
|
> v1 rooms should be more tolerant.
|
|
|
|
|
|
## Key IDs (for federation, e2e, and identity servers)
|
|
|
|
These are always of the form `<algorithm>:<tok>`.
|
|
|
|
Valid algorithms are defined at
|
|
https://matrix.org/docs/spec/client_server/unstable.html#key-algorithms, though
|
|
we should define the alphabet for future algorithms.
|
|
|
|
Proposal:
|
|
|
|
> Future algorithm identifiers will be assigned from the alphabet `[a-z0-9_.]`
|
|
> and will be at most 31 characters in length.
|
|
|
|
For federation keys,
|
|
[Synapse](https://github.com/matrix-org/synapse/blob/74854a97191191b08101821753c2672efc2a65fd/synapse/config/key.py#L159)
|
|
generates key ids as `ed25519:a_[A-Za-z]{4}`, though an HS admin can configure
|
|
them manually to be anything without whitespace.
|
|
|
|
Key IDs end up in an Authorization header which looks like `X-Matrix
|
|
origin=origin.example.com,key="keyId",sig="ABCDEF..."`. The Synapse
|
|
implementation splits on `,` and `=` without regard to quoting so this
|
|
currently precludes the use of `,` or `=` in a key ID.
|
|
|
|
For e2e, device keys have a `tok` corresponding to the device id, whilst
|
|
one-time keys are generated by libolm, which uses a base64-encoded 32-bit int, ie
|
|
`[A-Za-z0-9+/]{6}`.
|
|
|
|
A key ID needs to be unique over the lifetime of the server (for federation) or
|
|
the device (for e2e). However, they are used fairly widely, so making them long
|
|
is unattractive as they could significantly increase the amount of data being
|
|
transmitted. Let's limit the 'tok' part of the key to 31 characters too.
|
|
|
|
Proposal:
|
|
|
|
> Key IDs use the following BNF grammar:
|
|
>
|
|
> ```
|
|
> key_id = algorithm ":" tok
|
|
>
|
|
> algorithm = 1*31 alg_chars
|
|
>
|
|
> tok = 1*31 tok_chars
|
|
>
|
|
> alg_chars = %x61-7a / %30-39 / "_" / "."
|
|
> ; a-z 0-9 _ .
|
|
>
|
|
> tok_chars = ALPHA / DIGIT / "." / "=" / "_" / "-"
|
|
> ; A-Z a-z 0-9 . = _ -
|
|
> ```
|
|
>
|
|
|
|
Note that enforcing this grammar will mean:
|
|
|
|
* Making sure that synapse handles "=" characters in key IDs (easy).
|
|
|
|
* Making libolm not put + and / characters in key IDs (easy enough, but there
|
|
will be a bunch of malformed unique keys out there in the wild. Possibly they
|
|
would just get thrown away. Servers may need to continue to tolerate `+` and
|
|
`/` in e2e keys for a while.)
|
|
|
|
## Opaque IDs
|
|
|
|
[Issue](https://github.com/matrix-org/matrix-doc/issues/666)
|
|
|
|
This is a class of identifier types where nobody is really meant to parse any
|
|
part of the ID - they are just unique identifiers (with varying scopes of
|
|
uniqueness). See below for discussion on what is currently in use.
|
|
|
|
I propose to specify the almost the same grammar for all of these, for
|
|
simplicity and consistency.
|
|
|
|
Proposal:
|
|
|
|
> Opaque IDs must be strings consisting entirely of the characters
|
|
> `[0-9a-zA-Z.=_-]`. Their length must not exceed 255 characters and they must
|
|
> not be empty.
|
|
|
|
For almost all of the current implementations I have looked at (listed below),
|
|
the grammar above is a superset of the generated identifiers, and a subset of
|
|
the understood identifiers. There should therefore be no
|
|
backwards-compatibility problems with its introduction.
|
|
|
|
The exception is transaction IDs generated by some clients. I think that we'll
|
|
just have to fix those clients and accept that old versions may not work with
|
|
future servers.
|
|
|
|
### Call IDs
|
|
|
|
[Spec](https://matrix.org/docs/spec/client_server/unstable.html#m-call-invite)
|
|
|
|
These are only used within the body of `m.call.*` events, as far as I am
|
|
aware. They should be unique within the lifetime of a room. (Some
|
|
implementations currently treat them as globally unique, but that is considered
|
|
an implementation bug.)
|
|
|
|
[matrix-js-sdk](https://github.com/matrix-org/matrix-js-sdk/blob/4d310cd4618db4e98a8e6b5eb812480102ee4dee/src/webrtc/call.js#L72) uses `c[0-9.]{32}`.
|
|
[matrix-android-sdk](https://github.com/matrix-org/matrix-android-sdk/blob/5c6f785e53632e7b6fb3f3859a90c3d85b040e7f/matrix-sdk/src/main/java/org/matrix/androidsdk/call/MXWebRtcCall.java#L221) uses `c[0-9]{13}`.
|
|
|
|
Additional proposal:
|
|
|
|
> Call IDs should be long enough to make clashes unlikely.
|
|
|
|
### Media IDs
|
|
|
|
[Spec](https://matrix.org/docs/spec/client_server/r0.3.0.html#id67)
|
|
|
|
These are generated by the server on upload, and then embedded in `mxc://` URIs
|
|
and used in the C-S API and the S-S API.
|
|
|
|
They must be URI-safe to be sensibly embedded in `mxc://` URIs.
|
|
|
|
[Synapse](https://github.com/matrix-org/synapse/blob/74854a97191191b08101821753c2672efc2a65fd/synapse/rest/media/v1/media_repository.py#L153)
|
|
uses `[A-Za-z]{24}`, though it also uses `[0-9A-Za-z_-]{27}` for
|
|
[URL
|
|
previews](https://github.com/matrix-org/synapse/blob/74854a97191191b08101821753c2672efc2a65fd/synapse/rest/media/v1/preview_url_resource.py#L285).
|
|
|
|
[matrix-media-repo](https://github.com/turt2live/matrix-media-repo/blob/539f25ee75ba6cdbb0410314b29978f4b8b1d7fe/src/github.com/turt2live/matrix-media-repo/controllers/upload_controller/upload_controller.go#L50)
|
|
uses `[A-Za-z0-9]{32}`, via [random.go](https://github.com/turt2live/matrix-media-repo/blob/539f25ee75ba6cdbb0410314b29978f4b8b1d7fe/src/github.com/turt2live/matrix-media-repo/util/random.go#L18-L27).
|
|
|
|
### Filter IDs
|
|
|
|
[Spec](https://matrix.org/docs/spec/client_server/unstable.html#post-matrix-client-r0-user-userid-filter)
|
|
|
|
These are generated by the server and then used in the CS API. They are only
|
|
required to be unique for a given user. `{` is already forbidden by the spec.
|
|
|
|
[Synapse](https://github.com/matrix-org/synapse/blob/74854a97191191b08101821753c2672efc2a65fd/synapse/storage/filtering.py#L70-L73)
|
|
uses a stringified int.
|
|
|
|
### Auth Session IDs
|
|
|
|
[Spec](https://matrix.org/docs/spec/client_server/r0.3.0.html#user-interactive-authentication-api)
|
|
|
|
These are generated by the server during auth, and then used in the CS
|
|
API. However, they need to be unique for a given server.
|
|
|
|
[Synapse](https://github.com/matrix-org/synapse/blob/74854a97191191b08101821753c2672efc2a65fd/synapse/handlers/auth.py#L494) uses `[A-Za-z]{24}`.
|
|
|
|
### Transaction IDs (for federation)
|
|
|
|
[Spec](https://matrix.org/docs/spec/server_server/unstable.html#put-matrix-federation-v1-send-txnid)
|
|
|
|
Generated by sending server. Needs to be unique for a given pair of servers.
|
|
|
|
[Synapse](https://github.com/matrix-org/synapse/blob/74854a97191191b08101821753c2672efc2a65fd/synapse/federation/transaction_queue.py#L593) uses a stringified int and accepts pretty much anything.
|
|
|
|
### Transaction IDs (for C-S API)
|
|
|
|
[Spec](https://matrix.org/docs/spec/client_server/unstable.html#put-matrix-client-r0-rooms-roomid-send-eventtype-txnid)
|
|
|
|
These are generated by the client. They only need to be unique within the
|
|
context of a single access_token/device.
|
|
|
|
Synapse doesn't appear to do any sanity-checking here currently.
|
|
|
|
[matrix-js-sdk](https://github.com/matrix-org/matrix-js-sdk/blob/c6b500bc09994ab5924ef8aab9bd10fc7ded5dae/src/base-apis.js#L123)
|
|
uses `m[0-9]{13}.[0-9]{1,}`.
|
|
[matrix-android-sdk](https://github.com/matrix-org/matrix-android-sdk/blob/088414fb187cae341690c3a01493b87d97f0169f/matrix-sdk/src/main/java/org/matrix/androidsdk/rest/model/Event.java#L503)
|
|
uses a room ID plus a timestamp, hence kinda could be anything, but certainly
|
|
will include a `!`.
|
|
|
|
### Device IDs
|
|
|
|
[Spec](https://matrix.org/docs/spec/client_server/unstable.html#relationship-between-access-tokens-and-devices)
|
|
|
|
These are normally generated by the server on login. It's possible for clients
|
|
to present their own device_ids, but we're not aware of this feature being
|
|
widely used.
|
|
|
|
They are used between users and across federation for E2E and to-device
|
|
messages. They need to be unique for a particular user. They also appear in key
|
|
IDs and must therefore be a subset of that grammar.
|
|
|
|
[Synapse](https://github.com/matrix-org/synapse/blob/74854a97191191b08101821753c2672efc2a65fd/synapse/handlers/device.py#L89)
|
|
generates device IDs with `[A-Z]{10}`. It appears to do little sanity-checking
|
|
of client-generated device IDs currently.
|
|
|
|
Additional proposal:
|
|
|
|
> Device IDs must not exceed 31 characters in length.
|
|
|
|
### Message IDs
|
|
|
|
These are used in the server-server API for
|
|
[Send-to-device messaging](https://matrix.org/docs/spec/server_server/unstable.html#send-to-device-messaging).
|
|
|
|
Synapse uses `[A-Za-z]{16}`, and accepts anything that fits in a postgres TEXT
|
|
field. Ref: [devicemessage.py](https://github.com/matrix-org/synapse/blob/74854a97191191b08101821753c2672efc2a65fd/synapse/handlers/devicemessage.py#L102).
|
|
|
|
|
|
## Room Aliases
|
|
|
|
These are a complex topic and are discussed in [MSC
|
|
1608](https://github.com/matrix-org/matrix-doc/issues/1608).
|