tree: 305b987aeda55bb16aeaf0e11a2d68ef5a53610e [path history] [tgz]
  1. credentials/
  2. test/
  3. _credentials.py
  4. async_customized_auth_client.py
  5. async_customized_auth_server.py
  6. BUILD.bazel
  7. customized_auth_client.py
  8. customized_auth_server.py
  9. README.md
  10. tls_client.py
  11. tls_server.py
  12. token_based_auth_client.py
  13. token_based_auth_server.py
examples/python/auth/README.md

Authentication Extension Example in gRPC Python

Check Our Guide First

For most common usage of authentication in gRPC Python, please see our Authentication guide's Python section. The Guide includes following scenarios:

  1. Server SSL credential setup
  2. Client SSL credential setup
  3. Authenticate with Google using a JWT
  4. Authenticate with Google using an Oauth2 token

Also, the guide talks about gRPC specific credential types.

Channel credentials

Channel credentials are attached to a Channel object, the most common use case are SSL credentials.

Call credentials

Call credentials are attached to a Call object (corresponding to an RPC). Under the hood, the call credentials is a function that takes in information of the RPC and modify metadata through callback.

About This Example

This example focuses on extending gRPC authentication mechanism:

  1. Customize authentication plugin;
  2. Composite client side credentials;
  3. Validation through interceptor on server side.

AuthMetadataPlugin: Manipulate metadata for each call

Unlike TLS/SSL based authentication, the authentication extension in gRPC Python lives at a much higher level of networking. It relies on the transmission of metadata (HTTP Header) between client and server, instead of alternating the transport protocol.

gRPC Python provides a way to intercept an RPC and append authentication related metadata through AuthMetadataPlugin. Those in need of a custom authentication method may simply provide a concrete implementation of the following interface:

class AuthMetadataPlugin:
    """A specification for custom authentication."""

    def __call__(self, context, callback):
        """Implements authentication by passing metadata to a callback.

        Implementations of this method must not block.

        Args:
          context: An AuthMetadataContext providing information on the RPC that
            the plugin is being called to authenticate.
          callback: An AuthMetadataPluginCallback to be invoked either
            synchronously or asynchronously.
        """

Then pass the instance of the concrete implementation to grpc.metadata_call_credentials function to be converted into a CallCredentials object. Please NOTE that it is possible to pass a Python function object directly, but we recommend to inherit from the base class to ensure implementation correctness.

def metadata_call_credentials(metadata_plugin, name=None):
    """Construct CallCredentials from an AuthMetadataPlugin.

    Args:
      metadata_plugin: An AuthMetadataPlugin to use for authentication.
      name: An optional name for the plugin.

    Returns:
      A CallCredentials.
    """

The CallCredentials object can be passed directly into an RPC like:

call_credentials = grpc.metadata_call_credentials(my_foo_plugin)
stub.FooRpc(request, credentials=call_credentials)

Or you can use ChannelCredentials and CallCredentials at the same time by combining them:

channel_credentials = ...
call_credentials = ...
composite_credentials = grpc.composite_channel_credentials(
    channel_credential,
    call_credentials)
channel = grpc.secure_channel(server_address, composite_credentials)

It is also possible to apply multiple CallCredentials to a single RPC:

call_credentials_foo = ...
call_credentials_bar = ...
call_credentials = grpc.composite_call_credentials(
    call_credentials_foo,
    call_credentials_bar)
stub.FooRpc(request, credentials=call_credentials)

Token-based authentication

Instead of AuthMetadataPlugin, you can also use token-based authentication mechanisms using OAuth2 tokens or other customized tokens.

OAuth2 tokens can be obtained using libraries like google-auth:

import google.auth

google_credentials, unused_project_id = google.auth.default()
call_credentials = grpc.access_token_call_credentials(google_credentials.token)

After obtaining the token, the rest of the flow is documented in token_based_auth_client.py and token_based_auth_server.py.