> can it trust that it's talking to the same client over the same RPC? And if so, why?
Yes, because an RPC is an unbroken stream in an unbroken TCP connection which is always with one specific client. I suggest you familiarize yourself with the concepts of a http2 stream, a TCP connection, a gRPC channel and so on. On Sun, Mar 19, 2023 at 2:10 PM Eric Robins <ericrobin...@gmail.com> wrote: > Ok, I think I'm getting closer to understanding what I need to > understand. I'm admittedly being a bit loose with terminology, and I > believe it's the instantiation and maintenance of an *RPC* on which I > need to focus. By default - without trying to intercept every message that > the client sends to the server - is an RPC that has been authenticated > initially expected to be secure throughout its lifecycle? In other words, > if the server authenticates the client upon RPC instantiation, can it trust > that it's talking to the same client over the same RPC? And if so, why? > > Thanks. > > On Friday, March 17, 2023 at 4:55:08 PM UTC-5 sanjay...@google.com wrote: > >> Comments inline below: >> >> On Friday, March 17, 2023 at 12:57:31 PM UTC-7 Eric Robins wrote: >> >> Ok, I have a simple POC of a bidrectional streaming RPC up in Java. The >> client instantiates the non-blocking message stub a single time and the >> request and response StreamObservers are re-used throughout the >> communication between client/server. >> >> >> Yes, your observation is consistent with how a streaming RPC is works. A >> single StreamObserver (one each on request and response side) will be used >> throughout the life of a streaming RPC. >> >> >> I confirmed in Wireshark that the same HTTP/2 stream is being reused for >> all communications. This is ideal and is how our organization will likely >> implement if/when we start using gRPC. >> >> >> Yes a bidirectional streaming RPC *does* mean a single HTTP/2 stream will >> be used for that RPC and you could say is the definition of it. >> >> >> Implemented on the server is an interceptor - similar to what you've >> linked in above. >> >> >> I think you are talking about the JwtServerInterceptor in >> https://github.com/grpc/grpc-java/tree/master/examples/example-jwt-auth. >> This interceptor gets invoked per RPC but *does not* intercept (or listen >> to) messages in an RPC. It should be easy to modify your interceptor to >> intercept (listen to) each incoming request message. Take a look at >> https://github.com/grpc/grpc-java/blob/master/gcp-observability/src/main/java/io/grpc/gcp/observability/interceptors/InternalLoggingServerInterceptor.java >> to see how the interceptor returns a SimpleForwardingServerCallListener< >> ReqT> to intercept each (request) message in onMessage(ReqT message). >> You add your authorization logic there. >> >> >> I'm noticing that it's only invoked once, when the channel is first >> established. >> >> >> I would like to make sure you are clear about the distinction between >> channel, stream, message and so on. A channel is one or more TCP >> connections and is used for multiple RPCs. Each RPC is an http2 stream and >> consists of one or more request/response messages. What you are probably >> trying to say is that "...it's only invoked once, when an RPC is first >> started." Whereas what you want is an invocation per (request) message in >> an RPC. >> >> Subsequent communication with the server from the client doesn't result >> in any new hits to the interceptor. If I don't reuse streams it will be >> invoked every time new streams are established. Is this expected behavior >> - for interceptors only to fire during the first time a client makes a call >> over a newly established stream? If so then I come back to my original >> question that started this thread: how would we consider the established >> stream and channel secure, how how does the server continue to trust that >> it's the same client with which it's communicating? >> >> >> As mentioned above if you modify your server interceptor to "intercept" >> each request message in onMessage(ReqT message) then you are set. Having >> said that if you are trying to authorize each request message in the >> request stream then it may not be the right model - one of the reasons is >> there is metadata (headers) for the whole RPC and not per message so it >> does not make sense to authorize each request message. >> >> >> Thanks in advance. If there's a more appropriate place to get ongoing >> support for questions such as these, please let me know. >> >> >> This is probably the right place for asking such questions. >> >> >> Eric >> >> On Thursday, March 2, 2023 at 4:03:30 PM UTC-6 sanjay...@google.com >> wrote: >> >> On Thursday, March 2, 2023 at 9:57:15 AM UTC-8 Eric Robins wrote: >> >> Thanks - this discussion is helpful. When I mentioned interceptors I was >> looking specifically at Java, which is likely to be the language chosen. I >> am however looking at this from a security perspective as an engineer >> attempting to evaluate the protocol and the implementation in Java. >> >> >> Okay. The SDK is also available although it only supports static config >> for now and I think file watcher is coming soon. >> >> >> >> I may be having trouble asking my question. As I noted in my first post, >> it's easy in traditional REST services over HTTP/1.1 to see how continued >> communication between a client and server is authenticated and authorized. >> With the popular OAuth 2.0 model as an example, the client may initially >> authenticate to an /auth endpoint with a token, cert, etc in order to get >> back a short-lived session grant (usually a JWT). Subsequent calls to the >> server require that grant to be present in an HTTP header in order to >> access the requested services. In this pattern, the client must always >> deliberately present a credential issued to them by the server in order to >> continue to access the necessary services and resources. The server isn't >> relying on anything else - the TLS connection, TCP connection, etc to >> identify the client - only the grant. >> >> >> This is definitely possible in gRPC (provided you verify the JWT) - see >> the example >> https://github.com/grpc/grpc-java/tree/master/examples/example-jwt-auth >> . This uses interceptors which I would consider as the right way to do >> this. >> >> >> >> >> I'm trying to relate that to how gRPC continues to identify a client >> after they've authenticated and a channel has been established. Under the >> covers, is gRPC associating that channel to the TCP connection such that if >> the TCP connection is closed, the channel is closed? Is it bound instead >> to the HTTP/2 stream, which binds a client to the server via TCP or TLS? >> Or, is there something the client continuously presents with each >> subsequent call that the server uses to identify them? The implication is >> that the server can continue to identify the client after a channel has >> been established; I'm trying to understand how. >> >> >> Good question. This is a bit involved - you can see how it's done in >> GrpcAuthorizationEngine.EvaluateArgs.getPrincipalNames >> <https://github.com/grpc/grpc-java/blob/master/xds/src/main/java/io/grpc/xds/internal/rbac/engine/GrpcAuthorizationEngine.java#L303> >> when >> mTLS is used for client identity. TRANSPORT_ATTR_SSL_SESSION allows you >> to access the SSL session as a transport attribute of your current server >> call and you can get then get the peer cert and the principal name from the >> SSLSession. As you can see it is already done for you by the >> GrpcAuthorizationEngine >> <https://github.com/grpc/grpc-java/blob/master/xds/src/main/java/io/grpc/xds/internal/rbac/engine/GrpcAuthorizationEngine.java#L303> >> which >> is the implementation of >> https://github.com/grpc/proposal/blob/master/A43-grpc-authorization-api.md >> . >> >> >> >> >> Thanks again... >> >> -- > You received this message because you are subscribed to the Google Groups " > grpc.io" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to grpc-io+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/grpc-io/c28cc011-2889-4adb-9f50-093427ac4e2dn%40googlegroups.com > <https://groups.google.com/d/msgid/grpc-io/c28cc011-2889-4adb-9f50-093427ac4e2dn%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "grpc.io" group. To unsubscribe from this group and stop receiving emails from it, send an email to grpc-io+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/grpc-io/CA%2BPad6gz24qUv6uc8r%2BYc9UUGHFart2CNw9WfNLRSrBkFoP9Tw%40mail.gmail.com.