Skip to content
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

Clarify how third party invites work #1505

Merged
merged 7 commits into from
Aug 31, 2018

Conversation

turt2live
Copy link
Member

Rendered: see 'docs' commit status. This is highly recommended given the large sequence diagrams in the client-server spec.


This adds several diagrams to the Client-Server API about how invites are handled, including what the server is expected to do. This helps implementors know what they are supposed to do in the common cases, and infer where needed to get the more complex cases correct.

Although lacking in some areas, this is how third party invites work today.

A link to the now-improved client-server documentation for third party invites has been added to the server-server specification, alongside some documentation on how the /3pid/onbind endpoint works.

Fixes #1366
Fixes #1422

This adds several diagrams to the Client-Server API about how invites
are handled, including what the server is expected to do. This helps
implementors know what they are supposed to do in the common cases,
and infer where needed to get the more complex cases correct.

Although lacking in some areas, this is how third party invites work
today.

A link to the now-improved client-server documentation for third party
invites has been added to the server-server specification. The existing
server-server specification needed no further changes on the subject.

Fixes matrix-org#1366
@turt2live turt2live requested a review from a team August 13, 2018 23:02
@turt2live turt2live mentioned this pull request Aug 13, 2018
35 tasks
Copy link
Member

@dbkr dbkr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

otherwise this looks great!

@@ -56,7 +56,7 @@ paths:
get:
summary: Check whether a long-term public key is valid.
description: |-
Check whether a long-term public key is valid.
Check whether a long-term public key is valid. The request must be idempotent.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm - presumably this is saying it should always return the same data for a given key ID? It's slightly debatable whether idempotency strictly means this since it generally asserts that the operation will not be performed again, not that the resource doesn't change by other means in the intervening time. A GET request should always be idempotent since it should have no side effect.

Might be clearer to just say it should always be the same for a given key ID. :)

@turt2live
Copy link
Member Author

@dbkr please take a look at the updated wording. It's slightly different than your suggestion as I want to make sure people don't cache the request as invalid forever, even if the key becomes valid at a later date.

@turt2live turt2live requested a review from dbkr August 17, 2018 15:50
@dbkr
Copy link
Member

dbkr commented Aug 29, 2018

Actually, hang on - I thought the point of this endpoint was mostly to support key revocation, so the point of it is that it might later say a key is not valid that previously was? Also, in your suggestion of it going invalid -> valid at some point, this also would violate your condition of it always being the same?

@turt2live
Copy link
Member Author

If the key can become invalid at a later point then third party invites would be rejected by servers as they attempt to verify them.

The updated wording for checking for valid keys should support only the case of the server publishing new keys. If the IS were required to always say the same thing for a given request then someone could easily reserve a ton of keys on the server that it then has to consider as invalid forever. With the condition that it has to consider a key that exists as (in)valid forever, the server isn't open to being abused.

@dbkr
Copy link
Member

dbkr commented Aug 29, 2018

Hmm, the thing is that the intro for that section says:

is, the In the event of key compromise, the identity service may revoke any of its keys. An HTTP API is offered to get public keys, and check whether a particular key is valid.

Which surely is saying it exists so the ISes can revoke keys? I was afraid it might be that subsequent servers validating the 3pid invite would get a different result - this seems a bit broken? Not sure how best to untangle this mess.

@turt2live
Copy link
Member Author

turt2live commented Aug 29, 2018

The ability to revoke keys is important. I'm sure there's a hole somewhere in this suggestion, but how does altering the auth rules slightly sound? The auth rules could consider the age of the event (by depth or ts or something) as a heuristic for "this was probably valid at one point, but it's so old now that an invalid key isn't unexpected". It should still check the key, and maybe just not send the event to clients if the key is invalid and old, but otherwise accept it?

This does have the problem where if someone does a 3rd party invite and moments later the IS decides it needs to rotate keys - the fresh invite would be considered as invalid by a subset of servers and reject it.

@dbkr
Copy link
Member

dbkr commented Aug 29, 2018

I think the hole may be that a server can come up with an event supposedly from an old fork (but that actually it's just made up) referencing an old 3pid invite with a revoked key, and this will always be accepted. I was about to question why the validity endpoint doesn't return a not-before & not-after like an x.509 cert, but I think this applies here too in that whatever server is making the join can just pick whatever time at which the key was valid.

Might be good to get @erikjohnston / @richvdh 's thoughts here. There's a certain argument for speccing what we have and trying to unravel this later, even if that means something like saying you actually can't ever revoke keys (which presumably is currently the case).

@turt2live turt2live changed the title Clarify how third party invites works Clarify how third party invites work Aug 30, 2018
| | | (Federation) Emit m.room.member for invite | | |
| | |----------------------------------------------->| | |
| | | | | |
| | | | Accept event | |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is "accept event" drawn in for m.room.member but not m.room.third_party_invite? I'm not sure it adds any value here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a subtle thing where the event in this case must be accepted, which is why it is annotated specifically.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hrm. I'm not sure that this arrow shows that clearly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll just take the arrow out - the surrounding text seems to cover the subtly well enough imo.

| | | | | | |
| | |<------------------ | | |
| | | | | |
| | | (Federation) Emit m.room.member for invite | | |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does there not need to be a send_join dance before this can happen?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, the user doesn't join. The exchange of the 3rd party invite produces a real invite, which just has to be broadcast to all the other servers

@richvdh
Copy link
Member

richvdh commented Aug 30, 2018

I'm not quite sure I understand the discussion here. If the IS wants to revoke its key, it stops replying yes to "/isvalid". Does that break something?

There's a certain argument for speccing what we have and trying to unravel this later,

+1 to that, I fear

@turt2live
Copy link
Member Author

I'm not quite sure I understand the discussion here. If the IS wants to revoke its key, it stops replying yes to "/isvalid". Does that break something?

Yes, otherwise valid 3rd party invite events get rejected by servers that weren't lucky enough to check the event when the key was valid.

@richvdh
Copy link
Member

richvdh commented Aug 30, 2018

Yes, otherwise valid 3rd party invite events get rejected by servers that weren't lucky enough to check the event when the key was valid.

Oh right. I hadn't grokked that other HSes needed to verify the signature at the point they see the 3pid invite - the only time 'isvalid' is mentioned in the spec is at the point H1 turns it into a normal invite. TBH this sounds like a questionable decision, but it's probably not worth debating at this point.

Given what you say, I agree that the correct decision is to spec it as-is, even if that means that keys can't be revoked, and then fix it asap.

@@ -102,26 +141,85 @@ No other homeservers may reject the joining of the room on the basis of
the room. They may, however, indicate to their clients that a member's'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

member's'

@turt2live
Copy link
Member Author

@richvdh and/or @dbkr - please take a look. I've opened https://github.com/matrix-org/matrix-doc/issues/1633 to cover the case of identity services not actually being able to revoke their keys.

Copy link
Member

@richvdh richvdh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, it looks sensible to me.

@turt2live turt2live merged commit 38ae166 into matrix-org:master Aug 31, 2018
@turt2live turt2live deleted the travis/general/3pid_invite branch August 31, 2018 14:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants