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

Explore CallCredentials and SessionCredentials for GRPC #230

Closed
Tracked by #228
tegefaulkes opened this issue Aug 18, 2021 · 13 comments
Closed
Tracked by #228

Explore CallCredentials and SessionCredentials for GRPC #230

tegefaulkes opened this issue Aug 18, 2021 · 13 comments
Assignees
Labels
development Standard development security Security risk

Comments

@tegefaulkes
Copy link
Contributor

tegefaulkes commented Aug 18, 2021

Specification

Check the robustness of the usage of call credentials and SessionCredentials.

Additional context

Reference https://gitlab.com/MatrixAI/Engineering/Polykey/js-polykey/-/merge_requests/207#note_652476363 and https://gitlab.com/MatrixAI/Engineering/Polykey/js-polykey/-/merge_requests/207#note_652440417

An MR has been created for this issue.
https://gitlab.com/MatrixAI/Engineering/Polykey/js-polykey/-/merge_requests/210

Tasks

  1. ...
  2. ...
  3. ...
@tegefaulkes tegefaulkes changed the title Check the robustness of the usage of call credentials and SessionCredentials: https://gitlab.com/MatrixAI/Engineering/Polykey/js-polykey/-/merge_requests/207#note_652476363 and https://gitlab.com/MatrixAI/Engineering/Polykey/js-polykey/-/merge_requests/207#note_652440417 Check the robustness of the usage of call credentials and SessionCredentials Aug 18, 2021
@tegefaulkes tegefaulkes added the development Standard development label Aug 18, 2021
@tegefaulkes tegefaulkes changed the title Check the robustness of the usage of call credentials and SessionCredentials Explore CallCredentials and SessionCredentials for GRPC Aug 18, 2021
@CMCDragonkai
Copy link
Member

@DrFacepalm can you take over this issue this week/weekend?

@DrFacepalm
Copy link
Contributor

Taking a look, im not too sure what we'd prefer here.

image

We have two options here, either something like:

// Option 1
const pCall = grpcClient.vaultsCreate(
    vaultMessage,                                                      // Message Type
    await client.session.createCallCredentials(),       // grpc.CallOptions
);

or

// Option 2
const pCall = grpcClient.vaultsCreate(
    vaultMessage,                                                      // Message Type
    meta,                                                                    // grpc.Metadata
    await client.session.createCallCredentials(),       // grpc.CallOptions
);

Option 2 seems more robust simply because it seems more supported by the grpc library. In the generated code:

public vaultsCreate(request: Client_pb.VaultMessage, callback: (error: grpc.ServiceError | null, response: Client_pb.VaultMessage) => void): grpc.ClientUnaryCall;
public vaultsCreate(request: Client_pb.VaultMessage, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: Client_pb.VaultMessage) => void): grpc.ClientUnaryCall;
public vaultsCreate(request: Client_pb.VaultMessage, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: Client_pb.VaultMessage) => void): grpc.ClientUnaryCall;

The last overload shows that the function call takes: MessageType, grpc.Metadata, grpc.CallOptions, which matches Options 2. There does not seem to be a function call for vaultsCreate that matches Option 1.

@CMCDragonkai mentioned before that maybe, the only reason Option 1 had worked as because we had removed typings from the call by using ...args in our GRPCClientClient

The strange thing is that the exist function overloads that match Option 1 for the stream based grpc calls.

public vaultsList(request: Client_pb.EmptyMessage, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<Client_pb.VaultListMessage>;
public vaultsList(request: Client_pb.EmptyMessage, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<Client_pb.VaultListMessage>;

The first one takes a MessageType and a grpc.CallOptions, but it also has the MessageType, grpc.Metadata and grpc.CallOptions call.

With that, honestly it seems like the best approach is to use the calls with grpc.Metadata in them. @tegefaulkes @CMCDragonkai thoughts?

@CMCDragonkai
Copy link
Member

Try doing option 2 for unary calls. And for streams leave it as is. I reckon we should matching the call signature even if it is weird.

@tegefaulkes
Copy link
Contributor Author

Looking into the callCredentials that you can create when setting up a client connection. I think it's possible for the client to provide metadata for each call automatically.

For example, if we provide the JWT token metadata to the client as a callCredential it should provide that each time we make a call. so we don't need to provide it each time we make the call. the documentation on this is very light so I need to do some testing to confirm this,

I'll look deeper into this once I've completed #229

@CMCDragonkai
Copy link
Member

CMCDragonkai commented Aug 30, 2021 via email

@tegefaulkes
Copy link
Contributor Author

I've done some testing now. Looks like you can provide a metadataGenerator to the callCredentials. This will generate new metadata each time a call is done add that to the metadata of the call. Using this we can get the JWT token from the session manager and provide that for each call automatically.

This way we don't have to provide the session token metadata explicitly for each call. if the token gets updated in the session manager this should be reflected in future calls.

This only solves half of the problem here. The server side still needs to verify the metadata for each call. I don't see a way around that however. but it does give the freedom to decide if the token is required on a call per call basis.

@CMCDragonkai
Copy link
Member

CMCDragonkai commented Aug 30, 2021 via email

@tegefaulkes
Copy link
Contributor Author

I have a functioning example of this working now. We wont need to provide the token for every call now.
I've made it optional by optionally passing the GRPCClientClient a Session object otherwise it defaults to the original behaviour.

If you do try to manually provide the token with this enabled then you'll get a error ErrorGRPCConnection: 13 INTERNAL: "authorization" metadata cannot have multiple values so keep that in mind.

I can proceed with updating the code to use this change.

@CMCDragonkai
Copy link
Member

That's great. Are you sure you want to pass the entire Session object as opposed to just the token data itself? Principle of least power... Etc.

@tegefaulkes
Copy link
Contributor Author

This way if we update the token inside the Session that is reflected inside the metadata. Ideally I could just pass the CallMetadataGenerator but that had an issue with scoping. Right now I'm creating the CallCredential with const callCredentials = grpc.credentials.createFromMetadataGenerator(session.sessionMetadatagenerator.bind(session));.
There might be a better way but this is just what I got working.

@tegefaulkes
Copy link
Contributor Author

tegefaulkes commented Aug 31, 2021

Fixed all the GRPC calls by removing the call Credentials and metadata where relevant. All tests are passing, linted and checked that it builds. Unless I'm missing anything this issue should be done.

Refer to this commit for the changes. 70bdcfb, d977f6a

This will be done when https://gitlab.com/MatrixAI/Engineering/Polykey/js-polykey/-/merge_requests/210 is merged

@CMCDragonkai
Copy link
Member

Awesome.

Although in the future, make sure to plan out the tasks before hand in the issue before starting on it.

@CMCDragonkai CMCDragonkai added the security Security risk label Sep 2, 2021
@CMCDragonkai
Copy link
Member

Done now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
development Standard development security Security risk
Development

No branches or pull requests

3 participants