-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding auth doc explaining all the ways to mint credentials.
Fixes #633.
- Loading branch information
Showing
3 changed files
with
330 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,28 @@ | ||
Now that you have a project, | ||
we need to make sure we are able to access our data. | ||
There are many ways to authenticate, | ||
but we're going to use a Service Account for today. | ||
|
||
A *Service Account* is sort of like a username and password | ||
(like when you're connecting to your MySQL database), | ||
except the username is automatically generated | ||
(and is an e-mail address) | ||
and the password is actually a private key file. | ||
A `Service Account`_ handles authentication for a backend service that | ||
needs to talk to other services (e.g. Google APIs). | ||
|
||
To create a Service Account: | ||
|
||
* **Click on Credentials** | ||
under the "APIs & Auth" section. | ||
|
||
* **Click the big red button** | ||
that says "Create New Client ID" | ||
under the OAuth section | ||
(the first one). | ||
#. Visit the `Google Developers Console`_. | ||
|
||
* **Choose "Service Account"** | ||
and click the blue button | ||
that says "Create Client ID". | ||
#. Create a new project or click on an existing project. | ||
|
||
* **This will automatically** | ||
download a private key file. | ||
**Do not lose this.** | ||
#. Navigate to **APIs & auth** > **APIs section** and turn on the following | ||
APIs (you may need to enable billing in order to use these services): | ||
|
||
* **Rename your key** something shorter. | ||
I like to name the key ``<project name>.p12``. | ||
* Google Cloud Datastore API | ||
* Google Cloud Storage | ||
* Google Cloud Storage JSON API | ||
* Google Pub/Sub API | ||
|
||
This is like your password for the account. | ||
#. Navigate to **APIs & auth** > **Credentials** and then: | ||
|
||
* **Copy the long weird e-mail address** | ||
labeled "E-mail address" | ||
in the information section | ||
for the Service Account | ||
you just created. | ||
* If you want to use a new service account, click on **Create new Client ID** | ||
and select **Service account**. After the account is created, you will be | ||
prompted to download the JSON key file that the library uses to authorize | ||
your requests. | ||
* If you want to generate a new key for an existing service account, click | ||
on **Generate new JSON key** and download the JSON key file. | ||
|
||
This is like your username for the account. | ||
.. _Google Developers Console: https://console.developers.google.com/project | ||
.. _Service Account: https://developers.google.com/accounts/docs/OAuth2ServiceAccount |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,310 @@ | ||
.. toctree:: | ||
:maxdepth: 1 | ||
:hidden: | ||
|
||
GCloud Auth | ||
----------- | ||
|
||
For the majority of cases, authentication with the ``gcloud`` library | ||
will **"just work"**. Credentials are loaded implicitly from the environment | ||
where the code is running and **no code** is required to enable authentication | ||
within your code. | ||
|
||
The core :mod:`gcloud.credentials` module provides helper methods | ||
for any account type needed. | ||
|
||
A production application should **use a service account**, but you may | ||
wish to use other methods when first getting started with the ``gcloud`` | ||
library. | ||
|
||
============= | ||
Basic Example | ||
============= | ||
|
||
After downloading a JSON key for a service account (see `Service Accounts`_), | ||
set the ``GOOGLE_APPLICATION_CREDENTIALS`` environment variable: | ||
|
||
.. code-block:: bash | ||
$ export GOOGLE_APPLICATION_CREDENTIALS="/path/to/key_file.json" | ||
After doing this, your API requests will be authenticated automatically | ||
using the JSON key: | ||
|
||
.. code-block:: python | ||
from gcloud import datastore | ||
from gcloud import pubsub | ||
from gcloud import storage | ||
key1 = datastore.Key('EntityKind', 1, dataset_id='foo') | ||
key2 = datastore.Key('EntityKind', 2, dataset_id='foo') | ||
entities = datastore.get([key1, key2]) | ||
bucket = storage.get_bucket('bucket-name') | ||
topic = pubsub.Topic('topic_name', project_id='my.project') | ||
topic.create() | ||
============= | ||
Advanced Uses | ||
============= | ||
|
||
A custom connection can be used as the default, but will need to be | ||
explicitly set. The | ||
:func:`set_default_connection() <gcloud.datastore.__init__.set_default_connection>` | ||
function is provided in all sub-packages to set a connection. For | ||
example, in the ``datastore`` sub-package: | ||
|
||
.. code-block:: python | ||
credentials = get_custom_credentials() | ||
connection = datastore.Connection(credentials=credentials) | ||
datastore.set_default_connection(connection) | ||
# ... Create keys. | ||
entities = datastore.get([key1, key2]) | ||
If no default is set, all functions which make a connection to an API | ||
accept an optional ``connection`` argument. For example, with ``datastore``, | ||
the implicit behavior can be duplicated with: | ||
|
||
.. code-block:: python | ||
from gcloud.credentials import get_credentials | ||
credentials = get_credentials().create_scoped(datastore.SCOPE) | ||
connection = datastore.Connection(credentials=credentials) | ||
# ... Create keys. | ||
entities = datastore.get([key1, key2], connection=connection) | ||
If no connection is passed explicity and | ||
:func:`set_default_connection() <gcloud.datastore.__init__.set_default_connection>` | ||
is never called, the request will fail: | ||
|
||
.. code-block:: python | ||
Traceback (most recent call last): | ||
File "<stdin>", line 1, in <module> | ||
File "gcloud/datastore/api.py", line 200, in get | ||
connection = _require_connection(connection) | ||
File "gcloud/datastore/api.py", line 82, in _require_connection | ||
raise EnvironmentError('Connection could not be inferred.') | ||
EnvironmentError: Connection could not be inferred. | ||
--------------------------------- | ||
Multiple Simultaneous Connections | ||
--------------------------------- | ||
|
||
Some applications will need to read and write data into multiple projects. | ||
This may require using more than one set of credentials (either via JSON key | ||
files or other means). | ||
|
||
As a result, a single connection will be insufficient to make all API requests. | ||
To use two separate connections, proceed as above by using explicit connections | ||
in each function that makes an API request: | ||
|
||
.. code-block:: python | ||
credentials1 = my_custom_credentials_function('foo') | ||
credentials2 = my_custom_credentials_function('bar') | ||
connection1 = datastore.Connection(credentials=credentials1) | ||
connection2 = datastore.Connection(credentials=credentials2) | ||
key1 = datastore.Key('CompanyA', 1337, dataset_id='foo') | ||
entities1 = datastore.get([key1], connection=connection1) | ||
key2 = datastore.Key('CompanyB', 42, dataset_id='bar') | ||
datastore.delete([key2], connection=connection2) | ||
If one is connection used more often than another, it can still be used as the | ||
default: | ||
|
||
.. code-block:: python | ||
datastore.set_default_connection(connection=connection1) | ||
entities1 = datastore.get([key1]) | ||
datastore.delete([key2], connection=connection2) | ||
======================= | ||
Supported Account Types | ||
======================= | ||
|
||
With the helper functions provided, we support the following | ||
OAuth 2.0 account types: | ||
|
||
- Google `App Engine Service Accounts`_ | ||
- Google `Compute Engine Service Accounts`_ | ||
- `Service Accounts`_ with JSON `Service Account Key`_ | ||
- User Accounts (3-legged `OAuth`_ 2.0) with refresh token | ||
- Service Accounts with PKCS12 / P12 `Service Account Key`_ | ||
|
||
========================== | ||
Google Default Credentials | ||
========================== | ||
|
||
The majority of cases can be handled by using Google | ||
`Application Default`_ credentials via | ||
:func:`get_credentials() <gcloud.credentials.get_credentials>`. This function | ||
can be used directly to obtain ``credentials`` to be passed | ||
to a ``Connection`` or can be used implictly by calling | ||
:func:`get_connection (datastore) <gcloud.datastore.__init__.get_connection>` | ||
and :func:`get_connection (storage) <gcloud.storage.__init__.get_connection>`. | ||
|
||
---------------------------------- | ||
Google App Engine Service Accounts | ||
---------------------------------- | ||
|
||
:func:`get_credentials() <gcloud.credentials.get_credentials>` | ||
implicitly handles **Google App Engine Service Accounts** with no user | ||
intervention required. | ||
|
||
To explicitly load these credentials: | ||
|
||
.. code-block:: python | ||
from oauth2client.appengine import AppAssertionCredentials | ||
credentials = AppAssertionCredentials([]) | ||
-------------------------------------- | ||
Google Compute Engine Service Accounts | ||
-------------------------------------- | ||
|
||
:func:`get_credentials() <gcloud.credentials.get_credentials>` implicitly | ||
handles **Google Compute Engine Service Accounts** with no user intervention | ||
required. However, when creating the `instance`_, the service account | ||
must be enabled and the correct set of scopes must be selected for | ||
the services you intend to use. | ||
|
||
To explicitly load these credentials: | ||
|
||
.. code-block:: python | ||
from oauth2client.gce import AppAssertionCredentials | ||
credentials = AppAssertionCredentials([]) | ||
.. _instance: https://cloud.google.com/compute/docs/instances | ||
|
||
------------------------------- | ||
Service Accounts with JSON keys | ||
------------------------------- | ||
|
||
As mentioned above, support for **Service Accounts with JSON keys** can be done | ||
by setting the ``GOOGLE_APPLICATION_CREDENTIALS`` environment variable: | ||
|
||
.. code-block:: bash | ||
$ export GOOGLE_APPLICATION_CREDENTIALS="/path/to/key_file.json" | ||
If you'd like to load these credentials explicitly rather than via the | ||
environment, you can use | ||
:func:`get_for_service_account_json() <gcloud.credentials.get_for_service_account_json>`: | ||
|
||
.. code-block:: python | ||
from gcloud.credentials import get_for_service_account_json | ||
private_key_path = '/path/to/key_file.p12' | ||
credentials = get_for_service_account_json(private_key_path) | ||
------------------------------------------------- | ||
User Accounts (3-legged OAuth) with refresh token | ||
------------------------------------------------- | ||
|
||
As mentioned in the introduction, a production application should | ||
**use a service account**. However, when just getting started with the library, | ||
it can be useful to just use an authorized user account. | ||
|
||
If you've installed the ``gcloud`` command line `tool`_, you can authorize | ||
a user account by running | ||
|
||
.. code-block:: bash | ||
$ gcloud auth login | ||
(it's very likely you've already done so). | ||
|
||
.. _tool: https://cloud.google.com/sdk/gcloud/ | ||
|
||
After doing so, you can re-use these credentials within ``gcloud`` | ||
just by using :func:`get_credentials() <gcloud.credentials.get_credentials>`: | ||
|
||
.. code-block:: python | ||
from gcloud.credentials import get_credentials | ||
credentials = get_credentials() | ||
.. note:: | ||
|
||
The ``gcloud`` CLI tool will create an authorized user JSON credentials | ||
file on your system. On \*nix systems, this will typically reside in | ||
``${HOME}/.config/gcloud/application_default_credentials.json``. | ||
|
||
In addition to using the credentials from the ``gcloud`` CLI, you can use your | ||
own credentials file. This file will contain a JSON object with four keys: | ||
|
||
.. code-block:: json | ||
{ | ||
"client_id": "123", | ||
"client_secret": "secret", | ||
"refresh_token": "FOO", | ||
"type": "authorized_user" | ||
} | ||
This can be used just as a JSON key file can be used for a service account | ||
|
||
.. code-block:: bash | ||
$ export GOOGLE_APPLICATION_CREDENTIALS="/path/to/authorized_user_credentials.json" | ||
As with Service Accounts with JSON keys, you can explicitly load an authorized | ||
user account key with | ||
:func:`get_for_service_account_json() <gcloud.credentials.get_for_service_account_json>`. | ||
|
||
================================= | ||
PKCS12 / P12 Service Account Keys | ||
================================= | ||
|
||
PKCS12 / P12 Service Account keys are the only `supported account type`_ above | ||
that is not covered by Google Default Credentials. | ||
|
||
.. _supported account type: #supported-account-types | ||
|
||
This is because **JSON Service Account Credentials** are the preferred format. | ||
|
||
If for some reason you need (or want) to use a P12 key, | ||
:func:`get_for_service_account_p12() <gcloud.credentials.get_for_service_account_p12>` | ||
allows you to load service account credentials for such a key: | ||
|
||
.. code-block:: python | ||
from gcloud.credentials import get_for_service_account_p12 | ||
client_email = '[email protected]' | ||
private_key_path = '/path/to/key_file.p12' | ||
credentials = get_for_service_account_p12(client_email, private_key_path) | ||
Notice that unlike the JSON Service Account Key, the P12 key also | ||
**requires the email address** for the service account. (This is because the | ||
JSON key file contains the email address, while the P12 key file only contains | ||
the private key bytes.) | ||
|
||
========================== | ||
Enabling a service account | ||
========================== | ||
|
||
.. include:: _components/enabling-a-service-account.rst | ||
|
||
.. _Service Account Key: https://cloud.google.com/storage/docs/authentication#generating-a-private-key | ||
.. _Application Default: https://developers.google.com/accounts/docs/application-default-credentials | ||
.. _App Engine Service Accounts: https://cloud.google.com/appengine/docs/python/appidentity/ | ||
.. _Compute Engine Service Accounts: https://cloud.google.com/compute/docs/authentication#metadata | ||
.. _OAuth: https://developers.google.com/accounts/docs/OAuth2WebServer | ||
.. _Service Accounts: #enabling-a-service-account |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
:hidden: | ||
|
||
gcloud-api | ||
gcloud-auth | ||
datastore-api | ||
datastore-entities | ||
datastore-keys | ||
|