Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 7 Current »

Key Points

  1. remote RPC using gossip protocol


References

Reference_description_with_linked_URLs____________________Notes____________________________________________________________


https://grpc.io/docs/guides/What is gRPC?
https://grpc.io/docs/guides/concepts/concepts
https://grpc.io/docs/tutorials/tutorials
https://grpc.io/docs/tutorials/basic/web/gRPC from Web browsers
https://grpc.io/docs/tutorials/basic/java/gRPC from Java
https://grpc.io/docs/tutorials/basic/node/gRPC from Node
https://grpc.io/docs/tutorials/basic/python/gRPC from Python


https://managementfromscratch.wordpress.com/2016/04/01/introduction-to-gossip/

https://drive.google.com/open?id=11wcOHe6vwdpucOjwhI9tktxEeYp1yEEv

gossip-protocol-overview-2016-managementfromscratch.wordpress.com-Introduction to Gossip.pdf

What is the gossip protocol - article


https://developers.google.com/protocol-buffersGoogle protocol buffers
https://developers.google.com/protocol-buffers/docs/overviewProtocol buffers overview
https://developers.google.com/protocol-buffers/docs/tutorialsProto buffer tutorlals
https://developers.google.com/protocol-buffers/docs/javatutorialProtobuf java ex
https://developers.google.com/protocol-buffers/docs/pythontutorialProtobuf Python ex


https://grpc.io/docs/what-is-grpc/core-concepts/
https://betterprogramming.pub/understanding-grpc60737b23e79e#:~:text=It%20is%20an%20
adaptation%20of,communication%20instead%20of%20JSON%2FXML
.

https://www.altexsoft.com/blog/what-is-grpc/
https://cloud.google.com/blog/products/api-management/understanding-grpc-openapi-and-rest-and-when-to-use-them


https://www.freecodecamp.org/news/what-is-grpc-protocol-buffers-stream-architecture/


Key Concepts


Common Message Protocols: protobuf, gossip. grpc, more ...


Jem CMP - common meta protocol model … conversation envelope header with pointers to 4 streams and conversation id:


Allows defining protocol types flexibly and then instantiating conversations from those protocols


Conversation Envelope has a header, end message and encompasses pointers to 4 streams


Parties with role permissions stream

Control stream

Data stream 

Metadata stream


Events are defined within any stream


Open protocol model allows custom rules for conversation initiation, connections, acquisition etc


  1. ANY protocol can be engineered from the meta protocol to fit any network and application use case 
  2. A defined CMP type can be registered locally or globally in a directory. The CMP id has 2 parts - the owner id and the CMP id. The CMP also has a canonical name that can be searched for in the registry.
    1. Conversations are instantiated by referring to a CMP type
  3. Examples of protocols definable with CMP include: protobuf, GRPC, Thrift, UPC, SFTP and so on
  4. Using secured conversation packages and streams allows ultimate flexibility to fit any app need or scenario
  5. Also, smart protocols can adapt with connection rules to link conversations real-time 
  6. All authorized object services in the network can participate in conversations based on conversation governance rules in effect
  7. Parties map to different identity models to identify parties - there are a “supported” set of identity standards ( eg SAML, OAUTH2, SSI etc )
  8. The SOC model - separation of concerns - allows full, flexible control with the highest possible performance -- the isolated data stream only contains data as a stream or message stream ( much more efficient than https protocol for example )
  9. The messages in the data stream are defined by the metadata stream including usage rules
  10. The messages in the data stream are managed by the control stream which also manages the full conversation instance
  11. While the conversation can be identified with canonical data, it can be referenced simply using the GCI and UCI - Global Contenxt ID and the Unique Conversation ID - therefore conversations can be assigned, shared or transferred to different GCIs -- a big win
  12. Smart agents that understand the meta protocol can dynamically understand and interact with the protocol if they have the appropriate permissions and credentials to do so
  13. Like OSI, the CMP - conversation meta protocol can define multiple layers of conversations for different service use cases and types - think a low-level network message protocol as the transport and an application level protocol ( eg order messages ) using the network protocol as we do today in OSI
  14. As a meta protocol, if authorized, parties can discover the protocol model and governing rules to adapt dynamically
  15. Multiple conversation models are supported ( as other protocols do ) - duplex, half duplex, parties roles can be producer, consumer, both, editor, manager etc ), ACID, CAP message rules are enforceable, 
  16. custom transaction life cycles are possible ( given commit, add age, finalization states for example supporting rules )
  17. The CMP standard makes observability, audits and compliance easy compared to building in specific protocols that can’t be dynamically understood but must be pre-defined by parties using or observing the conversations - independent traceability and governance is a big win for secure environments.
  18. Privacy - the privacy rules for the parties, the conversation, the messages are all configurable and, therefore, compliant with many related privacy standards - GDPR, HIPAA, PCI, TIPPSS, DPP, SSI, etc 
  19. Given a CMP model ( unlike TCP ), protocol level resiliency, replay and recovery can be automated ( as I did at Dupont with SNA LU1 user defined message sizes ) without custom recovery or replay programming at the app level - big win


Message Formats - Binary vs Text formats - Protobuf, JSON-LD, XML



https://www.techtarget.com/searchapparchitecture/tip/Understanding-protocol-buffers-vs-JSON

For data storage and sharing, structured data must be converted into simpler formats. This data serialization must be reversible to recover the original structure when required. Data serialization is supported by various formats such as CSV, YAML, XML, JSON and protocol buffers.

The highly regarded JSON data-interchange format is a subset of the JavaScript programming language. It is praised for being lightweight and easy to understand.

Google developed protocol buffers, or Protobuf, as a binary format to serialize data between services. While Protobuf is not yet capable of replacing JSON where services are consumed by a web browser, it has practical use cases.

Speed and performance. The core idea that drove the team at Google to develop Protobuf was to create a format that's lighter, faster and significantly more performant than XML. As it turns out, Protobuf performs even better than JSON, as shown in Eishay Smith's study. This becomes more apparent while encoding integers.

Support for programming languages. Protobuf is currently restricted to some common languages like Objective-C, Java, C# and Python, which are used through Google's new proto3 language version. Nonetheless, protocol buffers are platform-independent and language-neutral. While JSON was derived from JavaScript, almost all languages can now generate and parse data in this format.


Gossip protocol for multi-cast messaging


https://en.wikipedia.org/wiki/Gossip_protocol



https://www.educative.io/answers/what-is-gossip-protocol

Gossip protocol is a communication protocol that allows state sharing in distributed systems. Most modern systems use this peer-to-peer protocol to disseminate information to all the members in a network or cluster.

This protocol is used in a decentralized system that does not have any central node to keep track of all nodes and know if a node is down or not


Compare Gossip to other multicast protocols

Evaluation of gossip to build scalable and reliable multicast protocols

https://www.sciencedirect.com/science/article/abs/pii/S0166531604000781

The evaluation comprises of three parts: (1) a comparison of the gossip technique with other traditional message loss detection and recovery techniques, (2) an extensive performance evaluation of the gossip technique under several different operating parameters, and (3) an evaluation of how the performance of a gossip-based multicast protocol is affected by varying various gossip parameters. The main conclusion of the paper is that the gossip technique is certainly a useful technique for constructing scalable and reliable multicast protocols. However, it performs poorly under some specific operating conditions, and its performance is affected by the selection criteria used to select a gossip subgroup and gossip period. Based on the results of this experimental evaluation, the paper identifies three major factors that critically affect the scalability and reliability of a multicast protocol. These are (1) percentage of overhead messages exchanged, (2) overhead message concentration, and (3) application characteristics that determine message arrival rate and message arrival pattern.



What is gRPC and Protobuf?

https://grpc.io/docs/guides/

This document introduces you to gRPC and protocol buffers. gRPC can use protocol buffers as both its Interface Definition Language (IDL) and as its underlying message interchange format. If you’re new to gRPC and/or protocol buffers, read this! If you just want to dive in and see gRPC in action first, see our Quick Starts.


https://grpc.io/docs/what-is-grpc/faq/

gRPC is a modern, open source remote procedure call (RPC) framework that can run anywhere. It enables client and server applications to communicate transparently, and makes it easier to build connected systems.

gRPC uses HTTP/2, which multiplexes multiple calls on a single TCP connection. All gRPC calls over that connection go to one endpoint.

The main usage scenarios:

  • Low latency, highly scalable, distributed systems.
  • Developing mobile clients which are communicating to a cloud server.
  • Designing a new protocol that needs to be accurate, efficient and language independent.
  • Layered design to enable extension eg. authentication, load balancing, logging and monitoring etc.

Overview

In gRPC a client application can directly call methods on a server application on a different machine as if it was a local object, making it easier for you to create distributed applications and services. As in many RPC systems, gRPC is based around the idea of defining a service, specifying the methods that can be called remotely with their parameters and return types. On the server side, the server implements this interface and runs a gRPC server to handle client calls. On the client side, the client has a stub (referred to as just a client in some languages) that provides the same methods as the server.

Concept Diagram

gRPC clients and servers can run and talk to each other in a variety of environments - from servers inside Google to your own desktop - and can be written in any of gRPC’s supported languages. So, for example, you can easily create a gRPC server in Java with clients in Go, Python, or Ruby. In addition, the latest Google APIs will have gRPC versions of their interfaces, letting you easily build Google functionality into your applications.

Working with Protocol Buffers

By default gRPC uses protocol buffers, Google’s mature open source mechanism for serializing structured data (although it can be used with other data formats such as JSON). Here’s a quick intro to how it works. If you’re already familiar with protocol buffers, feel free to skip ahead to the next section.

The first step when working with protocol buffers is to define the structure for the data you want to serialize in a proto file: this is an ordinary text file with a .proto extension. Protocol buffer data is structured as messages, where each message is a small logical record of information containing a series of name-value pairs called fields. Here’s a simple example:

message Person {
  string name = 1;
  int32 id = 2;
  bool has_ponycopter = 3;
}

Then, once you’ve specified your data structures, you use the protocol buffer compiler protoc to generate data access classes in your preferred language(s) from your proto definition. These provide simple accessors for each field (like name() and set_name()) as well as methods to serialize/parse the whole structure to/from raw bytes – so, for instance, if your chosen language is C++, running the compiler on the above example will generate a class called Person. You can then use this class in your application to populate, serialize, and retrieve Person protocol buffer messages.

As you’ll see in more detail in our examples, you define gRPC services in ordinary proto files, with RPC method parameters and return types specified as protocol buffer messages:

// The greeter service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

gRPC also uses protoc with a special gRPC plugin to generate code from your proto file. However, with the gRPC plugin, you get generated gRPC client and server code, as well as the regular protocol buffer code for populating, serializing, and retrieving your message types. We’ll look at this example in more detail below.

You can find out lots more about protocol buffers in the Protocol Buffers documentation, and find out how to get and install protoc with gRPC plugins in your chosen language’s Quickstart.

Protocol buffer versions

While protocol buffers have been available for open source users for some time, our examples use a new flavor of protocol buffers called proto3, which has a slightly simplified syntax, some useful new features, and supports lots more languages. This is currently available in Java, C++, Python, Objective-C, C#, a lite-runtime (Android Java), Ruby, and JavaScript from the protocol buffers GitHub repo, as well as a Go language generator from the golang/protobuf GitHub repo, with more languages in development. You can find out more in the proto3 language guide and the reference documentation available for each language. The reference documentation also includes a formal specification for the .proto file format.

In general, while you can use proto2 (the current default protocol buffers version), we recommend that you use proto3 with gRPC as it lets you use the full range of gRPC-supported languages, as well as avoiding compatibility issues with proto2 clients talking to proto3 servers and vice versa.



gRPC Concepts

https://grpc.io/docs/guides/concepts/

This document introduces some key gRPC concepts with an overview of gRPC’s architecture and RPC life cycle.

It assumes that you’ve read What is gRPC?. For language-specific details, see the Quick Start, tutorial, and reference documentation for your chosen language(s), where available (complete reference docs are coming soon).

Overview

Service definition

Like many RPC systems, gRPC is based around the idea of defining a service, specifying the methods that can be called remotely with their parameters and return types. By default, gRPC uses protocol buffers as the Interface Definition Language (IDL) for describing both the service interface and the structure of the payload messages. It is possible to use other alternatives if desired.

service HelloService {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string greeting = 1;
}

message HelloResponse {
  string reply = 1;
}

gRPC lets you define four kinds of service method:

  • Unary RPCs where the client sends a single request to the server and gets a single response back, just like a normal function call.
rpc SayHello(HelloRequest) returns (HelloResponse){
}
  • Server streaming RPCs where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. gRPC guarantees message ordering within an individual RPC call.
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){
}
  • Client streaming RPCs where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them and return its response. Again gRPC guarantees message ordering within an individual RPC call.
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {
}
  • Bidirectional streaming RPCs where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved.
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse){
}

We’ll look at the different types of RPC in more detail in the RPC life cycle section below.

Using the API surface

Starting from a service definition in a .proto file, gRPC provides protocol buffer compiler plugins that generate client- and server-side code. gRPC users typically call these APIs on the client side and implement the corresponding API on the server side.

  • On the server side, the server implements the methods declared by the service and runs a gRPC server to handle client calls. The gRPC infrastructure decodes incoming requests, executes service methods, and encodes service responses.
  • On the client side, the client has a local object known as stub (for some languages, the preferred term is client) that implements the same methods as the service. The client can then just call those methods on the local object, wrapping the parameters for the call in the appropriate protocol buffer message type - gRPC looks after sending the request(s) to the server and returning the server’s protocol buffer response(s).

Synchronous vs. asynchronous

Synchronous RPC calls that block until a response arrives from the server are the closest approximation to the abstraction of a procedure call that RPC aspires to. On the other hand, networks are inherently asynchronous and in many scenarios it’s useful to be able to start RPCs without blocking the current thread.

The gRPC programming surface in most languages comes in both synchronous and asynchronous flavors. You can find out more in each language’s tutorial and reference documentation (complete reference docs are coming soon).

RPC life cycle

Now let’s take a closer look at what happens when a gRPC client calls a gRPC server method. We won’t look at implementation details, you can find out more about these in our language-specific pages.

Unary RPC

First let’s look at the simplest type of RPC, where the client sends a single request and gets back a single response.

  • Once the client calls the method on the stub/client object, the server is notified that the RPC has been invoked with the client’s metadata for this call, the method name, and the specified deadline if applicable.
  • The server can then either send back its own initial metadata (which must be sent before any response) straight away, or wait for the client’s request message - which happens first is application-specific.
  • Once the server has the client’s request message, it does whatever work is necessary to create and populate its response. The response is then returned (if successful) to the client together with status details (status code and optional status message) and optional trailing metadata.
  • If the status is OK, the client then gets the response, which completes the call on the client side.

Server streaming RPC

A server-streaming RPC is similar to our simple example, except the server sends back a stream of responses after getting the client’s request message. After sending back all its responses, the server’s status details (status code and optional status message) and optional trailing metadata are sent back to complete on the server side. The client completes once it has all the server’s responses.

Client streaming RPC

A client-streaming RPC is also similar to our simple example, except the client sends a stream of requests to the server instead of a single request. The server sends back a single response, typically but not necessarily after it has received all the client’s requests, along with its status details and optional trailing metadata.

Bidirectional streaming RPC

In a bidirectional streaming RPC, again the call is initiated by the client calling the method and the server receiving the client metadata, method name, and deadline. Again the server can choose to send back its initial metadata or wait for the client to start sending requests.

What happens next depends on the application, as the client and server can read and write in any order - the streams operate completely independently. So, for example, the server could wait until it has received all the client’s messages before writing its responses, or the server and client could “ping-pong”: the server gets a request, then sends back a response, then the client sends another request based on the response, and so on.


Deadlines/Timeouts

gRPC allows clients to specify how long they are willing to wait for an RPC to complete before the RPC is terminated with the error DEADLINE_EXCEEDED. On the server side, the server can query to see if a particular RPC has timed out, or how much time is left to complete the RPC.

How the deadline or timeout is specified varies from language to language - for example, not all languages have a default deadline, some language APIs work in terms of a deadline (a fixed point in time), and some language APIs work in terms of timeouts (durations of time).

RPC termination

In gRPC, both the client and server make independent and local determinations of the success of the call, and their conclusions may not match. This means that, for example, you could have an RPC that finishes successfully on the server side (“I have sent all my responses!”) but fails on the client side (“The responses arrived after my deadline!“). It’s also possible for a server to decide to complete before a client has sent all its requests.

Cancelling RPCs

Either the client or the server can cancel an RPC at any time. A cancellation terminates the RPC immediately so that no further work is done. It is not an “undo”: changes made before the cancellation will not be rolled back.


Metadata

Metadata is information about a particular RPC call (such as authentication details) in the form of a list of key-value pairs, where the keys are strings and the values are typically strings (but can be binary data). Metadata is opaque to gRPC itself - it lets the client provide information associated with the call to the server and vice versa.

Access to metadata is language-dependent.

Channels

A gRPC channel provides a connection to a gRPC server on a specified host and port and is used when creating a client stub (or just “client” in some languages). Clients can specify channel arguments to modify gRPC’s default behaviour, such as switching on and off message compression. A channel has state, including connected and idle.

How gRPC deals with closing down channels is language-dependent. Some languages also permit querying channel state.


gRPC Authentication

https://grpc.io/docs/guides/auth/

This document provides an overview of gRPC authentication, including our built-in supported auth mechanisms, how to plug in your own authentication systems, and examples of how to use gRPC auth in our supported languages.

Overview

gRPC is designed to work with a variety of authentication mechanisms, making it easy to safely use gRPC to talk to other systems. You can use our supported mechanisms - SSL/TLS with or without Google token-based authentication - or you can plug in your own authentication system by extending our provided code.

gRPC also provides a simple authentication API that lets you provide all the necessary authentication information as Credentials when creating a channel or making a call.

Supported auth mechanisms

The following authentication mechanisms are built-in to gRPC:

  • SSL/TLS: gRPC has SSL/TLS integration and promotes the use of SSL/TLS to authenticate the server, and to encrypt all the data exchanged between the client and the server. Optional mechanisms are available for clients to provide certificates for mutual authentication.
  • Token-based authentication with Google: gRPC provides a generic mechanism (described below) to attach metadata based credentials to requests and responses. Additional support for acquiring access tokens (typically OAuth2 tokens) while accessing Google APIs through gRPC is provided for certain auth flows: you can see how this works in our code examples below. In general this mechanism must be used as well as SSL/TLS on the channel - Google will not allow connections without SSL/TLS, and most gRPC language implementations will not let you send credentials on an unencrypted channel.

WARNING: Google credentials should only be used to connect to Google services. Sending a Google issued OAuth2 token to a non-Google service could result in this token being stolen and used to impersonate the client to Google services.

Authentication API

gRPC provides a simple authentication API based around the unified concept of Credentials objects, which can be used when creating an entire gRPC channel or an individual call.

Credential types

Credentials can be of two types:

  • Channel credentials, which are attached to a Channel, such as SSL credentials.
  • Call credentials, which are attached to a call (or ClientContext in C++).

You can also combine these in a CompositeChannelCredentials, allowing you to specify, for example, SSL details for the channel along with call credentials for each call made on the channel. A CompositeChannelCredentials associates a ChannelCredentials and a CallCredentials to create a new ChannelCredentials. The result will send the authentication data associated with the composed CallCredentials with every call made on the channel.

For example, you could create a ChannelCredentials from an SslCredentials and an AccessTokenCredentials. The result when applied to a Channel would send the appropriate access token for each call on this channel.

Individual CallCredentials can also be composed using CompositeCallCredentials. The resulting CallCredentials when used in a call will trigger the sending of the authentication data associated with the two CallCredentials.

Using client-side SSL/TLS

Now let’s look at how Credentials work with one of our supported auth mechanisms. This is the simplest authentication scenario, where a client just wants to authenticate the server and encrypt all data. The example is in C++, but the API is similar for all languages: you can see how to enable SSL/TLS in more languages in our Examples section below.

// Create a default SSL ChannelCredentials object.
auto channel_creds = grpc::SslCredentials(grpc::SslCredentialsOptions());
// Create a channel using the credentials created in the previous step.
auto channel = grpc::CreateChannel(server_name, channel_creds);
// Create a stub on the channel.
std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel));
// Make actual RPC calls on the stub.
grpc::Status s = stub->sayHello(&context, *request, response);

For advanced use cases such as modifying the root CA or using client certs, the corresponding options can be set in the SslCredentialsOptions parameter passed to the factory method.

Using Google token-based authentication

gRPC applications can use a simple API to create a credential that works for authentication with Google in various deployment scenarios. Again, our example is in C++ but you can find examples in other languages in our Examples section.

auto creds = grpc::GoogleDefaultCredentials();
// Create a channel, stub and make RPC calls (same as in the previous example)
auto channel = grpc::CreateChannel(server_name, creds);
std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel));
grpc::Status s = stub->sayHello(&context, *request, response);

This channel credentials object works for applications using Service Accounts as well as for applications running in Google Compute Engine (GCE). In the former case, the service account’s private keys are loaded from the file named in the environment variable GOOGLE_APPLICATION_CREDENTIALS. The keys are used to generate bearer tokens that are attached to each outgoing RPC on the corresponding channel.

For applications running in GCE, a default service account and corresponding OAuth2 scopes can be configured during VM setup. At run-time, this credential handles communication with the authentication systems to obtain OAuth2 access tokens and attaches them to each outgoing RPC on the corresponding channel.

Extending gRPC to support other authentication mechanisms

The Credentials plugin API allows developers to plug in their own type of credentials. This consists of:

  • The MetadataCredentialsPlugin abstract class, which contains the pure virtual GetMetadata method that needs to be implemented by a sub-class created by the developer.
  • The MetadataCredentialsFromPlugin function, which creates a CallCredentials from the MetadataCredentialsPlugin.

Here is example of a simple credentials plugin which sets an authentication ticket in a custom header.

class MyCustomAuthenticator : public grpc::MetadataCredentialsPlugin {
 public:
  MyCustomAuthenticator(const grpc::string& ticket) : ticket_(ticket) {}

  grpc::Status GetMetadata(
      grpc::string_ref service_url, grpc::string_ref method_name,
      const grpc::AuthContext& channel_auth_context,
      std::multimap<grpc::string, grpc::string>* metadata) override {
    metadata->insert(std::make_pair("x-custom-auth-ticket", ticket_));
    return grpc::Status::OK;
  }

 private:
  grpc::string ticket_;
};

auto call_creds = grpc::MetadataCredentialsFromPlugin(
    std::unique_ptr<grpc::MetadataCredentialsPlugin>(
        new MyCustomAuthenticator("super-secret-ticket")));

A deeper integration can be achieved by plugging in a gRPC credentials implementation at the core level. gRPC internals also allow switching out SSL/TLS with other encryption mechanisms.

Examples

These authentication mechanisms will be available in all gRPC’s supported languages. The following sections demonstrate how authentication and authorization features described above appear in each language: more languages are coming soon.

Go

Base case - no encryption or authentication

Client:

conn, _ := grpc.Dial("localhost:50051", grpc.WithInsecure())
// error handling omitted
client := pb.NewGreeterClient(conn)
// ...

Server:

s := grpc.NewServer()
lis, _ := net.Listen("tcp", "localhost:50051")
// error handling omitted
s.Serve(lis)
With server authentication SSL/TLS

Client:

creds, _ := credentials.NewClientTLSFromFile(certFile, "")
conn, _ := grpc.Dial("localhost:50051", grpc.WithTransportCredentials(creds))
// error handling omitted
client := pb.NewGreeterClient(conn)
// ...

Server:

creds, _ := credentials.NewServerTLSFromFile(certFile, keyFile)
s := grpc.NewServer(grpc.Creds(creds))
lis, _ := net.Listen("tcp", "localhost:50051")
// error handling omitted
s.Serve(lis)
Authenticate with Google
pool, _ := x509.SystemCertPool()
// error handling omitted
creds := credentials.NewClientTLSFromCert(pool, "")
perRPC, _ := oauth.NewServiceAccountFromFile("service-account.json", scope)
conn, _ := grpc.Dial(
	"greeter.googleapis.com",
	grpc.WithTransportCredentials(creds),
	grpc.WithPerRPCCredentials(perRPC),
)
// error handling omitted
client := pb.NewGreeterClient(conn)
// ...

Ruby

Base case - no encryption or authentication
stub = Helloworld::Greeter::Stub.new('localhost:50051', :this_channel_is_insecure)
...
With server authentication SSL/TLS
creds = GRPC::Core::Credentials.new(load_certs)  # load_certs typically loads a CA roots file
stub = Helloworld::Greeter::Stub.new('myservice.example.com', creds)
Authenticate with Google
require 'googleauth'  # from http://www.rubydoc.info/gems/googleauth/0.1.0
...
ssl_creds = GRPC::Core::ChannelCredentials.new(load_certs)  # load_certs typically loads a CA roots file
authentication = Google::Auth.get_application_default()
call_creds = GRPC::Core::CallCredentials.new(authentication.updater_proc)
combined_creds = ssl_creds.compose(call_creds)
stub = Helloworld::Greeter::Stub.new('greeter.googleapis.com', combined_creds)

C++

Base case - no encryption or authentication
auto channel = grpc::CreateChannel("localhost:50051", InsecureChannelCredentials());
std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel));
...
With server authentication SSL/TLS
auto channel_creds = grpc::SslCredentials(grpc::SslCredentialsOptions());
auto channel = grpc::CreateChannel("myservice.example.com", channel_creds);
std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel));
...
Authenticate with Google
auto creds = grpc::GoogleDefaultCredentials();
auto channel = grpc::CreateChannel("greeter.googleapis.com", creds);
std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel));
...

C#

Base case - no encryption or authentication
var channel = new Channel("localhost:50051", ChannelCredentials.Insecure);
var client = new Greeter.GreeterClient(channel);
...
With server authentication SSL/TLS
var channelCredentials = new SslCredentials(File.ReadAllText("roots.pem"));  // Load a custom roots file.
var channel = new Channel("myservice.example.com", channelCredentials);
var client = new Greeter.GreeterClient(channel);
Authenticate with Google
using Grpc.Auth;  // from Grpc.Auth NuGet package
...
// Loads Google Application Default Credentials with publicly trusted roots.
var channelCredentials = await GoogleGrpcCredentials.GetApplicationDefaultAsync();

var channel = new Channel("greeter.googleapis.com", channelCredentials);
var client = new Greeter.GreeterClient(channel);
...
Authenticate a single RPC call
var channel = new Channel("greeter.googleapis.com", new SslCredentials());  // Use publicly trusted roots.
var client = new Greeter.GreeterClient(channel);
...
var googleCredential = await GoogleCredential.GetApplicationDefaultAsync();
var result = client.SayHello(request, new CallOptions(credentials: googleCredential.ToCallCredentials()));
...

Python

Base case - No encryption or authentication
import grpc
import helloworld_pb2

channel = grpc.insecure_channel('localhost:50051')
stub = helloworld_pb2.GreeterStub(channel)
With server authentication SSL/TLS

Client:

import grpc
import helloworld_pb2

with open('roots.pem', 'rb') as f:
    creds = grpc.ssl_channel_credentials(f.read())
channel = grpc.secure_channel('myservice.example.com:443', creds)
stub = helloworld_pb2.GreeterStub(channel)

Server:

import grpc
import helloworld_pb2
from concurrent import futures

server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
with open('key.pem', 'rb') as f:
    private_key = f.read()
with open('chain.pem', 'rb') as f:
    certificate_chain = f.read()
server_credentials = grpc.ssl_server_credentials( ( (private_key, certificate_chain), ) )
# Adding GreeterServicer to server omitted
server.add_secure_port('myservice.example.com:443', server_credentials)
server.start()
# Server sleep omitted
Authenticate with Google using a JWT
import grpc
import helloworld_pb2

from google import auth as google_auth
from google.auth import jwt as google_auth_jwt
from google.auth.transport import grpc as google_auth_transport_grpc

credentials, _ = google_auth.default()
jwt_creds = google_auth_jwt.OnDemandCredentials.from_signing_credentials(
    credentials)
channel = google_auth_transport_grpc.secure_authorized_channel(
    jwt_creds, None, 'greeter.googleapis.com:443')
stub = helloworld_pb2.GreeterStub(channel)
Authenticate with Google using an Oauth2 token
import grpc
import helloworld_pb2

from google import auth as google_auth
from google.auth.transport import grpc as google_auth_transport_grpc
from google.auth.transport import requests as google_auth_transport_requests

credentials, _ = google_auth.default(scopes=(scope,))
request = google_auth_transport_requests.Request()
channel = google_auth_transport_grpc.secure_authorized_channel(
    credentials, request, 'greeter.googleapis.com:443')
stub = helloworld_pb2.GreeterStub(channel)

Java

Base case - no encryption or authentication
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051)
    .usePlaintext(true)
    .build();
GreeterGrpc.GreeterStub stub = GreeterGrpc.newStub(channel);
With server authentication SSL/TLS

In Java we recommend that you use OpenSSL when using gRPC over TLS. You can find details about installing and using OpenSSL and other required libraries for both Android and non-Android Java in the gRPC Java Security documentation.

To enable TLS on a server, a certificate chain and private key need to be specified in PEM format. Such private key should not be using a password. The order of certificates in the chain matters: more specifically, the certificate at the top has to be the host CA, while the one at the very bottom has to be the root CA. The standard TLS port is 443, but we use 8443 below to avoid needing extra permissions from the OS.

Server server = ServerBuilder.forPort(8443)
    // Enable TLS
    .useTransportSecurity(certChainFile, privateKeyFile)
    .addService(TestServiceGrpc.bindService(serviceImplementation))
    .build();
server.start();

If the issuing certificate authority is not known to the client then a properly configured SslContext or SSLSocketFactory should be provided to the NettyChannelBuilder or OkHttpChannelBuilder, respectively.

On the client side, server authentication with SSL/TLS looks like this:

// With server authentication SSL/TLS
ManagedChannel channel = ManagedChannelBuilder.forAddress("myservice.example.com", 443)
    .build();
GreeterGrpc.GreeterStub stub = GreeterGrpc.newStub(channel);

// With server authentication SSL/TLS; custom CA root certificates; not on Android
ManagedChannel channel = NettyChannelBuilder.forAddress("myservice.example.com", 443)
    .sslContext(GrpcSslContexts.forClient().trustManager(new File("roots.pem")).build())
    .build();
GreeterGrpc.GreeterStub stub = GreeterGrpc.newStub(channel);
Authenticate with Google

The following code snippet shows how you can call the Google Cloud PubSub API using gRPC with a service account. The credentials are loaded from a key stored in a well-known location or by detecting that the application is running in an environment that can provide one automatically, e.g. Google Compute Engine. While this example is specific to Google and its services, similar patterns can be followed for other service providers.

GoogleCredentials creds = GoogleCredentials.getApplicationDefault();
ManagedChannel channel = ManagedChannelBuilder.forTarget("greeter.googleapis.com")
    .build();
GreeterGrpc.GreeterStub stub = GreeterGrpc.newStub(channel)
    .withCallCredentials(MoreCallCredentials.from(creds));

Node.js

Base case - No encryption/authentication
var stub = new helloworld.Greeter('localhost:50051', grpc.credentials.createInsecure());
With server authentication SSL/TLS
var ssl_creds = grpc.credentials.createSsl(root_certs);
var stub = new helloworld.Greeter('myservice.example.com', ssl_creds);
Authenticate with Google
// Authenticating with Google
var GoogleAuth = require('google-auth-library'); // from https://www.npmjs.com/package/google-auth-library
...
var ssl_creds = grpc.credentials.createSsl(root_certs);
(new GoogleAuth()).getApplicationDefault(function(err, auth) {
  var call_creds = grpc.credentials.createFromGoogleCredential(auth);
  var combined_creds = grpc.credentials.combineChannelCredentials(ssl_creds, call_creds);
  var stub = new helloworld.Greeter('greeter.googleapis.com', combined_credentials);
});
Authenticate with Google using Oauth2 token (legacy approach)
var GoogleAuth = require('google-auth-library'); // from https://www.npmjs.com/package/google-auth-library
...
var ssl_creds = grpc.Credentials.createSsl(root_certs); // load_certs typically loads a CA roots file
var scope = 'https://www.googleapis.com/auth/grpc-testing';
(new GoogleAuth()).getApplicationDefault(function(err, auth) {
  if (auth.createScopeRequired()) {
    auth = auth.createScoped(scope);
  }
  var call_creds = grpc.credentials.createFromGoogleCredential(auth);
  var combined_creds = grpc.credentials.combineChannelCredentials(ssl_creds, call_creds);
  var stub = new helloworld.Greeter('greeter.googleapis.com', combined_credentials);
});

PHP

Base case - No encryption/authorization
$client = new helloworld\GreeterClient('localhost:50051', [
    'credentials' => Grpc\ChannelCredentials::createInsecure(),
]);
...
Authenticate with Google
function updateAuthMetadataCallback($context)
{
    $auth_credentials = ApplicationDefaultCredentials::getCredentials();
    return $auth_credentials->updateMetadata($metadata = [], $context->service_url);
}
$channel_credentials = Grpc\ChannelCredentials::createComposite(
    Grpc\ChannelCredentials::createSsl(file_get_contents('roots.pem')),
    Grpc\CallCredentials::createFromPlugin('updateAuthMetadataCallback')
);
$opts = [
  'credentials' => $channel_credentials
];
$client = new helloworld\GreeterClient('greeter.googleapis.com', $opts);
Authenticate with Google using Oauth2 token (legacy approach)
// the environment variable "GOOGLE_APPLICATION_CREDENTIALS" needs to be set
$scope = "https://www.googleapis.com/auth/grpc-testing";
$auth = Google\Auth\ApplicationDefaultCredentials::getCredentials($scope);
$opts = [
  'credentials' => Grpc\Credentials::createSsl(file_get_contents('roots.pem'));
  'update_metadata' => $auth->getUpdateMetadataFunc(),
];
$client = new helloworld\GreeterClient('greeter.googleapis.com', $opts);

Dart

Base case - no encryption or authentication
final channel = new ClientChannel('localhost',
      port: 50051,
      options: const ChannelOptions(
          credentials: const ChannelCredentials.insecure()));
final stub = new GreeterClient(channel);
With server authentication SSL/TLS
// Load a custom roots file.
final trustedRoot = new File('roots.pem').readAsBytesSync();
final channelCredentials =
    new ChannelCredentials.secure(certificates: trustedRoot);
final channelOptions = new ChannelOptions(credentials: channelCredentials);
final channel = new ClientChannel('myservice.example.com',
    options: channelOptions);
final client = new GreeterClient(channel);
Authenticate with Google
// Uses publicly trusted roots by default.
final channel = new ClientChannel('greeter.googleapis.com');
final serviceAccountJson =
     new File('service-account.json').readAsStringSync();
final credentials = new JwtServiceAccountAuthenticator(serviceAccountJson);
final client =
    new GreeterClient(channel, options: credentials.toCallOptions);
Authenticate a single RPC call
// Uses publicly trusted roots by default.
final channel = new ClientChannel('greeter.googleapis.com');
final client = new GreeterClient(channel);
...
final serviceAccountJson =
     new File('service-account.json').readAsStringSync();
final credentials = new JwtServiceAccountAuthenticator(serviceAccountJson);
final response =
    await client.sayHello(request, options: credentials.toCallOptions);




Potential Value Opportunities



Potential Challenges



Candidate Solutions



Step-by-step guide for Example



sample code block

sample code block
 



Recommended Next Steps



  • No labels