aboutsummaryrefslogtreecommitdiffhomepage
path: root/doc/grpc-auth-support.md
diff options
context:
space:
mode:
Diffstat (limited to 'doc/grpc-auth-support.md')
-rw-r--r--doc/grpc-auth-support.md289
1 files changed, 289 insertions, 0 deletions
diff --git a/doc/grpc-auth-support.md b/doc/grpc-auth-support.md
new file mode 100644
index 0000000000..800fbedd80
--- /dev/null
+++ b/doc/grpc-auth-support.md
@@ -0,0 +1,289 @@
+#gRPC Authentication support
+
+gRPC is designed to plug-in a number of authentication mechanisms. This document
+provides a quick overview of the various auth mechanisms supported, discusses
+the API with some examples, and concludes with a discussion of extensibility.
+More documentation and examples are coming soon!
+
+## Supported auth mechanisms
+
+###SSL/TLS
+gRPC has SSL/TLS integration and promotes the use of SSL/TLS to authenticate the
+server, and encrypt all the data exchanged between the client and the server.
+Optional mechanisms are available for clients to provide certificates to
+accomplish mutual authentication.
+
+###OAuth 2.0
+gRPC provides a generic mechanism (described below) to attach metadata to
+requests and responses. This mechanism can be used to attach OAuth 2.0 Access
+Tokens to RPCs being made at a client. Additional support for acquiring Access
+Tokens while accessing Google APIs through gRPC is provided for certain auth
+flows, demonstrated through code examples below.
+
+## API
+To reduce complexity and minimize API clutter, gRPC works with a unified concept
+of a Credentials object. Users construct gRPC credentials using corresponding
+bootstrap credentials (e.g., SSL client certs or Service Account Keys), and use
+the credentials while creating a gRPC channel to any server. Depending on the
+type of credential supplied, the channel uses the credentials during the initial
+SSL/TLS handshake with the server, or uses the credential to generate and
+attach Access Tokens to each request being made on the channel.
+
+###SSL/TLS for server authentication and encryption
+This is the simplest authentication scenario, where a client just wants to
+authenticate the server and encrypt all data.
+
+```cpp
+SslCredentialsOptions ssl_opts; // Options to override SSL params, empty by default
+// Create the credentials object by providing service account key in constructor
+std::unique_ptr<Credentials> creds = CredentialsFactory::SslCredentials(ssl_opts);
+// Create a channel using the credentials created in the previous step
+std::shared_ptr<ChannelInterface> channel = CreateChannel(server_name, creds, channel_args);
+// 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.
+
+
+###Authenticating with Google
+
+gRPC applications can use a simple API to create a credential that works in various deployment scenarios.
+
+```cpp
+std::unique_ptr<Credentials> creds = CredentialsFactory::GoogleDefaultCredentials();
+// Create a channel, stub and make RPC calls (same as in the previous example)
+std::shared_ptr<ChannelInterface> channel = CreateChannel(server_name, creds, channel_args);
+std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel));
+grpc::Status s = stub->sayHello(&context, *request, response);
+```
+
+This credential works for applications using Service Accounts as well as for
+applications running in [Google Compute Engine (GCE)](https://cloud.google.com/compute/). 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
+OAuth 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 gRPC protocol is designed with a general mechanism for sending metadata
+associated with RPC. Clients can send metadata at the beginning of an RPC and
+servers can send back metadata at the beginning and end of the RPC. This
+provides a natural mechanism to support OAuth2 and other authentication
+mechanisms that need attach bearer tokens to individual request.
+
+In the simplest case, there is a single line of code required on the client
+to add a specific token as metadata to an RPC and a corresponding access on
+the server to retrieve this piece of metadata. The generation of the token
+on the client side and its verification at the server can be done separately.
+
+A deeper integration can be achieved by plugging in a gRPC credentials implementation for any custom authentication mechanism that needs to attach per-request tokens. 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.
+
+###SSL/TLS for server authentication and encryption (Ruby)
+```ruby
+# Base case - No encryption
+stub = Helloworld::Greeter::Stub.new('localhost:50051')
+...
+
+# 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('localhost:50051', creds: creds)
+```
+
+###SSL/TLS for server authentication and encryption (C#)
+```csharp
+// Base case - No encryption
+var channel = new Channel("localhost:50051");
+var client = new Greeter.GreeterClient(channel);
+...
+
+// With server authentication SSL/TLS
+var credentials = new SslCredentials(File.ReadAllText("ca.pem")); // Load a CA file
+var channel = new Channel("localhost:50051", credentials);
+var client = new Greeter.GreeterClient(channel);
+```
+
+###SSL/TLS for server authentication and encryption (Objective-C)
+
+The default for Objective-C is to use SSL/TLS, as that's the most common use case when accessing
+remote APIs.
+
+```objective-c
+// Base case - With server authentication SSL/TLS
+HLWGreeter *client = [[HLWGreeter alloc] initWithHost:@"localhost:50051"];
+// Same as using @"https://localhost:50051".
+...
+
+// No encryption
+HLWGreeter *client = [[HLWGreeter alloc] initWithHost:@"http://localhost:50051"];
+// Specifying the HTTP scheme explicitly forces no encryption.
+```
+
+###SSL/TLS for server authentication and encryption (Python)
+```python
+# Base case - No encryption
+stub = early_adopter_create_GreeterService_stub('localhost', 50051)
+...
+
+# With server authentication SSL/TLS
+stub = early_adopter_create_GreeterService_stub(
+ 'localhost', 50051, secure=True, root_certificates=open('ca.pem').read())
+...
+```
+n.b.: the beta API will look different
+
+###Authenticating with Google (Ruby)
+```ruby
+# Base case - No encryption/authorization
+stub = Helloworld::Greeter::Stub.new('localhost:50051')
+...
+
+# Authenticating with Google
+require 'googleauth' # from http://www.rubydoc.info/gems/googleauth/0.1.0
+...
+creds = GRPC::Core::Credentials.new(load_certs) # load_certs typically loads a CA roots file
+scope = 'https://www.googleapis.com/auth/grpc-testing'
+authorization = Google::Auth.get_application_default(scope)
+stub = Helloworld::Greeter::Stub.new('localhost:50051',
+ creds: creds,
+ update_metadata: authorization.updater_proc)
+```
+
+###Authenticating with Google (Node.js)
+
+```node
+// Base case - No encryption/authorization
+var stub = new helloworld.Greeter('localhost:50051');
+...
+// Authenticating with Google
+var GoogleAuth = require('google-auth-library'); // from https://www.npmjs.com/package/google-auth-library
+...
+var creds = grpc.Credentials.createSsl(load_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 stub = new helloworld.Greeter('localhost:50051',
+ {credentials: creds},
+ grpc.getGoogleAuthDelegate(auth));
+});
+```
+
+###Authenticating with Google (C#)
+```csharp
+// Base case - No encryption/authorization
+var channel = new Channel("localhost:50051");
+var client = new Greeter.GreeterClient(channel);
+...
+
+// Authenticating with Google
+using Grpc.Auth; // from Grpc.Auth NuGet package
+...
+var credentials = new SslCredentials(File.ReadAllText("ca.pem")); // Load a CA file
+var channel = new Channel("localhost:50051", credentials);
+
+string scope = "https://www.googleapis.com/auth/grpc-testing";
+var authorization = GoogleCredential.GetApplicationDefault();
+if (authorization.IsCreateScopedRequired)
+{
+ authorization = credential.CreateScoped(new[] { scope });
+}
+var client = new Greeter.GreeterClient(channel,
+ new StubConfiguration(OAuth2InterceptorFactory.Create(credential)));
+```
+
+###Authenticating with Google (PHP)
+```php
+// Base case - No encryption/authorization
+$client = new helloworld\GreeterClient(
+ new Grpc\BaseStub('localhost:50051', []));
+...
+
+// Authenticating with Google
+// 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('ca.pem'));
+ 'update_metadata' => $auth->getUpdateMetadataFunc(),
+];
+
+$client = new helloworld\GreeterClient(
+ new Grpc\BaseStub('localhost:50051', $opts));
+
+```
+
+###Authenticating with Google (Objective-C)
+
+This example uses the [Google iOS Sign-In library](https://developers.google.com/identity/sign-in/ios/),
+but it's easily extrapolated to any other OAuth2 library.
+
+```objective-c
+// Base case - No authentication
+[client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) {
+ ...
+}];
+
+...
+
+// Authenticating with Google
+
+// When signing the user in, ask her for the relevant scopes.
+GIDSignIn.sharedInstance.scopes = @[@"https://www.googleapis.com/auth/grpc-testing"];
+
+...
+
+#import <ProtoRPC/ProtoRPC.h>
+
+// Create a not-yet-started RPC. We want to set the request headers on this object before starting
+// it.
+ProtoRPC *call =
+ [client RPCToSayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) {
+ ...
+ }];
+
+// Set the access token to be used.
+NSString *accessToken = GIDSignIn.sharedInstance.currentUser.authentication.accessToken;
+call.requestMetadata[@"Authorization"] = [@"Bearer " stringByAppendingString:accessToken]}];
+
+// Start the RPC.
+[call start];
+```
+
+You can see a working example app, with a more detailed explanation, [here](examples/objective-c/auth_sample).
+
+### Authenticating with Google (Python)
+```python
+# Base case - No encryption
+stub = early_adopter_create_GreeterService_stub('localhost', 50051)
+...
+
+# With server authentication SSL/TLS
+import oauth2client.client
+credentials = oauth2client.GoogleCredentials.get_application_default()
+scope = 'https://www.googleapis.com/auth/grpc-testing'
+scoped_credentials = credentials.create_scoped([scope])
+access_token = scoped_credentials.get_access_token().access_token
+metadata_transformer = (
+ lambda x: [('Authorization', 'Bearer {}'.format(access_token))])
+
+stub = early_adopter_create_GreeterService_stub(
+ 'localhost', 50051, secure=True, root_certificates=open('ca.pem').read(),
+ metadata_transformer=metadata_transformer)
+...
+```
+n.b.: the beta API will look different