Page MenuHomePhabricator

[Tunnelbroker] Create gRPC service for emitting messages to devices
ClosedPublic

Authored by jon on Apr 13 2023, 9:50 AM.
Tags
None
Referenced Files
Unknown Object (File)
Sun, May 19, 8:25 AM
Unknown Object (File)
Sun, May 19, 8:25 AM
Unknown Object (File)
Sun, May 19, 8:25 AM
Unknown Object (File)
Sun, May 19, 8:25 AM
Unknown Object (File)
Sun, May 19, 8:25 AM
Unknown Object (File)
Sun, May 19, 8:25 AM
Unknown Object (File)
Sun, May 19, 8:25 AM
Unknown Object (File)
Sun, May 19, 8:24 AM
Subscribers

Details

Summary

Establish how identity will issue refreshUserKeys rpc to tunnelbroker.

https://linear.app/comm/issue/ENG-3680

Test Plan

N/A, this is more about api design than implementation

Diff Detail

Repository
rCOMM Comm
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

ashoat requested changes to this revision.Apr 14 2023, 5:58 AM

Can you explain a little bit more these two decisions:

  1. Decision to create a separate service specifically for service A to talk to service B, versus just a unified service definition for service B
  2. Decision to have a specific RPC for issuing a specific kind of message, versus just have a generic RPC for issuing any message

I think I would prefer to see TunnelbrokerService with a single RPC that takes targetDeviceID and generic message

This revision now requires changes to proceed.Apr 14 2023, 5:58 AM

My proposal: single TunnelbrokerService with a single RPC that takes targetDeviceID and generic message (API will probably expand in the future though)

Pros of my proposal:

  • Better "separation of concerns"... Tunnelbroker does not need to concern itself with the contents of messages
  • If we ever need some other internal service to send a message via Tunnelbroker, we won't need to update the .proto

Cons of my proposal:

  • It shunts responsibility for checking validity of messages to clients. This can be done with cryptographic signatures, but it may be slightly more complicated
  • It might complicate efforts to control spam / malicious actors in the future

Decision to create a separate service specifically for service A to talk to service B, versus just a unified service definition for service B

Since tunnelbroker needs to verify that it's the official identity service, I wanted a service specific to just those two. Especially if the services will require something like a token to authenticate.

Decision to have a specific RPC for issuing a specific kind of message, versus just have a generic RPC for issuing any message

My preference for type safety. If it compiles, it usually runs without issue. Just want to avoid a lot of "stringly" typed API.

I think I would prefer to see TunnelbrokerService with a single RPC that takes targetDeviceID and generic message

That feels like it's trying to work around protobuf messages, I don't see a clear advantage. It's also not as ergonomic in rust as just consuming the generated bindings for gRPC.

ashoat requested changes to this revision.Apr 14 2023, 6:37 AM

Our messages got crossed when you re-requested review I think, passing back to you for my more recent message where I discuss tradeoffs

My preference for type safety. If it compiles, it usually runs without issue. Just want to avoid a lot of "stringly" typed API.

Shouldn't matter if the message is opaque to the Tunnelbroker service

That feels like it's trying to work around protobuf messages, I don't see a clear advantage. It's also not as ergonomic in rust as just consuming the generated bindings for gRPC.

I put the advantages in my more recent comment

Since tunnelbroker needs to verify that it's the official identity service, I wanted a service specific to just those two. Especially if the services will require something like a token to authenticate.

This is the important point I think – can you expand on some of the alternative approaches we could use here? How about having clients verify the messages? How would that look like?

This revision now requires changes to proceed.Apr 14 2023, 6:37 AM

If we ever need some other internal service to send a message via Tunnelbroker, we won't need to update the .proto

I don't think this is a big win. Protobuf was designed with the goal of dealing with evolving APIs. I see changing a .proto as a good thing for API management, as then you at least get compilation errors if an API has changed.

This is the important point I think – can you expand on some of the alternative approaches we could use here?

I would like to keep discussion of that centralized to https://linear.app/comm/issue/ENG-3677#comment-439904f5

How about having clients verify the messages? How would that look like?

This service isn't concerned with how tunnelbroker delivers the message to the user, and I think it's out-of-scope for this diff.

But to try and answer the question: the sender (tunnelbroker) will be able to have the clients connect through wss://, which should at least verify the authenticity of tunnelbroker. This isn't as strong as verifying individual messages, but it's usually "good enough". As part of initializing a session with tunnelbroker, tunnelbroker will be authenticating the client by verifying the access token through identity service. I created https://linear.app/comm/issue/ENG-3688/have-tunnelbroker-authenticate-connecting-devices to discuss this further.

If you're asking about verifying individual messages, this would probably be a better question of annuay as this is outside my expertise.

Shouldn't matter if the message is opaque to the Tunnelbroker service

Just doesn't feel right, that an error in another service will propagate through tunnelbroker. I understand where you're coming from, as tunnelbroker doesn't strictly need to know the contents, but it just still feels weird from an API standpoint.

But as a "broker", I understand your point.

Having identity service be aware of the "websocket payload", also couples identity service to being aware of the websocket implementation. Which would mean that the client messages would need to reside in a shared location (not necessarily a bad thing, but it is an implication of making the messages opaque).

Having identity service be aware of the "websocket payload", also couples identity service to being aware of the websocket implementation. Which would mean that the client messages would need to reside in a shared location (not necessarily a bad thing, but it is an implication of making the messages opaque).

Yeah, that makes sense.

If you're asking about verifying individual messages, this would probably be a better question of annuay as this is outside my expertise.

Yeah that's what I'm getting at. As an example approach, what if identity service has some certificate vended by a CA that the client trusts, and identity service signs the request for more one-time keys?

One nice property of this approach is that we can start by doing it without the signature, and then add the signature later when we're ready.

Just doesn't feel right, that an error in another service will propagate through tunnelbroker. I understand where you're coming from, as tunnelbroker doesn't strictly need to know the contents, but it just still feels weird from an API standpoint.

But as a "broker", I understand your point.

That's the core of my point... Tunnelbroker is already complicated enough as is. I'd like to keep a "separation of concerns" where understanding the contents of the payload is outside the scope of the Tunnelbroker service.

jon retitled this revision from [Identity/Tunnelbroker] Create refresh user keys protobuf RPC to [Tunnelbroker] Create gRPC service for emitting messages to devices.Apr 17 2023, 5:16 PM
shared/protos/tunnelbroker.proto
10 ↗(On Diff #25243)

Couldn't think of a better name. It could be just Tunnelbroker, but I would like to name it something which makes it specific to services. And ServicesTunnelbrokerService just sounds repetitive.

Looks good, just have some concerns about naming and comments

Going forward, it would be great if you could aim for consistency in capitalization so I don't need to leave nits on your diffs. You capitalize "Tunnelbroker" and "Comm services" inconsistently throughout the diff

Please address all comments before landing

shared/protos/tunnelbroker.proto
5 ↗(On Diff #25245)

Capitalize "Comm"

6 ↗(On Diff #25245)

Capitalize "Tunnelbroker"

Don't capitalize "services"

9 ↗(On Diff #25245)

Capitalize RPC

RPC = Remote Procedure Call, there's no need to repeat the word "call"

10 ↗(On Diff #25245)

Can we just call it Tunnelbroker?

23 ↗(On Diff #25245)

This is a comma splice; see proposed edit

This revision is now accepted and ready to land.Apr 18 2023, 5:29 AM
jon marked 5 inline comments as done.

Address feedback

This was rebased on top of deleting the old tunnelbroker.proto. Which is why I had it as something else originally.

shared/protos/tunnelbroker.proto
9 ↗(On Diff #25245)

used "protocol" instead.

10 ↗(On Diff #25245)

Yea, when I first up the the diff, the legacy file still existed. I rebased this on top of that work, so now that's possible.

ashoat added inline comments.
shared/protos/tunnelbroker.proto
6 ↗(On Diff #25263)

Capitalize Tunnelbroker

14 ↗(On Diff #25263)

Capitalize Tunnelbroker