grpc-node icon indicating copy to clipboard operation
grpc-node copied to clipboard

How to create secure credentials with custom connection options?

Open banool opened this issue 2 years ago • 2 comments

I have this code at the moment that I use to increase the frame and window sizes:

class CustomChannelCred extends ChannelCredentials {
  constructor(callCredentials?: CallCredentials) {
    super();
  }

  compose(callCredentials: CallCredentials): never {
    throw new Error("Cannot compose insecure credentials");
  }

  _getConnectionOptions(): any {
    return {
      settings: {
        // This will increase the http2 frame size. Default is 16384, which is too small.
        maxFrameSize: 4194304,
        // The initial window size set here is overridden later. We need to patch the grpc-js library to allow this.
        initialWindowSize: 4194304,
        maxHeaderListSize: 8192,
        enablePush: false,
        maxConcurrentStreams: 0,
      },
    };
  }

  _isSecure(): boolean {
    return false;
  }

  _equals(other: ChannelCredentials): boolean {
    return other instanceof CustomChannelCred;
  }
}

Previously I was connecting to an upstream without SSL but that has changed. I can successfully connect to the upstream if I scrap all of that and just use credentials.createSsl(), but then I'm not setting my custom connection options. Making _isSecure return true also doesn't work.

I've tried a variety of ways to create a custom channel credentials class, composing with CallCredentials, etc. but none of that seems to work. I'm reaching for some kind of compose function that works with another instance of ChannelCredentials, but it doesn't exist.

I looked at these docs and they didn't really help either: https://grpc.io/docs/guides/auth/#nodejs.

In short, how can I modify the connection options on an instance of ChannelCredentials?

banool avatar Sep 01 '23 11:09 banool

Setting custom connection options is not an intended usage of the credentials API. It is just an artifact of how the TLS credentials operate.

We can discuss implementing channel arguments to set those connection options. In particular, regarding the settings you have there:

  • [ ] maxFrameSize has a channel argument defined. Implementing it should be simple.
  • [ ] initialWindowSize is discussed in #2429. The conclusion there is that the right path forward is BDP-based dynamic flow control window adjustment. I have not yet had an opportunity to actually implement that.
  • [ ] I think maxHeaderListSize is controlled by this channel argument. Implementing that should also be simple.
  • [ ] enablePush is irrelevant because gRPC servers should never push anyway. I think we can just hardcode this to false.
  • [ ] maxConcurrentStreams is also irrelevant. gRPC servers do not create streams. I think this can also be hardcoded to 0.

murgatroid99 avatar Sep 01 '23 16:09 murgatroid99

Hahah yeah I could tell from the API that customizing the connection options was not really supported.

Being able to set some of those arguments would be nice indeed, consider this a +1 to the feature request! As it is now, I'm seeing that upgrading from 1.8 to 1.9 actually improves the perf issues we were seeing significantly so this doesn't seem to be a blocker for us anymore.

Thanks a lot for the prompt response!

banool avatar Sep 01 '23 17:09 banool