Jon Wayne Parrott | 53c7b17 | 2016-11-10 10:44:30 -0800 | [diff] [blame] | 1 | User Guide |
| 2 | ========== |
| 3 | |
| 4 | .. currentmodule:: google.auth |
| 5 | |
| 6 | Credentials and account types |
| 7 | ----------------------------- |
| 8 | |
| 9 | :class:`~credentials.Credentials` are the means of identifying an application or |
| 10 | user to a service or API. Credentials can be obtained with two different types |
| 11 | of accounts: *service accounts* and *user accounts*. |
| 12 | |
| 13 | Credentials from service accounts identify a particular application. These types |
| 14 | of credentials are used in server-to-server use cases, such as accessing a |
| 15 | database. This library primarily focuses on service account credentials. |
| 16 | |
| 17 | Credentials from user accounts are obtained by asking the user to authorize |
| 18 | access to their data. These types of credentials are used in cases where your |
| 19 | application needs access to a user's data in another service, such as accessing |
| 20 | a user's documents in Google Drive. This library provides no support for |
| 21 | obtaining user credentials, but does provide limited support for using user |
| 22 | credentials. |
| 23 | |
| 24 | Obtaining credentials |
| 25 | --------------------- |
| 26 | |
| 27 | .. _application-default: |
| 28 | |
| 29 | Application default credentials |
| 30 | +++++++++++++++++++++++++++++++ |
| 31 | |
| 32 | `Google Application Default Credentials`_ abstracts authentication across the |
| 33 | different Google Cloud Platform hosting environments. When running on any Google |
| 34 | Cloud hosting environment or when running locally with the `Google Cloud SDK`_ |
| 35 | installed, :func:`default` can automatically determine the credentials from the |
| 36 | environment:: |
| 37 | |
| 38 | import google.auth |
| 39 | |
| 40 | credentials, project = google.auth.default() |
| 41 | |
| 42 | If your application requires specific scopes:: |
| 43 | |
| 44 | credentials, project = google.auth.default( |
| 45 | scopes=['https://www.googleapis.com/auth/cloud-platform']) |
| 46 | |
| 47 | .. _Google Application Default Credentials: |
| 48 | https://developers.google.com/identity/protocols/ |
| 49 | application-default-credentials |
| 50 | .. _Google Cloud SDK: https://cloud.google.com/sdk |
| 51 | |
| 52 | |
| 53 | Service account private key files |
| 54 | +++++++++++++++++++++++++++++++++ |
| 55 | |
| 56 | A service account private key file can be used to obtain credentials for a |
| 57 | service account. You can create a private key using the `Credentials page of the |
| 58 | Google Cloud Console`_. Once you have a private key you can either obtain |
Alan Yee | 0958d7a | 2019-07-25 16:22:56 -0700 | [diff] [blame] | 59 | credentials one of three ways: |
Jon Wayne Parrott | 53c7b17 | 2016-11-10 10:44:30 -0800 | [diff] [blame] | 60 | |
| 61 | 1. Set the ``GOOGLE_APPLICATION_CREDENTIALS`` environment variable to the full |
| 62 | path to your service account private key file |
| 63 | |
| 64 | .. code-block:: bash |
| 65 | |
| 66 | $ export GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json |
| 67 | |
| 68 | Then, use :ref:`application default credentials <application-default>`. |
| 69 | :func:`default` checks for the ``GOOGLE_APPLICATION_CREDENTIALS`` |
| 70 | environment variable before all other checks, so this will always use the |
| 71 | credentials you explicitly specify. |
| 72 | |
| 73 | 2. Use :meth:`service_account.Credentials.from_service_account_file |
| 74 | <google.oauth2.service_account.Credentials.from_service_account_file>`:: |
| 75 | |
| 76 | from google.oauth2 import service_account |
| 77 | |
| 78 | credentials = service_account.Credentials.from_service_account_file( |
| 79 | '/path/to/key.json') |
| 80 | |
| 81 | scoped_credentials = credentials.with_scopes( |
| 82 | ['https://www.googleapis.com/auth/cloud-platform']) |
| 83 | |
Alan Yee | 0958d7a | 2019-07-25 16:22:56 -0700 | [diff] [blame] | 84 | 3. Use :meth:`service_account.Credentials.from_service_account_info |
| 85 | <google.oauth2.service_account.Credentials.from_service_account_info>`:: |
| 86 | |
| 87 | import json |
| 88 | |
| 89 | from google.oauth2 import service_account |
| 90 | |
| 91 | json_acct_info = json.loads(function_to_get_json_creds()) |
| 92 | credentials = service_account.Credentials.from_service_account_info( |
| 93 | json_acct_info) |
| 94 | |
| 95 | scoped_credentials = credentials.with_scopes( |
| 96 | ['https://www.googleapis.com/auth/cloud-platform']) |
| 97 | |
Jon Wayne Parrott | 53c7b17 | 2016-11-10 10:44:30 -0800 | [diff] [blame] | 98 | .. warning:: Private keys must be kept secret. If you expose your private key it |
| 99 | is recommended to revoke it immediately from the Google Cloud Console. |
| 100 | |
| 101 | .. _Credentials page of the Google Cloud Console: |
| 102 | https://console.cloud.google.com/apis/credentials |
| 103 | |
| 104 | Compute Engine, Container Engine, and the App Engine flexible environment |
| 105 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| 106 | |
| 107 | Applications running on `Compute Engine`_, `Container Engine`_, or the `App |
| 108 | Engine flexible environment`_ can obtain credentials provided by `Compute |
| 109 | Engine service accounts`_. When running on these platforms you can obtain |
| 110 | credentials for the service account one of two ways: |
| 111 | |
| 112 | 1. Use :ref:`application default credentials <application-default>`. |
| 113 | :func:`default` will automatically detect if these credentials are available. |
| 114 | |
| 115 | 2. Use :class:`compute_engine.Credentials`:: |
| 116 | |
| 117 | from google.auth import compute_engine |
| 118 | |
| 119 | credentials = compute_engine.Credentials() |
| 120 | |
| 121 | .. _Compute Engine: https://cloud.google.com/compute |
| 122 | .. _Container Engine: https://cloud.google.com/container-engine |
| 123 | .. _App Engine flexible environment: |
| 124 | https://cloud.google.com/appengine/docs/flexible/ |
| 125 | .. _Compute Engine service accounts: |
| 126 | https://cloud.google.com/compute/docs/access/service-accounts |
| 127 | |
| 128 | The App Engine standard environment |
| 129 | +++++++++++++++++++++++++++++++++++ |
| 130 | |
| 131 | Applications running on the `App Engine standard environment`_ can obtain |
| 132 | credentials provided by the `App Engine App Identity API`_. You can obtain |
| 133 | credentials one of two ways: |
| 134 | |
| 135 | 1. Use :ref:`application default credentials <application-default>`. |
| 136 | :func:`default` will automatically detect if these credentials are available. |
| 137 | |
| 138 | 2. Use :class:`app_engine.Credentials`:: |
| 139 | |
| 140 | from google.auth import app_engine |
| 141 | |
| 142 | credentials = app_engine.Credentials() |
| 143 | |
Hiranya Jayathilaka | 22d9094 | 2017-07-17 09:08:49 -0700 | [diff] [blame] | 144 | In order to make authenticated requests in the App Engine environment using the |
| 145 | credentials and transports provided by this library, you need to follow a few |
| 146 | additional steps: |
| 147 | |
| 148 | #. If you are using the :mod:`google.auth.transport.requests` transport, vendor |
Rohan Talip | b61cecd | 2018-05-29 08:48:25 -0700 | [diff] [blame] | 149 | in the `requests-toolbelt`_ library into your app, and enable the App Engine |
Hiranya Jayathilaka | 22d9094 | 2017-07-17 09:08:49 -0700 | [diff] [blame] | 150 | monkeypatch. Refer `App Engine documentation`_ for more details on this. |
Rohan Talip | b61cecd | 2018-05-29 08:48:25 -0700 | [diff] [blame] | 151 | #. To make HTTPS calls, enable the ``ssl`` library for your app by adding the |
Hiranya Jayathilaka | 22d9094 | 2017-07-17 09:08:49 -0700 | [diff] [blame] | 152 | following configuration to the ``app.yaml`` file:: |
| 153 | |
| 154 | libraries: |
| 155 | - name: ssl |
| 156 | version: latest |
| 157 | |
Rohan Talip | b61cecd | 2018-05-29 08:48:25 -0700 | [diff] [blame] | 158 | #. Enable billing for your App Engine project. Then enable socket support for |
Hiranya Jayathilaka | 22d9094 | 2017-07-17 09:08:49 -0700 | [diff] [blame] | 159 | your app. This can be achieved by setting an environment variable in the |
| 160 | ``app.yaml`` file:: |
| 161 | |
| 162 | env_variables: |
| 163 | GAE_USE_SOCKETS_HTTPLIB : 'true' |
| 164 | |
Jon Wayne Parrott | 53c7b17 | 2016-11-10 10:44:30 -0800 | [diff] [blame] | 165 | .. _App Engine standard environment: |
| 166 | https://cloud.google.com/appengine/docs/python |
| 167 | .. _App Engine App Identity API: |
| 168 | https://cloud.google.com/appengine/docs/python/appidentity/ |
Hiranya Jayathilaka | 22d9094 | 2017-07-17 09:08:49 -0700 | [diff] [blame] | 169 | .. _requests-toolbelt: |
| 170 | https://toolbelt.readthedocs.io/en/latest/ |
| 171 | .. _App Engine documentation: |
| 172 | https://cloud.google.com/appengine/docs/standard/python/issue-requests |
Jon Wayne Parrott | 53c7b17 | 2016-11-10 10:44:30 -0800 | [diff] [blame] | 173 | |
| 174 | User credentials |
| 175 | ++++++++++++++++ |
| 176 | |
| 177 | User credentials are typically obtained via `OAuth 2.0`_. This library does not |
Jon Wayne Parrott | 8170194 | 2017-03-01 14:03:38 -0800 | [diff] [blame] | 178 | provide any direct support for *obtaining* user credentials, however, you can |
| 179 | use user credentials with this library. You can use libraries such as |
| 180 | `oauthlib`_ to obtain the access token. After you have an access token, you |
Jon Wayne Parrott | 53c7b17 | 2016-11-10 10:44:30 -0800 | [diff] [blame] | 181 | can create a :class:`google.oauth2.credentials.Credentials` instance:: |
| 182 | |
| 183 | import google.oauth2.credentials |
| 184 | |
| 185 | credentials = google.oauth2.credentials.Credentials( |
| 186 | 'access_token') |
| 187 | |
| 188 | If you obtain a refresh token, you can also specify the refresh token and token |
| 189 | URI to allow the credentials to be automatically refreshed:: |
| 190 | |
| 191 | credentials = google.oauth2.credentials.Credentials( |
| 192 | 'access_token', |
| 193 | refresh_token='refresh_token', |
| 194 | token_uri='token_uri', |
| 195 | client_id='client_id', |
| 196 | client_secret='client_secret') |
| 197 | |
Jon Wayne Parrott | 8170194 | 2017-03-01 14:03:38 -0800 | [diff] [blame] | 198 | |
Jon Wayne Parrott | d47281b | 2017-03-22 13:45:26 -0700 | [diff] [blame] | 199 | There is a separate library, `google-auth-oauthlib`_, that has some helpers |
| 200 | for integrating with `requests-oauthlib`_ to provide support for obtaining |
| 201 | user credentials. You can use |
| 202 | :func:`google_auth_oauthlib.helpers.credentials_from_session` to obtain |
Jon Wayne Parrott | 8170194 | 2017-03-01 14:03:38 -0800 | [diff] [blame] | 203 | :class:`google.oauth2.credentials.Credentials` from a |
| 204 | :class:`requests_oauthlib.OAuth2Session` as above:: |
| 205 | |
Jon Wayne Parrott | d47281b | 2017-03-22 13:45:26 -0700 | [diff] [blame] | 206 | from google_auth_oauthlib.helpers import credentials_from_session |
Jon Wayne Parrott | 8170194 | 2017-03-01 14:03:38 -0800 | [diff] [blame] | 207 | |
Jon Wayne Parrott | d47281b | 2017-03-22 13:45:26 -0700 | [diff] [blame] | 208 | google_auth_credentials = credentials_from_session(oauth2session) |
Jon Wayne Parrott | 8170194 | 2017-03-01 14:03:38 -0800 | [diff] [blame] | 209 | |
Jon Wayne Parrott | d47281b | 2017-03-22 13:45:26 -0700 | [diff] [blame] | 210 | You can also use :class:`google_auth_oauthlib.flow.Flow` to perform the OAuth |
| 211 | 2.0 Authorization Grant Flow to obtain credentials using `requests-oauthlib`_. |
Jon Wayne Parrott | 8170194 | 2017-03-01 14:03:38 -0800 | [diff] [blame] | 212 | |
Jon Wayne Parrott | 53c7b17 | 2016-11-10 10:44:30 -0800 | [diff] [blame] | 213 | .. _OAuth 2.0: |
| 214 | https://developers.google.com/identity/protocols/OAuth2 |
| 215 | .. _oauthlib: |
| 216 | https://oauthlib.readthedocs.io/en/latest/ |
Jon Wayne Parrott | d47281b | 2017-03-22 13:45:26 -0700 | [diff] [blame] | 217 | .. _google-auth-oauthlib: |
| 218 | https://pypi.python.org/pypi/google-auth-oauthlib |
Jon Wayne Parrott | 8170194 | 2017-03-01 14:03:38 -0800 | [diff] [blame] | 219 | .. _requests-oauthlib: |
| 220 | https://requests-oauthlib.readthedocs.io/en/latest/ |
Jon Wayne Parrott | 53c7b17 | 2016-11-10 10:44:30 -0800 | [diff] [blame] | 221 | |
salrashid123 | 1fbc679 | 2018-11-09 11:05:34 -0800 | [diff] [blame] | 222 | Impersonated credentials |
| 223 | ++++++++++++++++++++++++ |
| 224 | |
| 225 | Impersonated Credentials allows one set of credentials issued to a user or service account |
Tianzi Cai | 4086543 | 2019-03-29 11:12:37 -0700 | [diff] [blame] | 226 | to impersonate another. The source credentials must be granted |
| 227 | the "Service Account Token Creator" IAM role. :: |
salrashid123 | 1fbc679 | 2018-11-09 11:05:34 -0800 | [diff] [blame] | 228 | |
| 229 | from google.auth import impersonated_credentials |
| 230 | |
| 231 | target_scopes = ['https://www.googleapis.com/auth/devstorage.read_only'] |
| 232 | source_credentials = service_account.Credentials.from_service_account_file( |
| 233 | '/path/to/svc_account.json', |
| 234 | scopes=target_scopes) |
| 235 | |
| 236 | target_credentials = impersonated_credentials.Credentials( |
| 237 | source_credentials=source_credentials, |
| 238 | target_principal='impersonated-account@_project_.iam.gserviceaccount.com', |
| 239 | target_scopes=target_scopes, |
| 240 | lifetime=500) |
| 241 | client = storage.Client(credentials=target_credentials) |
| 242 | buckets = client.list_buckets(project='your_project') |
| 243 | for bucket in buckets: |
salrashid123 | 7a8641a | 2019-08-07 14:31:33 -0700 | [diff] [blame] | 244 | print(bucket.name) |
salrashid123 | 1fbc679 | 2018-11-09 11:05:34 -0800 | [diff] [blame] | 245 | |
| 246 | |
| 247 | In the example above `source_credentials` does not have direct access to list buckets |
| 248 | in the target project. Using `ImpersonatedCredentials` will allow the source_credentials |
Tianzi Cai | 4086543 | 2019-03-29 11:12:37 -0700 | [diff] [blame] | 249 | to assume the identity of a target_principal that does have access. |
salrashid123 | 1fbc679 | 2018-11-09 11:05:34 -0800 | [diff] [blame] | 250 | |
salrashid123 | 7a8641a | 2019-08-07 14:31:33 -0700 | [diff] [blame] | 251 | Identity Tokens |
| 252 | +++++++++++++++ |
| 253 | |
| 254 | `Google OpenID Connect`_ tokens are avaiable through :mod:`Service Account <google.oauth2.service_account>`, |
| 255 | :mod:`Impersonated <google.auth.impersonated_credentials>`, |
| 256 | and :mod:`Compute Engine <google.auth.compute_engine>`. These tokens can be used to |
| 257 | authenticate against `Cloud Functions`_, `Cloud Run`_, a user service behind |
| 258 | `Identity Aware Proxy`_ or any other service capable of verifying a `Google ID Token`_. |
| 259 | |
| 260 | ServiceAccount :: |
| 261 | |
| 262 | from google.oauth2 import service_account |
| 263 | |
| 264 | target_audience = 'https://example.com' |
| 265 | |
| 266 | creds = service_account.IDTokenCredentials.from_service_account_file( |
| 267 | '/path/to/svc.json', |
| 268 | target_audience=target_audience) |
| 269 | |
| 270 | |
| 271 | Compute :: |
| 272 | |
| 273 | from google.auth import compute_engine |
| 274 | import google.auth.transport.requests |
| 275 | |
| 276 | target_audience = 'https://example.com' |
| 277 | |
| 278 | request = google.auth.transport.requests.Request() |
| 279 | creds = compute_engine.IDTokenCredentials(request, |
| 280 | target_audience=target_audience) |
| 281 | |
| 282 | Impersonated :: |
| 283 | |
| 284 | from google.auth import impersonated_credentials |
| 285 | |
| 286 | # get target_credentials from a source_credential |
| 287 | |
| 288 | target_audience = 'https://example.com' |
| 289 | |
| 290 | creds = impersonated_credentials.IDTokenCredentials( |
| 291 | target_credentials, |
| 292 | target_audience=target_audience) |
| 293 | |
Thea Flowers | e290a3d | 2020-04-01 10:11:42 -0700 | [diff] [blame^] | 294 | IDToken verification can be done for various type of IDTokens using the |
| 295 | :class:`google.oauth2.id_token` module. It supports ID token signed with RS256 |
| 296 | and ES256 algorithms. However, ES256 algorithm won't be available unless |
| 297 | `cryptography` dependency of version at least 1.4.0 is installed. You can check |
| 298 | the dependency with `pip freeze` or try `from google.auth.crypt import es256`. |
| 299 | The following is an example of verifying ID tokens: |
| 300 | |
| 301 | from google.auth2 import id_token |
| 302 | |
| 303 | request = google.auth.transport.requests.Request() |
| 304 | |
| 305 | try: |
| 306 | decoded_token = id_token.verify_token(token_to_verify,request) |
| 307 | except ValueError: |
| 308 | # Verification failed. |
salrashid123 | 7a8641a | 2019-08-07 14:31:33 -0700 | [diff] [blame] | 309 | |
| 310 | A sample end-to-end flow using an ID Token against a Cloud Run endpoint maybe :: |
| 311 | |
| 312 | from google.oauth2 import id_token |
| 313 | from google.oauth2 import service_account |
| 314 | import google.auth |
| 315 | import google.auth.transport.requests |
| 316 | from google.auth.transport.requests import AuthorizedSession |
| 317 | |
| 318 | target_audience = 'https://your-cloud-run-app.a.run.app' |
| 319 | url = 'https://your-cloud-run-app.a.run.app' |
| 320 | |
| 321 | creds = service_account.IDTokenCredentials.from_service_account_file( |
| 322 | '/path/to/svc.json', target_audience=target_audience) |
| 323 | |
| 324 | authed_session = AuthorizedSession(creds) |
| 325 | |
| 326 | # make authenticated request and print the response, status_code |
| 327 | resp = authed_session.get(url) |
| 328 | print(resp.status_code) |
| 329 | print(resp.text) |
| 330 | |
| 331 | # to verify an ID Token |
| 332 | request = google.auth.transport.requests.Request() |
| 333 | token = creds.token |
| 334 | print(token) |
| 335 | print(id_token.verify_token(token,request)) |
| 336 | |
| 337 | .. _Cloud Functions: https://cloud.google.com/functions/ |
| 338 | .. _Cloud Run: https://cloud.google.com/run/ |
| 339 | .. _Identity Aware Proxy: https://cloud.google.com/iap/ |
| 340 | .. _Google OpenID Connect: https://developers.google.com/identity/protocols/OpenIDConnect |
| 341 | .. _Google ID Token: https://developers.google.com/identity/protocols/OpenIDConnect#validatinganidtoken |
| 342 | |
Jon Wayne Parrott | 53c7b17 | 2016-11-10 10:44:30 -0800 | [diff] [blame] | 343 | Making authenticated requests |
| 344 | ----------------------------- |
| 345 | |
| 346 | Once you have credentials you can attach them to a *transport*. You can then |
| 347 | use this transport to make authenticated requests to APIs. google-auth supports |
| 348 | several different transports. Typically, it's up to your application or an |
| 349 | opinionated client library to decide which transport to use. |
| 350 | |
| 351 | Requests |
| 352 | ++++++++ |
| 353 | |
| 354 | The recommended HTTP transport is :mod:`google.auth.transport.requests` which |
| 355 | uses the `Requests`_ library. To make authenticated requests using Requests |
| 356 | you use a custom `Session`_ object:: |
| 357 | |
| 358 | from google.auth.transport.requests import AuthorizedSession |
| 359 | |
| 360 | authed_session = AuthorizedSession(credentials) |
| 361 | |
| 362 | response = authed_session.get( |
| 363 | 'https://www.googleapis.com/storage/v1/b') |
| 364 | |
| 365 | .. _Requests: http://docs.python-requests.org/en/master/ |
| 366 | .. _Session: http://docs.python-requests.org/en/master/user/advanced/#session-objects |
| 367 | |
| 368 | urllib3 |
| 369 | +++++++ |
| 370 | |
| 371 | :mod:`urllib3` is the underlying HTTP library used by Requests and can also be |
| 372 | used with google-auth. urllib3's interface isn't as high-level as Requests but |
| 373 | it can be useful in situations where you need more control over how HTTP |
| 374 | requests are made. To make authenticated requests using urllib3 create an |
| 375 | instance of :class:`google.auth.transport.urllib3.AuthorizedHttp`:: |
| 376 | |
| 377 | from google.auth.transport.urllib3 import AuthorizedHttp |
| 378 | |
| 379 | authed_http = AuthorizedHttp(credentials) |
| 380 | |
| 381 | response = authed_http.request( |
| 382 | 'GET', 'https://www.googleapis.com/storage/v1/b') |
| 383 | |
| 384 | You can also construct your own :class:`urllib3.PoolManager` instance and pass |
| 385 | it to :class:`~google.auth.transport.urllib3.AuthorizedHttp`:: |
| 386 | |
| 387 | import urllib3 |
| 388 | |
| 389 | http = urllib3.PoolManager() |
| 390 | authed_http = AuthorizedHttp(credentials, http) |
| 391 | |
| 392 | gRPC |
| 393 | ++++ |
| 394 | |
| 395 | `gRPC`_ is an RPC framework that uses `Protocol Buffers`_ over `HTTP 2.0`_. |
| 396 | google-auth can provide `Call Credentials`_ for gRPC. The easiest way to do |
| 397 | this is to use google-auth to create the gRPC channel:: |
| 398 | |
| 399 | import google.auth.transport.grpc |
| 400 | import google.auth.transport.requests |
| 401 | |
| 402 | http_request = google.auth.transport.requests.Request() |
| 403 | |
| 404 | channel = google.auth.transport.grpc.secure_authorized_channel( |
Jon Wayne Parrott | 840b3ac | 2016-11-10 12:07:51 -0800 | [diff] [blame] | 405 | credentials, http_request, 'pubsub.googleapis.com:443') |
Jon Wayne Parrott | 53c7b17 | 2016-11-10 10:44:30 -0800 | [diff] [blame] | 406 | |
| 407 | .. note:: Even though gRPC is its own transport, you still need to use one of |
| 408 | the other HTTP transports with gRPC. The reason is that most credential |
| 409 | types need to make HTTP requests in order to refresh their access token. |
| 410 | The sample above uses the Requests transport, but any HTTP transport can |
| 411 | be used. Additionally, if you know that your credentials do not need to |
| 412 | make HTTP requests in order to refresh (as is the case with |
| 413 | :class:`jwt.Credentials`) then you can specify ``None``. |
| 414 | |
| 415 | Alternatively, you can create the channel yourself and use |
| 416 | :class:`google.auth.transport.grpc.AuthMetadataPlugin`:: |
| 417 | |
| 418 | import grpc |
| 419 | |
| 420 | metadata_plugin = AuthMetadataPlugin(credentials, http_request) |
| 421 | |
| 422 | # Create a set of grpc.CallCredentials using the metadata plugin. |
| 423 | google_auth_credentials = grpc.metadata_call_credentials( |
| 424 | metadata_plugin) |
| 425 | |
| 426 | # Create SSL channel credentials. |
| 427 | ssl_credentials = grpc.ssl_channel_credentials() |
| 428 | |
| 429 | # Combine the ssl credentials and the authorization credentials. |
| 430 | composite_credentials = grpc.composite_channel_credentials( |
| 431 | ssl_credentials, google_auth_credentials) |
| 432 | |
| 433 | channel = grpc.secure_channel( |
| 434 | 'pubsub.googleapis.com:443', composite_credentials) |
| 435 | |
| 436 | You can use this channel to make a gRPC stub that makes authenticated requests |
| 437 | to a gRPC service:: |
| 438 | |
| 439 | from google.pubsub.v1 import pubsub_pb2 |
| 440 | |
| 441 | pubsub = pubsub_pb2.PublisherStub(channel) |
| 442 | |
| 443 | response = pubsub.ListTopics( |
| 444 | pubsub_pb2.ListTopicsRequest(project='your-project')) |
| 445 | |
| 446 | |
| 447 | .. _gRPC: http://www.grpc.io/ |
| 448 | .. _Protocol Buffers: |
| 449 | https://developers.google.com/protocol-buffers/docs/overview |
| 450 | .. _HTTP 2.0: |
| 451 | http://www.grpc.io/docs/guides/wire.html |
| 452 | .. _Call Credentials: |
| 453 | http://www.grpc.io/docs/guides/auth.html |