|
| 1 | +.. toctree:: |
| 2 | + :maxdepth: 1 |
| 3 | + :hidden: |
| 4 | + |
| 5 | +GCloud Auth |
| 6 | +----------- |
| 7 | + |
| 8 | +For the majority of cases, authentication with the ``gcloud`` library |
| 9 | +will **"just work"**. Credentials are loaded implicitly from the environment |
| 10 | +where the code is running and **no code** is required to enable authentication |
| 11 | +within your code. |
| 12 | + |
| 13 | +The core :mod:`gcloud.credentials` module provides helper methods |
| 14 | +for any account type needed. |
| 15 | + |
| 16 | +A production application should **use a service account**, but you may |
| 17 | +wish to use your own personal user account when first getting started with |
| 18 | +the ``gcloud`` library. |
| 19 | + |
| 20 | +============= |
| 21 | +Basic Example |
| 22 | +============= |
| 23 | + |
| 24 | +With an environment set up to use `Google Default Credentials`_, your |
| 25 | +API requests will be authenticated automatically: |
| 26 | + |
| 27 | +.. code-block:: python |
| 28 | +
|
| 29 | + from gcloud import datastore |
| 30 | + from gcloud import pubsub |
| 31 | + from gcloud import storage |
| 32 | +
|
| 33 | + entities = datastore.get([ |
| 34 | + datastore.Key('EntityKind', 1, dataset_id='foo')]) |
| 35 | +
|
| 36 | + bucket = storage.get_bucket('bucket-name') |
| 37 | +
|
| 38 | + pubsub.Topic('topic_name', project_id='my.project').create() |
| 39 | +
|
| 40 | +============= |
| 41 | +Advanced Uses |
| 42 | +============= |
| 43 | + |
| 44 | +A custom connection can be used as the default, but will need to be |
| 45 | +explicitly set. The |
| 46 | +:func:`set_default_connection() <gcloud.datastore.__init__.set_default_connection>` |
| 47 | +function is provided in all sub-packages to set a connection. For |
| 48 | +example, in the ``datastore`` sub-package: |
| 49 | + |
| 50 | +.. code-block:: python |
| 51 | +
|
| 52 | + credentials = get_custom_credentials() |
| 53 | + connection = datastore.Connection(credentials=credentials) |
| 54 | + datastore.set_default_connection(connection) |
| 55 | +
|
| 56 | + # ... Create keys. |
| 57 | + entities = datastore.get([key1, key2]) |
| 58 | +
|
| 59 | +If no default is set, all functions which make a connection to an API |
| 60 | +accept an optional ``connection`` argument. For example, with ``datastore``, |
| 61 | +the implicit behavior can be duplicated with: |
| 62 | + |
| 63 | +.. code-block:: python |
| 64 | +
|
| 65 | + from gcloud.credentials import get_credentials |
| 66 | +
|
| 67 | + credentials = get_credentials().create_scoped(datastore.SCOPE) |
| 68 | + connection = datastore.Connection(credentials=credentials) |
| 69 | +
|
| 70 | + # ... Create keys. |
| 71 | + entities = datastore.get([key1, key2], connection=connection) |
| 72 | +
|
| 73 | +If no connection is passed explicity and |
| 74 | +:func:`set_default_connection() <gcloud.datastore.__init__.set_default_connection>` |
| 75 | +is never called, the request will fail: |
| 76 | + |
| 77 | +.. code-block:: python |
| 78 | +
|
| 79 | + Traceback (most recent call last): |
| 80 | + File "<stdin>", line 1, in <module> |
| 81 | + File "gcloud/datastore/api.py", line 200, in get |
| 82 | + connection = _require_connection(connection) |
| 83 | + File "gcloud/datastore/api.py", line 82, in _require_connection |
| 84 | + raise EnvironmentError('Connection could not be inferred.') |
| 85 | + EnvironmentError: Connection could not be inferred. |
| 86 | +
|
| 87 | +--------------------------------- |
| 88 | +Multiple Simultaneous Connections |
| 89 | +--------------------------------- |
| 90 | + |
| 91 | +Some applications will need to read and write data into multiple projects. |
| 92 | +This may require using more than one set of credentials (either via JSON key |
| 93 | +files or other means). |
| 94 | + |
| 95 | +As a result, a single connection will be insufficient to make all API requests. |
| 96 | +To use two separate connections, proceed as above by using explicit connections |
| 97 | +in each function that makes an API request: |
| 98 | + |
| 99 | +.. code-block:: python |
| 100 | +
|
| 101 | + credentials1 = my_custom_credentials_function('foo') |
| 102 | + credentials2 = my_custom_credentials_function('bar') |
| 103 | +
|
| 104 | + connection1 = datastore.Connection(credentials=credentials1) |
| 105 | + connection2 = datastore.Connection(credentials=credentials2) |
| 106 | +
|
| 107 | + key1 = datastore.Key('CompanyA', 1337, dataset_id='foo') |
| 108 | + entities1 = datastore.get([key1], connection=connection1) |
| 109 | +
|
| 110 | + key2 = datastore.Key('CompanyB', 42, dataset_id='bar') |
| 111 | + datastore.delete([key2], connection=connection2) |
| 112 | +
|
| 113 | +If one is connection used more often than another, it can still be used as the |
| 114 | +default: |
| 115 | + |
| 116 | +.. code-block:: python |
| 117 | +
|
| 118 | + datastore.set_default_connection(connection=connection1) |
| 119 | +
|
| 120 | + entities1 = datastore.get([key1]) |
| 121 | +
|
| 122 | + datastore.delete([key2], connection=connection2) |
| 123 | +
|
| 124 | +======================= |
| 125 | +Supported Account Types |
| 126 | +======================= |
| 127 | + |
| 128 | +With the helper functions provided, we support the following |
| 129 | +OAuth 2.0 account types: |
| 130 | + |
| 131 | +- Google `App Engine Service Accounts`_ |
| 132 | +- Google `Compute Engine Service Accounts`_ |
| 133 | +- `Service Accounts`_ with JSON `Service Account Key`_ |
| 134 | +- User Accounts (3-legged `OAuth`_ 2.0) with refresh token |
| 135 | +- Service Accounts with PKCS12 / P12 `Service Account Key`_ |
| 136 | + |
| 137 | +========================== |
| 138 | +Google Default Credentials |
| 139 | +========================== |
| 140 | + |
| 141 | +All but one `supported account type`_ listed above can be handled by using |
| 142 | +Google `Application Default`_ credentials via |
| 143 | +:func:`get_credentials() <gcloud.credentials.get_credentials>`. This function |
| 144 | +can be used directly to obtain ``credentials`` to be passed |
| 145 | +to a ``Connection`` or can be used implictly by calling |
| 146 | +:func:`get_connection (datastore) <gcloud.datastore.__init__.get_connection>` |
| 147 | +and :func:`get_connection (storage) <gcloud.storage.__init__.get_connection>`. |
| 148 | + |
| 149 | +---------------------------------- |
| 150 | +Google App Engine Service Accounts |
| 151 | +---------------------------------- |
| 152 | + |
| 153 | +:func:`get_credentials() <gcloud.credentials.get_credentials>` |
| 154 | +implicitly handles **Google App Engine Service Accounts** with no user |
| 155 | +intervention required. |
| 156 | + |
| 157 | +To explicitly load these credentials: |
| 158 | + |
| 159 | +.. code-block:: python |
| 160 | +
|
| 161 | + from oauth2client.appengine import AppAssertionCredentials |
| 162 | + credentials = AppAssertionCredentials([]) |
| 163 | +
|
| 164 | +-------------------------------------- |
| 165 | +Google Compute Engine Service Accounts |
| 166 | +-------------------------------------- |
| 167 | + |
| 168 | +:func:`get_credentials() <gcloud.credentials.get_credentials>` implicitly |
| 169 | +handles **Google Compute Engine Service Accounts** with no user intervention |
| 170 | +required. However, when creating the `instance`_, the service account |
| 171 | +must be enabled and the correct set of scopes must be selected for |
| 172 | +the services you intend to use. |
| 173 | + |
| 174 | +To explicitly load these credentials: |
| 175 | + |
| 176 | +.. code-block:: python |
| 177 | +
|
| 178 | + from oauth2client.gce import AppAssertionCredentials |
| 179 | + credentials = AppAssertionCredentials([]) |
| 180 | +
|
| 181 | +.. _instance: https://cloud.google.com/compute/docs/instances |
| 182 | + |
| 183 | +------------------------------- |
| 184 | +Service Accounts with JSON keys |
| 185 | +------------------------------- |
| 186 | + |
| 187 | +As mentioned above, support for **Service Accounts with JSON keys** can be done |
| 188 | +by setting the ``GOOGLE_APPLICATION_CREDENTIALS`` environment variable: |
| 189 | + |
| 190 | +.. code-block:: bash |
| 191 | +
|
| 192 | + $ export GOOGLE_APPLICATION_CREDENTIALS="/path/to/key_file.json" |
| 193 | +
|
| 194 | +If you'd like to load these credentials explicitly rather than via the |
| 195 | +environment, you can use |
| 196 | +:func:`get_for_service_account_json() <gcloud.credentials.get_for_service_account_json>`: |
| 197 | + |
| 198 | +.. code-block:: python |
| 199 | +
|
| 200 | + from gcloud.credentials import get_for_service_account_json |
| 201 | +
|
| 202 | + private_key_path = '/path/to/key_file.p12' |
| 203 | +
|
| 204 | + credentials = get_for_service_account_json(private_key_path) |
| 205 | +
|
| 206 | +------------------------------------------------- |
| 207 | +User Accounts (3-legged OAuth) with refresh token |
| 208 | +------------------------------------------------- |
| 209 | + |
| 210 | +As mentioned in the introduction, a production application should |
| 211 | +**use a service account**. However, when just getting started with the library, |
| 212 | +it can be useful to just use an authorized user account. |
| 213 | + |
| 214 | +If you've installed the ``gcloud`` command line `tool`_, you can authorize |
| 215 | +a user account by running |
| 216 | + |
| 217 | +.. code-block:: bash |
| 218 | +
|
| 219 | + $ gcloud auth login |
| 220 | +
|
| 221 | +(it's very likely you've already done so). |
| 222 | + |
| 223 | +.. _tool: https://cloud.google.com/sdk/gcloud/ |
| 224 | + |
| 225 | +After doing so, you can re-use these credentials within ``gcloud`` |
| 226 | +just by using :func:`get_credentials() <gcloud.credentials.get_credentials>`: |
| 227 | + |
| 228 | +.. code-block:: python |
| 229 | +
|
| 230 | + from gcloud.credentials import get_credentials |
| 231 | + credentials = get_credentials() |
| 232 | +
|
| 233 | +.. note:: |
| 234 | + |
| 235 | + The ``gcloud`` CLI tool will create an authorized user JSON credentials |
| 236 | + file on your system. On \*nix systems, this will typically reside in |
| 237 | + ``${HOME}/.config/gcloud/application_default_credentials.json``. |
| 238 | + |
| 239 | +In addition to using the credentials from the ``gcloud`` CLI, you can use your |
| 240 | +own credentials file. This file will contain a JSON object with four keys: |
| 241 | + |
| 242 | +.. code-block:: json |
| 243 | +
|
| 244 | + { |
| 245 | + "client_id": "123", |
| 246 | + "client_secret": "secret", |
| 247 | + "refresh_token": "FOO", |
| 248 | + "type": "authorized_user" |
| 249 | + } |
| 250 | +
|
| 251 | +This can be used just as a JSON key file can be used for a service account |
| 252 | + |
| 253 | +.. code-block:: bash |
| 254 | +
|
| 255 | + $ export GOOGLE_APPLICATION_CREDENTIALS="/path/to/authorized_user_credentials.json" |
| 256 | +
|
| 257 | +As with Service Accounts with JSON keys, you can explicitly load an authorized |
| 258 | +user account key with |
| 259 | +:func:`get_for_service_account_json() <gcloud.credentials.get_for_service_account_json>`. |
| 260 | + |
| 261 | +================================= |
| 262 | +PKCS12 / P12 Service Account Keys |
| 263 | +================================= |
| 264 | + |
| 265 | +PKCS12 / P12 Service Account keys are the only `supported account type`_ above |
| 266 | +that is not covered by Google Default Credentials. |
| 267 | + |
| 268 | +.. _supported account type: #supported-account-types |
| 269 | + |
| 270 | +This is because **JSON Service Account Credentials** are the preferred format. |
| 271 | + |
| 272 | +If for some reason you need (or want) to use a P12 key, |
| 273 | +:func:`get_for_service_account_p12() <gcloud.credentials.get_for_service_account_p12>` |
| 274 | +allows you to load service account credentials for such a key: |
| 275 | + |
| 276 | +.. code-block:: python |
| 277 | +
|
| 278 | + from gcloud.credentials import get_for_service_account_p12 |
| 279 | +
|
| 280 | + client_email = '[email protected]' |
| 281 | + private_key_path = '/path/to/key_file.p12' |
| 282 | +
|
| 283 | + credentials = get_for_service_account_p12(client_email, private_key_path) |
| 284 | +
|
| 285 | +Notice that unlike the JSON Service Account Key, the P12 key also |
| 286 | +**requires the email address** for the service account. (This is because the |
| 287 | +JSON key file contains the email address, while the P12 key file only contains |
| 288 | +the private key bytes.) |
| 289 | + |
| 290 | +========================== |
| 291 | +Enabling a service account |
| 292 | +========================== |
| 293 | + |
| 294 | +.. include:: _components/enabling-a-service-account.rst |
| 295 | + |
| 296 | +.. _Service Account Key: https://cloud.google.com/storage/docs/authentication#generating-a-private-key |
| 297 | +.. _Application Default: https://developers.google.com/accounts/docs/application-default-credentials |
| 298 | +.. _App Engine Service Accounts: https://cloud.google.com/appengine/docs/python/appidentity/ |
| 299 | +.. _Compute Engine Service Accounts: https://cloud.google.com/compute/docs/authentication#metadata |
| 300 | +.. _OAuth: https://developers.google.com/accounts/docs/OAuth2WebServer |
| 301 | +.. _Service Accounts: #enabling-a-service-account |
0 commit comments