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 |
bojeil-google | d4d7f38 | 2021-02-16 12:33:20 -0800 | [diff] [blame] | 10 | user to a service or API. Credentials can be obtained with three different types |
| 11 | of accounts: *service accounts*, *user accounts* and *external accounts*. |
Jon Wayne Parrott | 53c7b17 | 2016-11-10 10:44:30 -0800 | [diff] [blame] | 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 | |
bojeil-google | d4d7f38 | 2021-02-16 12:33:20 -0800 | [diff] [blame] | 24 | Credentials from external accounts (workload identity federation) are used to |
| 25 | identify a particular application from an on-prem or non-Google Cloud platform |
| 26 | including Amazon Web Services (AWS), Microsoft Azure or any identity provider |
| 27 | that supports OpenID Connect (OIDC). |
| 28 | |
Jon Wayne Parrott | 53c7b17 | 2016-11-10 10:44:30 -0800 | [diff] [blame] | 29 | Obtaining credentials |
| 30 | --------------------- |
| 31 | |
| 32 | .. _application-default: |
| 33 | |
| 34 | Application default credentials |
| 35 | +++++++++++++++++++++++++++++++ |
| 36 | |
| 37 | `Google Application Default Credentials`_ abstracts authentication across the |
| 38 | different Google Cloud Platform hosting environments. When running on any Google |
| 39 | Cloud hosting environment or when running locally with the `Google Cloud SDK`_ |
| 40 | installed, :func:`default` can automatically determine the credentials from the |
| 41 | environment:: |
| 42 | |
| 43 | import google.auth |
| 44 | |
| 45 | credentials, project = google.auth.default() |
| 46 | |
| 47 | If your application requires specific scopes:: |
| 48 | |
| 49 | credentials, project = google.auth.default( |
| 50 | scopes=['https://www.googleapis.com/auth/cloud-platform']) |
| 51 | |
bojeil-google | d4d7f38 | 2021-02-16 12:33:20 -0800 | [diff] [blame] | 52 | Application Default Credentials also support workload identity federation to |
| 53 | access Google Cloud resources from non-Google Cloud platforms including Amazon |
| 54 | Web Services (AWS), Microsoft Azure or any identity provider that supports |
| 55 | OpenID Connect (OIDC). Workload identity federation is recommended for |
| 56 | non-Google Cloud environments as it avoids the need to download, manage and |
| 57 | store service account private keys locally. |
| 58 | |
Jon Wayne Parrott | 53c7b17 | 2016-11-10 10:44:30 -0800 | [diff] [blame] | 59 | .. _Google Application Default Credentials: |
| 60 | https://developers.google.com/identity/protocols/ |
| 61 | application-default-credentials |
| 62 | .. _Google Cloud SDK: https://cloud.google.com/sdk |
| 63 | |
| 64 | |
| 65 | Service account private key files |
| 66 | +++++++++++++++++++++++++++++++++ |
| 67 | |
| 68 | A service account private key file can be used to obtain credentials for a |
| 69 | service account. You can create a private key using the `Credentials page of the |
| 70 | 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] | 71 | credentials one of three ways: |
Jon Wayne Parrott | 53c7b17 | 2016-11-10 10:44:30 -0800 | [diff] [blame] | 72 | |
| 73 | 1. Set the ``GOOGLE_APPLICATION_CREDENTIALS`` environment variable to the full |
| 74 | path to your service account private key file |
| 75 | |
| 76 | .. code-block:: bash |
| 77 | |
| 78 | $ export GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json |
| 79 | |
| 80 | Then, use :ref:`application default credentials <application-default>`. |
| 81 | :func:`default` checks for the ``GOOGLE_APPLICATION_CREDENTIALS`` |
| 82 | environment variable before all other checks, so this will always use the |
| 83 | credentials you explicitly specify. |
| 84 | |
| 85 | 2. Use :meth:`service_account.Credentials.from_service_account_file |
| 86 | <google.oauth2.service_account.Credentials.from_service_account_file>`:: |
| 87 | |
| 88 | from google.oauth2 import service_account |
| 89 | |
| 90 | credentials = service_account.Credentials.from_service_account_file( |
| 91 | '/path/to/key.json') |
| 92 | |
| 93 | scoped_credentials = credentials.with_scopes( |
| 94 | ['https://www.googleapis.com/auth/cloud-platform']) |
| 95 | |
Alan Yee | 0958d7a | 2019-07-25 16:22:56 -0700 | [diff] [blame] | 96 | 3. Use :meth:`service_account.Credentials.from_service_account_info |
| 97 | <google.oauth2.service_account.Credentials.from_service_account_info>`:: |
| 98 | |
| 99 | import json |
| 100 | |
| 101 | from google.oauth2 import service_account |
| 102 | |
| 103 | json_acct_info = json.loads(function_to_get_json_creds()) |
| 104 | credentials = service_account.Credentials.from_service_account_info( |
| 105 | json_acct_info) |
| 106 | |
| 107 | scoped_credentials = credentials.with_scopes( |
| 108 | ['https://www.googleapis.com/auth/cloud-platform']) |
| 109 | |
Jon Wayne Parrott | 53c7b17 | 2016-11-10 10:44:30 -0800 | [diff] [blame] | 110 | .. warning:: Private keys must be kept secret. If you expose your private key it |
| 111 | is recommended to revoke it immediately from the Google Cloud Console. |
| 112 | |
| 113 | .. _Credentials page of the Google Cloud Console: |
| 114 | https://console.cloud.google.com/apis/credentials |
| 115 | |
| 116 | Compute Engine, Container Engine, and the App Engine flexible environment |
| 117 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| 118 | |
| 119 | Applications running on `Compute Engine`_, `Container Engine`_, or the `App |
| 120 | Engine flexible environment`_ can obtain credentials provided by `Compute |
| 121 | Engine service accounts`_. When running on these platforms you can obtain |
| 122 | credentials for the service account one of two ways: |
| 123 | |
| 124 | 1. Use :ref:`application default credentials <application-default>`. |
| 125 | :func:`default` will automatically detect if these credentials are available. |
| 126 | |
| 127 | 2. Use :class:`compute_engine.Credentials`:: |
| 128 | |
| 129 | from google.auth import compute_engine |
| 130 | |
| 131 | credentials = compute_engine.Credentials() |
| 132 | |
| 133 | .. _Compute Engine: https://cloud.google.com/compute |
| 134 | .. _Container Engine: https://cloud.google.com/container-engine |
| 135 | .. _App Engine flexible environment: |
| 136 | https://cloud.google.com/appengine/docs/flexible/ |
| 137 | .. _Compute Engine service accounts: |
| 138 | https://cloud.google.com/compute/docs/access/service-accounts |
| 139 | |
| 140 | The App Engine standard environment |
| 141 | +++++++++++++++++++++++++++++++++++ |
| 142 | |
| 143 | Applications running on the `App Engine standard environment`_ can obtain |
| 144 | credentials provided by the `App Engine App Identity API`_. You can obtain |
| 145 | credentials one of two ways: |
| 146 | |
| 147 | 1. Use :ref:`application default credentials <application-default>`. |
| 148 | :func:`default` will automatically detect if these credentials are available. |
| 149 | |
| 150 | 2. Use :class:`app_engine.Credentials`:: |
| 151 | |
| 152 | from google.auth import app_engine |
| 153 | |
| 154 | credentials = app_engine.Credentials() |
| 155 | |
Hiranya Jayathilaka | 22d9094 | 2017-07-17 09:08:49 -0700 | [diff] [blame] | 156 | In order to make authenticated requests in the App Engine environment using the |
| 157 | credentials and transports provided by this library, you need to follow a few |
| 158 | additional steps: |
| 159 | |
| 160 | #. If you are using the :mod:`google.auth.transport.requests` transport, vendor |
Rohan Talip | b61cecd | 2018-05-29 08:48:25 -0700 | [diff] [blame] | 161 | 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] | 162 | monkeypatch. Refer `App Engine documentation`_ for more details on this. |
Rohan Talip | b61cecd | 2018-05-29 08:48:25 -0700 | [diff] [blame] | 163 | #. 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] | 164 | following configuration to the ``app.yaml`` file:: |
| 165 | |
| 166 | libraries: |
| 167 | - name: ssl |
| 168 | version: latest |
| 169 | |
Rohan Talip | b61cecd | 2018-05-29 08:48:25 -0700 | [diff] [blame] | 170 | #. Enable billing for your App Engine project. Then enable socket support for |
Hiranya Jayathilaka | 22d9094 | 2017-07-17 09:08:49 -0700 | [diff] [blame] | 171 | your app. This can be achieved by setting an environment variable in the |
| 172 | ``app.yaml`` file:: |
| 173 | |
| 174 | env_variables: |
| 175 | GAE_USE_SOCKETS_HTTPLIB : 'true' |
| 176 | |
Jon Wayne Parrott | 53c7b17 | 2016-11-10 10:44:30 -0800 | [diff] [blame] | 177 | .. _App Engine standard environment: |
| 178 | https://cloud.google.com/appengine/docs/python |
| 179 | .. _App Engine App Identity API: |
| 180 | https://cloud.google.com/appengine/docs/python/appidentity/ |
Hiranya Jayathilaka | 22d9094 | 2017-07-17 09:08:49 -0700 | [diff] [blame] | 181 | .. _requests-toolbelt: |
| 182 | https://toolbelt.readthedocs.io/en/latest/ |
| 183 | .. _App Engine documentation: |
| 184 | https://cloud.google.com/appengine/docs/standard/python/issue-requests |
Jon Wayne Parrott | 53c7b17 | 2016-11-10 10:44:30 -0800 | [diff] [blame] | 185 | |
| 186 | User credentials |
| 187 | ++++++++++++++++ |
| 188 | |
| 189 | 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] | 190 | provide any direct support for *obtaining* user credentials, however, you can |
| 191 | use user credentials with this library. You can use libraries such as |
| 192 | `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] | 193 | can create a :class:`google.oauth2.credentials.Credentials` instance:: |
| 194 | |
| 195 | import google.oauth2.credentials |
| 196 | |
| 197 | credentials = google.oauth2.credentials.Credentials( |
| 198 | 'access_token') |
| 199 | |
| 200 | If you obtain a refresh token, you can also specify the refresh token and token |
| 201 | URI to allow the credentials to be automatically refreshed:: |
| 202 | |
| 203 | credentials = google.oauth2.credentials.Credentials( |
| 204 | 'access_token', |
| 205 | refresh_token='refresh_token', |
| 206 | token_uri='token_uri', |
| 207 | client_id='client_id', |
| 208 | client_secret='client_secret') |
| 209 | |
Jon Wayne Parrott | 8170194 | 2017-03-01 14:03:38 -0800 | [diff] [blame] | 210 | |
Jon Wayne Parrott | d47281b | 2017-03-22 13:45:26 -0700 | [diff] [blame] | 211 | There is a separate library, `google-auth-oauthlib`_, that has some helpers |
| 212 | for integrating with `requests-oauthlib`_ to provide support for obtaining |
| 213 | user credentials. You can use |
| 214 | :func:`google_auth_oauthlib.helpers.credentials_from_session` to obtain |
Jon Wayne Parrott | 8170194 | 2017-03-01 14:03:38 -0800 | [diff] [blame] | 215 | :class:`google.oauth2.credentials.Credentials` from a |
| 216 | :class:`requests_oauthlib.OAuth2Session` as above:: |
| 217 | |
Jon Wayne Parrott | d47281b | 2017-03-22 13:45:26 -0700 | [diff] [blame] | 218 | from google_auth_oauthlib.helpers import credentials_from_session |
Jon Wayne Parrott | 8170194 | 2017-03-01 14:03:38 -0800 | [diff] [blame] | 219 | |
Jon Wayne Parrott | d47281b | 2017-03-22 13:45:26 -0700 | [diff] [blame] | 220 | google_auth_credentials = credentials_from_session(oauth2session) |
Jon Wayne Parrott | 8170194 | 2017-03-01 14:03:38 -0800 | [diff] [blame] | 221 | |
Jon Wayne Parrott | d47281b | 2017-03-22 13:45:26 -0700 | [diff] [blame] | 222 | You can also use :class:`google_auth_oauthlib.flow.Flow` to perform the OAuth |
| 223 | 2.0 Authorization Grant Flow to obtain credentials using `requests-oauthlib`_. |
Jon Wayne Parrott | 8170194 | 2017-03-01 14:03:38 -0800 | [diff] [blame] | 224 | |
Jon Wayne Parrott | 53c7b17 | 2016-11-10 10:44:30 -0800 | [diff] [blame] | 225 | .. _OAuth 2.0: |
| 226 | https://developers.google.com/identity/protocols/OAuth2 |
| 227 | .. _oauthlib: |
| 228 | https://oauthlib.readthedocs.io/en/latest/ |
Jon Wayne Parrott | d47281b | 2017-03-22 13:45:26 -0700 | [diff] [blame] | 229 | .. _google-auth-oauthlib: |
| 230 | https://pypi.python.org/pypi/google-auth-oauthlib |
Jon Wayne Parrott | 8170194 | 2017-03-01 14:03:38 -0800 | [diff] [blame] | 231 | .. _requests-oauthlib: |
| 232 | https://requests-oauthlib.readthedocs.io/en/latest/ |
Jon Wayne Parrott | 53c7b17 | 2016-11-10 10:44:30 -0800 | [diff] [blame] | 233 | |
bojeil-google | d4d7f38 | 2021-02-16 12:33:20 -0800 | [diff] [blame] | 234 | External credentials (Workload identity federation) |
| 235 | +++++++++++++++++++++++++++++++++++++++++++++++++++ |
| 236 | |
| 237 | Using workload identity federation, your application can access Google Cloud |
| 238 | resources from Amazon Web Services (AWS), Microsoft Azure or any identity |
| 239 | provider that supports OpenID Connect (OIDC). |
| 240 | |
| 241 | Traditionally, applications running outside Google Cloud have used service |
| 242 | account keys to access Google Cloud resources. Using identity federation, |
| 243 | you can allow your workload to impersonate a service account. |
| 244 | This lets you access Google Cloud resources directly, eliminating the |
| 245 | maintenance and security burden associated with service account keys. |
| 246 | |
| 247 | Accessing resources from AWS |
| 248 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 249 | |
| 250 | In order to access Google Cloud resources from Amazon Web Services (AWS), the |
| 251 | following requirements are needed: |
| 252 | |
| 253 | - A workload identity pool needs to be created. |
| 254 | - AWS needs to be added as an identity provider in the workload identity pool |
| 255 | (The Google organization policy needs to allow federation from AWS). |
| 256 | - Permission to impersonate a service account needs to be granted to the |
| 257 | external identity. |
| 258 | - A credential configuration file needs to be generated. Unlike service account |
| 259 | credential files, the generated credential configuration file will only |
| 260 | contain non-sensitive metadata to instruct the library on how to retrieve |
| 261 | external subject tokens and exchange them for service account access tokens. |
| 262 | |
| 263 | Follow the detailed instructions on how to |
| 264 | `Configure Workload Identity Federation from AWS`_. |
| 265 | |
| 266 | .. _Configure Workload Identity Federation from AWS: |
| 267 | https://cloud.google.com/iam/docs/access-resources-aws |
| 268 | |
| 269 | Accessing resources from Microsoft Azure |
| 270 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 271 | |
| 272 | In order to access Google Cloud resources from Microsoft Azure, the following |
| 273 | requirements are needed: |
| 274 | |
| 275 | - A workload identity pool needs to be created. |
| 276 | - Azure needs to be added as an identity provider in the workload identity pool |
| 277 | (The Google organization policy needs to allow federation from Azure). |
| 278 | - The Azure tenant needs to be configured for identity federation. |
| 279 | - Permission to impersonate a service account needs to be granted to the |
| 280 | external identity. |
| 281 | - A credential configuration file needs to be generated. Unlike service account |
| 282 | credential files, the generated credential configuration file will only |
| 283 | contain non-sensitive metadata to instruct the library on how to retrieve |
| 284 | external subject tokens and exchange them for service account access tokens. |
| 285 | |
| 286 | Follow the detailed instructions on how to |
| 287 | `Configure Workload Identity Federation from Microsoft Azure`_. |
| 288 | |
| 289 | .. _Configure Workload Identity Federation from Microsoft Azure: |
| 290 | https://cloud.google.com/iam/docs/access-resources-azure |
| 291 | |
| 292 | Accessing resources from an OIDC identity provider |
| 293 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 294 | |
| 295 | In order to access Google Cloud resources from an identity provider that |
| 296 | supports `OpenID Connect (OIDC)`_, the following requirements are needed: |
| 297 | |
| 298 | - A workload identity pool needs to be created. |
| 299 | - An OIDC identity provider needs to be added in the workload identity pool |
| 300 | (The Google organization policy needs to allow federation from the identity |
| 301 | provider). |
| 302 | - Permission to impersonate a service account needs to be granted to the |
| 303 | external identity. |
| 304 | - A credential configuration file needs to be generated. Unlike service account |
| 305 | credential files, the generated credential configuration file will only |
| 306 | contain non-sensitive metadata to instruct the library on how to retrieve |
| 307 | external subject tokens and exchange them for service account access tokens. |
| 308 | |
| 309 | For OIDC providers, the Auth library can retrieve OIDC tokens either from a |
| 310 | local file location (file-sourced credentials) or from a local server |
| 311 | (URL-sourced credentials). |
| 312 | |
| 313 | - For file-sourced credentials, a background process needs to be continuously |
| 314 | refreshing the file location with a new OIDC token prior to expiration. |
| 315 | For tokens with one hour lifetimes, the token needs to be updated in the file |
| 316 | every hour. The token can be stored directly as plain text or in JSON format. |
| 317 | - For URL-sourced credentials, a local server needs to host a GET endpoint to |
| 318 | return the OIDC token. The response can be in plain text or JSON. |
| 319 | Additional required request headers can also be specified. |
| 320 | |
| 321 | Follow the detailed instructions on how to |
| 322 | `Configure Workload Identity Federation from an OIDC identity provider`_. |
| 323 | |
| 324 | .. _OpenID Connect (OIDC): |
| 325 | https://openid.net/connect/ |
| 326 | .. _Configure Workload Identity Federation from an OIDC identity provider: |
| 327 | https://cloud.google.com/iam/docs/access-resources-oidc |
| 328 | |
| 329 | Using External Identities |
| 330 | ~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 331 | |
| 332 | External identities (AWS, Azure and OIDC identity providers) can be used with |
| 333 | Application Default Credentials. |
| 334 | In order to use external identities with Application Default Credentials, you |
| 335 | need to generate the JSON credentials configuration file for your external |
| 336 | identity. |
| 337 | Once generated, store the path to this file in the |
| 338 | ``GOOGLE_APPLICATION_CREDENTIALS`` environment variable. |
| 339 | |
| 340 | .. code-block:: bash |
| 341 | |
| 342 | $ export GOOGLE_APPLICATION_CREDENTIALS=/path/to/config.json |
| 343 | |
| 344 | The library can now automatically choose the right type of client and initialize |
| 345 | credentials from the context provided in the configuration file:: |
| 346 | |
| 347 | import google.auth |
| 348 | |
| 349 | credentials, project = google.auth.default() |
| 350 | |
| 351 | When using external identities with Application Default Credentials, |
| 352 | the ``roles/browser`` role needs to be granted to the service account. |
| 353 | The ``Cloud Resource Manager API`` should also be enabled on the project. |
| 354 | This is needed since :func:`default` will try to auto-discover the project ID |
| 355 | from the current environment using the impersonated credential. |
| 356 | Otherwise, the project ID will resolve to ``None``. You can override the project |
| 357 | detection by setting the ``GOOGLE_CLOUD_PROJECT`` environment variable. |
| 358 | |
| 359 | You can also explicitly initialize external account clients using the generated |
| 360 | configuration file. |
| 361 | |
| 362 | For Azure and OIDC providers, use :meth:`identity_pool.Credentials.from_info |
| 363 | <google.auth.identity_pool.Credentials.from_info>` or |
| 364 | :meth:`identity_pool.Credentials.from_file |
| 365 | <google.auth.identity_pool.Credentials.from_file>`:: |
| 366 | |
| 367 | import json |
| 368 | |
| 369 | from google.auth import identity_pool |
| 370 | |
| 371 | json_config_info = json.loads(function_to_get_json_config()) |
| 372 | credentials = identity_pool.Credentials.from_info(json_config_info) |
| 373 | scoped_credentials = credentials.with_scopes( |
| 374 | ['https://www.googleapis.com/auth/cloud-platform']) |
| 375 | |
| 376 | For AWS providers, use :meth:`aws.Credentials.from_info |
| 377 | <google.auth.aws.Credentials.from_info>` or |
| 378 | :meth:`aws.Credentials.from_file |
| 379 | <google.auth.aws.Credentials.from_file>`:: |
| 380 | |
| 381 | import json |
| 382 | |
| 383 | from google.auth import aws |
| 384 | |
| 385 | json_config_info = json.loads(function_to_get_json_config()) |
| 386 | credentials = aws.Credentials.from_info(json_config_info) |
| 387 | scoped_credentials = credentials.with_scopes( |
| 388 | ['https://www.googleapis.com/auth/cloud-platform']) |
| 389 | |
| 390 | |
salrashid123 | 1fbc679 | 2018-11-09 11:05:34 -0800 | [diff] [blame] | 391 | Impersonated credentials |
| 392 | ++++++++++++++++++++++++ |
| 393 | |
| 394 | 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] | 395 | to impersonate another. The source credentials must be granted |
| 396 | the "Service Account Token Creator" IAM role. :: |
salrashid123 | 1fbc679 | 2018-11-09 11:05:34 -0800 | [diff] [blame] | 397 | |
| 398 | from google.auth import impersonated_credentials |
| 399 | |
| 400 | target_scopes = ['https://www.googleapis.com/auth/devstorage.read_only'] |
| 401 | source_credentials = service_account.Credentials.from_service_account_file( |
| 402 | '/path/to/svc_account.json', |
| 403 | scopes=target_scopes) |
| 404 | |
| 405 | target_credentials = impersonated_credentials.Credentials( |
| 406 | source_credentials=source_credentials, |
| 407 | target_principal='impersonated-account@_project_.iam.gserviceaccount.com', |
| 408 | target_scopes=target_scopes, |
| 409 | lifetime=500) |
| 410 | client = storage.Client(credentials=target_credentials) |
| 411 | buckets = client.list_buckets(project='your_project') |
| 412 | for bucket in buckets: |
salrashid123 | 7a8641a | 2019-08-07 14:31:33 -0700 | [diff] [blame] | 413 | print(bucket.name) |
salrashid123 | 1fbc679 | 2018-11-09 11:05:34 -0800 | [diff] [blame] | 414 | |
| 415 | |
| 416 | In the example above `source_credentials` does not have direct access to list buckets |
| 417 | in the target project. Using `ImpersonatedCredentials` will allow the source_credentials |
Tianzi Cai | 4086543 | 2019-03-29 11:12:37 -0700 | [diff] [blame] | 418 | to assume the identity of a target_principal that does have access. |
salrashid123 | 1fbc679 | 2018-11-09 11:05:34 -0800 | [diff] [blame] | 419 | |
salrashid123 | 7a8641a | 2019-08-07 14:31:33 -0700 | [diff] [blame] | 420 | Identity Tokens |
| 421 | +++++++++++++++ |
| 422 | |
DanielLearner | 684457a | 2021-02-11 14:20:03 -0600 | [diff] [blame] | 423 | `Google OpenID Connect`_ tokens are available through :mod:`Service Account <google.oauth2.service_account>`, |
salrashid123 | 7a8641a | 2019-08-07 14:31:33 -0700 | [diff] [blame] | 424 | :mod:`Impersonated <google.auth.impersonated_credentials>`, |
| 425 | and :mod:`Compute Engine <google.auth.compute_engine>`. These tokens can be used to |
| 426 | authenticate against `Cloud Functions`_, `Cloud Run`_, a user service behind |
| 427 | `Identity Aware Proxy`_ or any other service capable of verifying a `Google ID Token`_. |
| 428 | |
| 429 | ServiceAccount :: |
| 430 | |
| 431 | from google.oauth2 import service_account |
| 432 | |
| 433 | target_audience = 'https://example.com' |
| 434 | |
| 435 | creds = service_account.IDTokenCredentials.from_service_account_file( |
| 436 | '/path/to/svc.json', |
| 437 | target_audience=target_audience) |
| 438 | |
| 439 | |
| 440 | Compute :: |
| 441 | |
| 442 | from google.auth import compute_engine |
| 443 | import google.auth.transport.requests |
| 444 | |
| 445 | target_audience = 'https://example.com' |
| 446 | |
| 447 | request = google.auth.transport.requests.Request() |
| 448 | creds = compute_engine.IDTokenCredentials(request, |
| 449 | target_audience=target_audience) |
| 450 | |
| 451 | Impersonated :: |
| 452 | |
| 453 | from google.auth import impersonated_credentials |
| 454 | |
| 455 | # get target_credentials from a source_credential |
| 456 | |
| 457 | target_audience = 'https://example.com' |
| 458 | |
| 459 | creds = impersonated_credentials.IDTokenCredentials( |
| 460 | target_credentials, |
| 461 | target_audience=target_audience) |
| 462 | |
arithmetic1728 | 506c565 | 2020-04-01 10:34:37 -0700 | [diff] [blame] | 463 | If your application runs on `App Engine`_, `Cloud Run`_, `Compute Engine`_, or |
| 464 | has application default credentials set via `GOOGLE_APPLICATION_CREDENTIALS` |
| 465 | environment variable, you can also use `google.oauth2.id_token.fetch_id_token` |
| 466 | to obtain an ID token from your current running environment. The following is an |
| 467 | example :: |
| 468 | |
| 469 | import google.oauth2.id_token |
| 470 | import google.auth.transport.requests |
| 471 | |
| 472 | request = google.auth.transport.requests.Request() |
| 473 | target_audience = "https://pubsub.googleapis.com" |
| 474 | |
| 475 | id_token = google.oauth2.id_token.fetch_id_token(request, target_audience) |
| 476 | |
Thea Flowers | e290a3d | 2020-04-01 10:11:42 -0700 | [diff] [blame] | 477 | IDToken verification can be done for various type of IDTokens using the |
| 478 | :class:`google.oauth2.id_token` module. It supports ID token signed with RS256 |
| 479 | and ES256 algorithms. However, ES256 algorithm won't be available unless |
| 480 | `cryptography` dependency of version at least 1.4.0 is installed. You can check |
| 481 | the dependency with `pip freeze` or try `from google.auth.crypt import es256`. |
Matt Seymour | 4fd84bd | 2021-07-08 18:33:42 +0100 | [diff] [blame] | 482 | The following is an example of verifying ID tokens :: |
Thea Flowers | e290a3d | 2020-04-01 10:11:42 -0700 | [diff] [blame] | 483 | |
| 484 | from google.auth2 import id_token |
| 485 | |
| 486 | request = google.auth.transport.requests.Request() |
| 487 | |
| 488 | try: |
Matt Seymour | 4fd84bd | 2021-07-08 18:33:42 +0100 | [diff] [blame] | 489 | decoded_token = id_token.verify_token(token_to_verify,request) |
Thea Flowers | e290a3d | 2020-04-01 10:11:42 -0700 | [diff] [blame] | 490 | except ValueError: |
Matt Seymour | 4fd84bd | 2021-07-08 18:33:42 +0100 | [diff] [blame] | 491 | # Verification failed. |
salrashid123 | 7a8641a | 2019-08-07 14:31:33 -0700 | [diff] [blame] | 492 | |
| 493 | A sample end-to-end flow using an ID Token against a Cloud Run endpoint maybe :: |
| 494 | |
| 495 | from google.oauth2 import id_token |
| 496 | from google.oauth2 import service_account |
| 497 | import google.auth |
| 498 | import google.auth.transport.requests |
| 499 | from google.auth.transport.requests import AuthorizedSession |
| 500 | |
| 501 | target_audience = 'https://your-cloud-run-app.a.run.app' |
| 502 | url = 'https://your-cloud-run-app.a.run.app' |
| 503 | |
| 504 | creds = service_account.IDTokenCredentials.from_service_account_file( |
| 505 | '/path/to/svc.json', target_audience=target_audience) |
| 506 | |
| 507 | authed_session = AuthorizedSession(creds) |
| 508 | |
| 509 | # make authenticated request and print the response, status_code |
| 510 | resp = authed_session.get(url) |
| 511 | print(resp.status_code) |
| 512 | print(resp.text) |
| 513 | |
| 514 | # to verify an ID Token |
| 515 | request = google.auth.transport.requests.Request() |
| 516 | token = creds.token |
| 517 | print(token) |
| 518 | print(id_token.verify_token(token,request)) |
| 519 | |
arithmetic1728 | 506c565 | 2020-04-01 10:34:37 -0700 | [diff] [blame] | 520 | .. _App Engine: https://cloud.google.com/appengine/ |
salrashid123 | 7a8641a | 2019-08-07 14:31:33 -0700 | [diff] [blame] | 521 | .. _Cloud Functions: https://cloud.google.com/functions/ |
| 522 | .. _Cloud Run: https://cloud.google.com/run/ |
| 523 | .. _Identity Aware Proxy: https://cloud.google.com/iap/ |
| 524 | .. _Google OpenID Connect: https://developers.google.com/identity/protocols/OpenIDConnect |
| 525 | .. _Google ID Token: https://developers.google.com/identity/protocols/OpenIDConnect#validatinganidtoken |
| 526 | |
Jon Wayne Parrott | 53c7b17 | 2016-11-10 10:44:30 -0800 | [diff] [blame] | 527 | Making authenticated requests |
| 528 | ----------------------------- |
| 529 | |
| 530 | Once you have credentials you can attach them to a *transport*. You can then |
| 531 | use this transport to make authenticated requests to APIs. google-auth supports |
| 532 | several different transports. Typically, it's up to your application or an |
| 533 | opinionated client library to decide which transport to use. |
| 534 | |
| 535 | Requests |
| 536 | ++++++++ |
| 537 | |
| 538 | The recommended HTTP transport is :mod:`google.auth.transport.requests` which |
| 539 | uses the `Requests`_ library. To make authenticated requests using Requests |
| 540 | you use a custom `Session`_ object:: |
| 541 | |
| 542 | from google.auth.transport.requests import AuthorizedSession |
| 543 | |
| 544 | authed_session = AuthorizedSession(credentials) |
| 545 | |
| 546 | response = authed_session.get( |
| 547 | 'https://www.googleapis.com/storage/v1/b') |
| 548 | |
| 549 | .. _Requests: http://docs.python-requests.org/en/master/ |
| 550 | .. _Session: http://docs.python-requests.org/en/master/user/advanced/#session-objects |
| 551 | |
| 552 | urllib3 |
| 553 | +++++++ |
| 554 | |
| 555 | :mod:`urllib3` is the underlying HTTP library used by Requests and can also be |
| 556 | used with google-auth. urllib3's interface isn't as high-level as Requests but |
| 557 | it can be useful in situations where you need more control over how HTTP |
| 558 | requests are made. To make authenticated requests using urllib3 create an |
| 559 | instance of :class:`google.auth.transport.urllib3.AuthorizedHttp`:: |
| 560 | |
| 561 | from google.auth.transport.urllib3 import AuthorizedHttp |
| 562 | |
| 563 | authed_http = AuthorizedHttp(credentials) |
| 564 | |
| 565 | response = authed_http.request( |
| 566 | 'GET', 'https://www.googleapis.com/storage/v1/b') |
| 567 | |
| 568 | You can also construct your own :class:`urllib3.PoolManager` instance and pass |
| 569 | it to :class:`~google.auth.transport.urllib3.AuthorizedHttp`:: |
| 570 | |
| 571 | import urllib3 |
| 572 | |
| 573 | http = urllib3.PoolManager() |
| 574 | authed_http = AuthorizedHttp(credentials, http) |
| 575 | |
| 576 | gRPC |
| 577 | ++++ |
| 578 | |
| 579 | `gRPC`_ is an RPC framework that uses `Protocol Buffers`_ over `HTTP 2.0`_. |
| 580 | google-auth can provide `Call Credentials`_ for gRPC. The easiest way to do |
| 581 | this is to use google-auth to create the gRPC channel:: |
| 582 | |
| 583 | import google.auth.transport.grpc |
| 584 | import google.auth.transport.requests |
| 585 | |
| 586 | http_request = google.auth.transport.requests.Request() |
| 587 | |
| 588 | channel = google.auth.transport.grpc.secure_authorized_channel( |
Jon Wayne Parrott | 840b3ac | 2016-11-10 12:07:51 -0800 | [diff] [blame] | 589 | credentials, http_request, 'pubsub.googleapis.com:443') |
Jon Wayne Parrott | 53c7b17 | 2016-11-10 10:44:30 -0800 | [diff] [blame] | 590 | |
| 591 | .. note:: Even though gRPC is its own transport, you still need to use one of |
| 592 | the other HTTP transports with gRPC. The reason is that most credential |
| 593 | types need to make HTTP requests in order to refresh their access token. |
| 594 | The sample above uses the Requests transport, but any HTTP transport can |
| 595 | be used. Additionally, if you know that your credentials do not need to |
| 596 | make HTTP requests in order to refresh (as is the case with |
| 597 | :class:`jwt.Credentials`) then you can specify ``None``. |
| 598 | |
| 599 | Alternatively, you can create the channel yourself and use |
| 600 | :class:`google.auth.transport.grpc.AuthMetadataPlugin`:: |
| 601 | |
| 602 | import grpc |
| 603 | |
| 604 | metadata_plugin = AuthMetadataPlugin(credentials, http_request) |
| 605 | |
| 606 | # Create a set of grpc.CallCredentials using the metadata plugin. |
| 607 | google_auth_credentials = grpc.metadata_call_credentials( |
| 608 | metadata_plugin) |
| 609 | |
| 610 | # Create SSL channel credentials. |
| 611 | ssl_credentials = grpc.ssl_channel_credentials() |
| 612 | |
| 613 | # Combine the ssl credentials and the authorization credentials. |
| 614 | composite_credentials = grpc.composite_channel_credentials( |
| 615 | ssl_credentials, google_auth_credentials) |
| 616 | |
| 617 | channel = grpc.secure_channel( |
| 618 | 'pubsub.googleapis.com:443', composite_credentials) |
| 619 | |
| 620 | You can use this channel to make a gRPC stub that makes authenticated requests |
| 621 | to a gRPC service:: |
| 622 | |
| 623 | from google.pubsub.v1 import pubsub_pb2 |
| 624 | |
| 625 | pubsub = pubsub_pb2.PublisherStub(channel) |
| 626 | |
| 627 | response = pubsub.ListTopics( |
| 628 | pubsub_pb2.ListTopicsRequest(project='your-project')) |
| 629 | |
| 630 | |
| 631 | .. _gRPC: http://www.grpc.io/ |
| 632 | .. _Protocol Buffers: |
| 633 | https://developers.google.com/protocol-buffers/docs/overview |
| 634 | .. _HTTP 2.0: |
| 635 | http://www.grpc.io/docs/guides/wire.html |
| 636 | .. _Call Credentials: |
| 637 | http://www.grpc.io/docs/guides/auth.html |