-
Notifications
You must be signed in to change notification settings - Fork 412
MSC4243: User ID localparts as Account Keys #4243
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implementation requirements:
- Server (preferably multiple)
- Client with account key awareness (preferably multiple)
- Complement tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These implementation requirements are a bit light. Given that there is no security disclosure happening related to this MSC, could we please be a little more considerate with rolling this out vs V12?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tbh, why are implementation requirements this weak for a mainline room version?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do prefer multiple implementations for changes like this - I've clarified the comment.
Discussed over chat: this MSC does not define a (stable) room version like v12 - it describes a component of a possible future room version. The testing is more important for the future version's MSC when all the bundled changes are included in a "real" room version.
This means `foo.com` will not get events in the room routed to them, but a victim server `bar.com` will instead be pushed events as a form of amplification attack. | ||
Servers MUST have a global backoff timer per-domain to ensure that attackers cannot repeatedly join users with fake domains to popular rooms to cause amplification attacks. | ||
|
||
### Security Considerations |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to be able to determine the origin of events that are maliciously using another domain that does not claim ownership of the account key. Otherwise there will be no way to ban the server sending these events.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Particularly if selective /send
or smart use of backfill is being used to evade detection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See also #4243 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is precisely why the proposal links to policy servers for moderation. We may need even stronger guarantees here (e.g policy server signatures and an auth rule which drops events with an invalid policy server signature) for certain use cases else events can be spammed into the graph. This can admittedly still happen today even with our origin system so it doesn't really feel like this materially makes this worse as it stands.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Policy servers are not a done deal yet, and even with the requirement to have events signed by one, if multiple policy servers are involved in a room's access control then it's still not clear how we would go about determining origin in this proposal.
This can admittedly still happen today even with our origin system so it doesn't really feel like this materially makes this worse as it stands.
Entrenching and complicating the issue by ignoring it over successive proposals does make this materially worse. Removing the origin makes this worse.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunatly this would make changes to the user ID format a hard requirement (to include the public key and not the domain), and clients would need to be aware of the change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added this to the "Dependencies" section:
The MSC may depend on MSC4284: Policy Servers to ensure that events sent
by invalid domains can be moderated safely.
Therefore, in answer to your original comment:
determine the origin of events that are maliciously using another domain that does not claim ownership of the account key.
The answer would be "the policy server does this check and refuses to sign the event if the domain is not valid".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think room admins should be notaries. I think there still needs to be a role of other notaries, the role of notaries is allowing clients to verify ownership of the domain for the purpose of presentation to the user, not for authorizing events or verifying their authenticity.
To be explicit, the role for adding keys in rooms is for declaring the authorized participant keys and the routing information for those keys. Separately servers then need to verify servers claim ownership of the key before clients can show the domain to users. So verifying ownership of domains becomes purely an identity problem rather than a crossed concern with validity and authorisation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's an important upside of account keys (compared to server keys) that is not addressed by the current thread, which is that account keys open the possibility to replace them with user-owned keys in the future; perhaps even merging them with some existing user-owned keys such as the MSK. This would make the protocol overall better integrated and allow for end-to-end authenticity of events, rather than the present situation where users (and their clients) are second class citizens.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can and should have both.
This proposal tries to avoid clients needing to know or care about these account keys. As such, it takes steps to replace the account key | ||
with the account name in the user ID where possible in event JSON sent to clients/bots/bridges/appservices. For a given account key `@l8Hft5qXKn1vfHrg3p4+W8gELQVo8N13JkluMfmn2sQ:matrix.org`: | ||
- The server should replace the account key with the account name in the user ID for verified keys. E.g `@kegan:matrix.org`. | ||
- The server should replace the `domain` of the user ID with "invalid" for unverified keys. E.g `@l8Hft5qXKn1vfHrg3p4+W8gELQVo8N13JkluMfmn2sQ:invalid`. | ||
- The server should prefix the account key with `_` when the domain is unreachable. E.g `@_l8Hft5qXKn1vfHrg3p4+W8gELQVo8N13JkluMfmn2sQ:matrix.org`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be more consistent to never show the account name in the sender
and always use the account key user ID?
The account name could instead be annotated in the unsigned portion of a user's membership event. In similar vein to profile information.
but this is also possible today with server collusion. | ||
|
||
|
||
### Alternatives |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tada #4345
This will need a second part to add account keys.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
``` | ||
|
||
Clients can then use the `unsigned.account.key` field as an unchanging identifier for the sender of the event, akin to how they use the `sender` field today. | ||
A later room version can then: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would this be tied to a room version, rather than (say) a release of the C-S API?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it could, I didn't think of that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems to me it would fit more naturally in a C-S API release than anything to do with room versions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As long as users are an entirely orthogonal concept to rooms, this makes sense. But consider that eventually we want to change that, by tying users (as room members) to rooms cryptographically (as in e.g. MSC3917). Then it's no longer interchangeable whether @l8Hft5qXKn1vfHrg3p4+W8gELQVo8N13JkluMfmn2sQ:matrix.org
is a member of the room or whether it's @kegan:matrix.org
; it's no longer just a cosmetic translation and rooms listing one or the other are fundamentally different, with different semantics. Given that room versions are what determines room semantics, I don't see how we'll be able to avoid tying it to the room version.
|
||
#### Impacts on restricted rooms | ||
|
||
Rooms with the `restricted` join rule are impacted because we no longer want to check that the server domain signed the event. Thankfully, the `join_authorised_via_users_server` field is a _user ID_, so we can simply extract the account key from the localpart of the user ID and verify that there is a signature with that key. For clarity, auth rules are modified like so: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we no longer want to check that the server domain signed the event.
Could you explain this in more detail, possibly with links to the existing spec, for those of us who have paged out how restricted rooms work?
- The endpoint `/_matrix/federation/v2/ban` is `/_matrix/federation/v2/org.matrix.12.4243.ban`. | ||
- The endpoint `/_matrix/federation/v1/query/accounts` is `/_matrix/federation/v1/query/org.matrix.12.4243.accounts` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/_matrix/federation/unstable/org.matrix.msc4243/ban
and /_matrix/federation/unstable/org.matrix.msc4243/query/accounts
would be conventional
"EgdGx+0oy/9IX5k7tCobr0JoiwMvmmQ8sDOVlZODh/o": { | ||
"account_name": "matthew", | ||
"domain": "matrix.org", | ||
"signatures": { ... } | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the only way that the MSC allows a server to associate the account name with a key? What if it tries to associate multiple keys with one account? Is that Ok?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is the only place where the association with an account name is made. It is valid for servers to associate multiple keys with one account, though not encouraged because it reduces performance as every unique key for that user needs to be queried, rather than just the one key. Nothing fundamentally breaks by allowing this as far as I can tell because:
- we still resolve to the account name user ID for operations which need the actual account (e.g E2EE)
- malicious servers which try to evade bans can already do this by changing their account name. This would allow them to mint a new account key to do the same thing.
The reasons why servers may want to associate multiple keys with one account is for privacy, as there is useful metadata in knowing key X is in this set of rooms and therefore is one identity in the network.
- User IDs as they are today are direct personal data. For [GDPR](https://github.com/matrix-org/matrix-spec/issues/342) | ||
reasons we would like to be able to remove direct personal data from the immutable append-only DAG. This proposal | ||
replaces user IDs with indirect personal data. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not work for single user instances, since their domain is still part of all mxids in this proposal.
- As user IDs are user controlled, spammers set their localpart to abusive messages in order to harass and intimidate others. Redactions | ||
do not remove the user ID so these messages persist in the room. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly to https://github.com/matrix-org/matrix-spec-proposals/pull/4243/files#r2336511177, abusive domain names are still persisted
- By signing event JSON, the account key claims to belong to a particular domain. This is embedded into the DAG. | ||
- By responding to the endpoint with that account key, the domain claims to own that particular account key. This is not embedded into the DAG so not all servers will agree on this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thought experiment: an account key K
signs two events, one with @K:S1
as the sender, another with @K:S2
as the sender. S1
and S2
are maliciously cooperating and they both return K
when queried for its account.
Is there anything stopping this equivocation? I believe not, so is this a problem in any way? This demonstrates we can't really consider the full account key user ID to be the principal; only the account key itself is the principal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you're saying in the case where all of (S1, S2, K) are compromised, you can mint user IDs which map to the same key? Well... obviously yes? If all your inputs are malicious, this is possible in basically every design.
Remember, the account key K
must sign attestations stating "I belong to domain S1" and "I belong to domain S2" in the /accounts
response, thus the malicious entity controlling S1
and S2
must also control K
for your scenario to work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess your point is more that the user ID format introduces a namespace of domain names that the key can use to pick their identifier. If the identifier was just the key, you would have to change the key to change the identifier, whereas in your scenario this isn't true.
Rendered