CallCredentials Without ChannelCredentials

794 views
Skip to first unread message

Daniele T.

unread,
Feb 19, 2021, 9:16:47 AM2/19/21
to grpc.io

Dear Grpc community,

I would like to submit an issue I am experiencing with the Grpc Credential mechanism.

As far as I understand, there are 2 types of credentials:

  • Channel Credentials (TLS basically)

  • Call Credentials (per call headers management)

Those 2 mechanisms are supposed to be orthogonal (i.e. non dependent to each other).

In my domain, there is a Scala based application that acts as a Grpc Server.

My goal is to implement many clients in many different languages.

The server implements an authorization mechanism (realized by an interceptor) that essentially checks a JWT token coming from a request header.

Since the server will be deployed inside a private network and a proxy server will be used to expose the Grpc services, it’s been decided that the channel security will be in charge of this latter component, so the Grpc server itself must use plain text communication.

Consequently, My goal is to implement CallCredentials and not ChannelCredentials

For my Java and scala clients we were able to achieve that goal.

In fact the server is defined as follows

```

NettyServerBuilder

 .forAddress(new InetSocketAddress(InetAddresses.forString(interface), port))

```

And clients leverages a managed channel like this

```

ManagedChannelBuilder.forAddress(host, port).usePlaintext().build

```

With an implementation of the abstract class CallCredentials which add a Jwt token to each request.

Everything is working fine.

While in go I’m encountering the following issues.

On the client side I implemented the interface grpc/credentials.PerRPCCredentials using the tokenAuth structure in order to insert the token in the request header:

```

channel, _ := grpc.Dial(address,

    grpc.WithPerRPCCredentials(TokenAuth{

     token: "my.token",

  }))

```

At this point I have a client error message since it is required to make the credentials explicit:

grpc: no transport security set (use grpc.WithInsecure() explicitly or set credentials)

But if I set the credentials as follows

```

channel, channelErr := grpc.Dial(address,  grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")),

  grpc.WithPerRPCCredentials(TokenAuth{

     token: "my.token",

  }))

```

the server returns the following error message since no server-side TLS is set up:

rpc error: code = Unavailable desc = connection error: desc = "transport: authentication handshake failed: tls: first record does not look like a TLS handshake"

To recap,

My question is essentially what is the best practice, in the GO ecosystem, to use during a call credential and if there is a way to set a call without the transport credential, like I was able to achieve in the Java ecosystem.

Thanks in advance

Menghan Li

unread,
Feb 22, 2021, 5:54:16 PM2/22/21
to grpc.io
If you don't need transport credentials, create the channel with `grpc.WithInsecure()`.

And make sure your `TokenAuth` returns false in `RequireTransportSecurity()`. Otherwise Dial will fail.

Please give it a try and let me know if you have other questions.

Thanks,
Menghan

Reply all
Reply to author
Forward
0 new messages