Google Cloud Platform Auth ガイド

Google Cloud Platform では、Cloud StorageBigQuery など、さまざまなサービスを提供しています。通常、これらのサービスには API(もしくはウェブ インターフェース、コマンドライン ツール)でアクセスします。セキュリティとプライバシーを保護するため、すべての Google Cloud Platform API には認証と承認が必要です。このガイドは、さまざまな環境において認証と承認を簡単に行うことができるように、Cloud Platform API の一般的な使用手順、およびアプリケーションのデフォルト承認情報について説明します。

主なコンセプト

ユーザー アカウントとサービス アカウント

Google は、さまざまな種類のアカウントに対応しています。Google Cloud Platform にとって最も重要なアカウントは、ユーザー アカウントとサービス アカウントです。ユーザー アカウントは、データへのアクセスを承認するユーザーを表すものです。また、サービス アカウントは、Google API にアクセスするサービス側のアプリケーションを承認するためのものです。両アカウントともに、メールアドレスで識別されます。たとえば、Gmail と Google Cloud Platform Console ではユーザー アカウントを使用する必要がありますが、サービスを実行するにはサービス アカウントを使用しなくてはなりません。そのため、パスワードを変更しても機能が停止することはありません。

プロジェクトとリソース

Google Cloud Platform では、プロジェクトをリソース所有権の単位としています。すべての Cloud Platform リソース(App Engine アプリケーション、Compute Engine インスタンス、Cloud Storage バケット、API キーなど)は、プロジェクトごとに所有することができます。複数のユーザーで作業を行うために、プロジェクトをシェアすることもできます。

認証と承認

認証は、クライアントを識別するための確認プロセスです。通常、ユーザー アカウント、もしくはサービス アカウントで識別します。承認は、認証された ID のリソースでの権限を確認するためのプロセスです。

Google API では、認証なしに承認を行うことはできません。そのため、認証(auth)は認証と承認の両方のプロセスを意味する場合があります。

OAuth

OAuth 2.0 は、ネットワーク サービスの認証および承認を行うための業界標準です。Google Cloud Platform では、API 認証および承認に OAuth 2.0 を使用しています。通常使用されているシナリオは、ユーザー中心のフローとサーバー中心のフローです。

ユーザー中心のフローでは、アプリケーションは認証プロバイダへの認証情報をエンドユーザーから取得することができます。3 つのエンティティ(アプリケーション、認証プロバイダ、エンドユーザー)が関わっているため、このプロセスは 3-legged OAuth(3LO)とも呼ばれています。

The user-centric flow allows an application to obtain credentials to
    an authentication provider from an end user.
アプリ
ユーザーの同意
ユーザーデータ
図 1: ユーザー中心の認証

サーバー中心のフローでは、認証プロバイダへのサービスアカウントの認証情報をアプリケーションが直接所有することができます。これには、2 つのエンティティ(アプリケーション、認証プロバイダ)が関わっているため、2-legged OAuth(2LO)としても知られています。

The server-centric flow allows your
    application to directly hold credentials of a service account to an
    authentication provider.
サービス
承認
Google サービス
図 2: サーバー中心の認証

アプリケーションが認証情報を取得したら、認証プロバイダに連絡して特定のサービス用の OAuth アクセス トークンを取得し、API コールなどのサービスへのアクセスにトークンを使用します。

OAuth スコープ

OAuth 機能のスコープは、OAuth 認証情報の権限だけに制限されています。ユーザー アカウントもしくはサービス アカウントは、Cloud Storage バケットの Storage Read(読み取り)および Storage Write(書込み)など、リソースに関する幅広い権限があります。セキュリティとプライバシーを保護するため、アプリケーションではこれらの権限をすべて取得する必要はありません。OAuth スコープ機能により、認証情報を Storage Read などの権限やスコープのサブセットに制限することができます。Google API メソッドが必要とするスコープは、リファレンス ドキュメントのリストで確認してください。例については、Google Cloud Pub/Sub の projects.topics.list メソッドを参照してください。

アプリケーションのデフォルト認証情報

アプリケーションのデフォルト認証情報(ADC)は、Google Cloud Platform API の認証を簡単にする Google API クライアント ライブラリの一部です。さまざまな環境における認証を要約したもので、1 行のコードで認証が可能になります。単一の認証 ID と OAuth スコープの規定のセットで、アプリケーションが作動している場合などを想定して設計されたものです。

デベロッパー ワークフロー

すべてのシナリオを同じワークフローで行います。アプリケーションは、OAuth 認証情報を取得すると、認証情報から派生したアクセス トークンを使って、Google Cloud Platform API にリクエストを申請します。API はリクエストを許可するかどうか判断するためにアクセス トークンを使用します。

準備

Google API の使用を開始するには、Google Cloud Platform Console の次の要件を満たす必要があります。

  1. プロジェクトがない場合は、プロジェクトを作成します。

  2. API Manager にて、プロジェクトで使用する API を有効にします。これらの API を有効化すると、利用規約、プライバシー ポリシー、割り当て制限、支払い請求に同意したことになります。

サーバー中心のフローのための認証情報取得

ここで紹介するのは、さまざまなシナリオにおける認証情報取得のための推奨例です。 アプリケーションのデフォルト認証情報は、使用が簡単でさまざまな環境に対応する汎用性があるため、おすすめの認証情報取得方法です。

アプリケーションのデフォルト認証情報を使用する利点は、コードを本番環境にデプロイする際、コードをほとんど、あるいはまったく改変せずに実行できることです。

ローカルでの開発

開発およびテスト中に、ローカルでコードを実行するには、Google Cloud SDK(gcloud)とアプリケーションのデフォルト認証情報を使用します。gcloud beta auth application-default login コマンドを使って SDK を認証した後、アプリケーションのデフォルト認証情報を使用する API クライアント ライブラリが、作成された認証情報を自動的に反映させます。1 つのローカル ユーザー環境ごとに、コマンドを実行する必要があるのは一度だけです。

Compute Engine で実行されるサービス

Compute Engine でコードを実行するには、アプリケーションのデフォルト認証情報を使用する必要があります。アプリケーションのデフォルト認証情報を自動的に使用する API クライアント ライブラリが、Compute Engine メタデータのランタイムから、組み込みサービス アカウントの認証情報を取得します。

App Engine で実行されるサービス

App Engine でコードを実行するには、アプリケーションのデフォルト認証情報を使用する必要があります。アプリケーションのデフォルト認証情報を自動的に使用する API クライアント ライブラリが、App Engine ホストのランタイムから、組み込みのサービス アカウント認証情報を取得します。

オンプレミスで実行されるサービス

プライベート データセンターや他のパブリック クラウドなど、Google Cloud Platform 外でコードを実行する場合、明示的に作成したアカウントでアプリケーションのデフォルト認証情報を使用する必要があります。

  1. サービス アカウントを作成するため Google Cloud Platform Console を使用し、認証情報 JSON ファイルをサーバーにダウンロードします。ファイルを安全な場所に保存してください。

  2. 認証情報 JSON ファイルのパスへの環境変数 GOOGLE_APPLICATION_CREDENTIALS を設定します。

ユーザー中心のアプリケーション

ユーザーデータへのアクセスをリクエストするアプリケーションを構築するには、ユーザー中心の OAuth フローを使用する必要があります。詳しくは、Using OAuth 2.0 を使用して Access Google API にアクセスするをご覧ください。

トークンのライフサイクル管理

OAuth トークン、API キー、その他の認証情報は、重要なデータへのアクセス権を提供します。次に記載されている事項は、これらのリソースへのアクセスを保護するためのものです。

  • API キー、OAuth トークン、サービス アカウント認証情報など、認証に関する情報をソースコードに組み込まないでください。認証情報に関する環境変数は、安全なキー マネージャーなど、アプリケーションのソースコード外で使用してください。
  • テスト環境と本番環境のように、異なるコンテキストには異なる認証情報を使用してください。
  • 認証情報が第三者に盗まれないように、認証情報の転送は必ず HTTPS 上で行ってください。テキストや URL の一部として転送しないようご注意ください。
  • 長期間有効になっている認証情報をクライアント側アプリケーションに組み込まないでください。たとえば、モバイルアプリに、サービス アカウント認証情報を組み込まないでください。クライアント側アプリケーションは簡単に調べることが可能であるため、認証情報が第三者により簡単に見つけられてしまう可能性があります。
  • トークンが必要なくなった場合は取り消してください。

OAuth 2.0 の詳細

コードサンプル

アプリケーションのデフォルト認証情報には、Google Cloud Platform API のクライアント ライブラリが配布されており、現在、Java、Python、Node、Ruby、Go & .Net で利用することができます。これらのコードサンプルは、上記すべての環境で機能します。

Java

アプリケーションのデフォルト認証情報は、Java 用の Google API クライアント ライブラリのバージョン 1.19 より利用することができます。Cloud Storage API など、Google Cloud Platform API へアクセスするために、次のような形で使用することができます。

public class StorageFactory {
  private static Storage instance = null;

  public static synchronized Storage getService() throws IOException, GeneralSecurityException {
    if (instance == null) {
      instance = buildService();
    }
    return instance;
  }

  private static Storage buildService() throws IOException, GeneralSecurityException {
    HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
    JsonFactory jsonFactory = new JacksonFactory();
    GoogleCredential credential = GoogleCredential.getApplicationDefault(transport, jsonFactory);

    // Depending on the environment that provides the default credentials (for
    // example: Compute Engine, App Engine), the credentials may require us to
    // specify the scopes we need explicitly.  Check for this case, and inject
    // the Cloud Storage scope if required.
    if (credential.createScopedRequired()) {
      Collection<String> scopes = StorageScopes.all();
      credential = credential.createScoped(scopes);
    }

    return new Storage.Builder(transport, jsonFactory, credential)
        .setApplicationName("GCS Samples")
        .build();
  }
}
/**
 * Fetch a list of the objects within the given bucket.
 *
 * @param bucketName the name of the bucket to list.
 * @return a list of the contents of the specified bucket.
 */
public static List<StorageObject> listBucket(String bucketName)
    throws IOException, GeneralSecurityException {
  Storage client = StorageFactory.getService();
  Storage.Objects.List listRequest = client.objects().list(bucketName);

  List<StorageObject> results = new ArrayList<StorageObject>();
  Objects objects;

  // Iterate through each page of results, and add them to our results list.
  do {
    objects = listRequest.execute();
    // Add the items in this page of results to the list we'll return.
    results.addAll(objects.getItems());

    // Get the next page, in the next iteration of this loop.
    listRequest.setPageToken(objects.getNextPageToken());
  } while (null != objects.getNextPageToken());

  return results;
}

Python

アプリケーションのデフォルト認証情報は、Python用の Google API クライアント ライブラリ バージョン 1.3 より利用することができます。Cloud Storage API など、Google Cloud Platform API へアクセスするために、次のような形で使用することができます。

def create_service():
    """Creates the service object for calling the Cloud Storage API."""
    # Get the application default credentials. When running locally, these are
    # available after running `gcloud init`. When running on compute
    # engine, these are available from the environment.
    credentials = GoogleCredentials.get_application_default()

    # Construct the service object for interacting with the Cloud Storage API -
    # the 'storage' service, at version 'v1'.
    # You can browse other available api services and versions here:
    #     https://developers.google.com/api-client-library/python/apis/
    return discovery.build('storage', 'v1', credentials=credentials)
...
def list_bucket(bucket):
    """Returns a list of metadata of the objects within the given bucket."""
    service = create_service()

    # Create a request to objects.list to retrieve a list of objects.
    fields_to_return = \
        'nextPageToken,items(name,size,contentType,metadata(my-key))'
    req = service.objects().list(bucket=bucket, fields=fields_to_return)

    all_objects = []
    # If you have too many items to list in one request, list_next() will
    # automatically handle paging with the pageToken.
    while req:
        resp = req.execute()
        all_objects.extend(resp.get('items', []))
        req = service.objects().list_next(req, resp)
    return all_objects

Node.js

アプリケーションのデフォルト認証情報は、Node.js 用の Google Cloud クライアント ライブラリで利用することができます。Cloud Storage API など、Google Cloud Platform API へアクセスするために、次のような形で使用することができます。

// By default, the client will authenticate using the service account file
// specified by the GOOGLE_APPLICATION_CREDENTIALS environment variable and use
// the project specified by the GCLOUD_PROJECT environment variable. See
// https://googlecloudplatform.github.io/google-cloud-node/#/docs/google-cloud/latest/guides/authentication
var Storage = require('@google-cloud/storage');

// Instantiate a storage client
var storage = Storage();
/**
 * List all of the authenticated project's buckets.
 *
 * @param {function} cb The callback function.
 */
function listBuckets (callback) {
  // See https://googlecloudplatform.github.io/google-cloud-node/#/docs/storage/latest/storage
  storage.getBuckets(function (err, buckets) {
    if (err) {
      return callback(err);
    }

    console.log('Found %d bucket(s)!', buckets.length);
    return callback(null, buckets);
  });
}

Ruby

アプリケーションのデフォルト認証情報は、Ruby 用の Google 認証ライブラリ バージョン 0.1.0 より、利用することができます。Cloud Storage API など、Google Cloud Platform API へアクセスするために、Ruby 用の Google API クライアント ライブラリと併用して、次のような形で使用することができます。

require "google/apis/storage_v1"

# Alias the Google Cloud Storage module
Storage = Google::Apis::StorageV1

def list_buckets project_id
  # Create the storage service object, used to access the storage api.
  storage = Storage::StorageService.new
  # Have the service object use the application default credentials to
  # auth, which infers credentials from the environment.
  storage.authorization = Google::Auth.get_application_default(
    # Set the credentials to have a readonly scope to the storage service.
    Storage::AUTH_DEVSTORAGE_READ_ONLY
  )

  # Make the api call to list buckets owned by the default credentials.
  storage.list_buckets(project_id).items.each do |bucket|
    # Print out each bucket name.
    puts bucket.name
  end
end

Go

アプリケーションのデフォルト認証情報は、Go 用の Auth2 パッケージ 2015-03-18 より、利用することができます。Cloud Storage API など、Google Cloud Platform API へアクセスするために、Go 用のGoogle API クライアント ライブラリと併用して、次のような形で使用することができます。

// ListBuckets returns a slice of all the buckets for a given project.
func ListBuckets(projectID string) ([]*storage.Bucket, error) {
	ctx := context.Background()

	// Create the client that uses Application Default Credentials
	// See https://developers.google.com/identity/protocols/application-default-credentials
	client, err := google.DefaultClient(ctx, storage.DevstorageReadOnlyScope)
	if err != nil {
		return nil, err
	}

	// Create the Google Cloud Storage service
	service, err := storage.New(client)
	if err != nil {
		return nil, err
	}

	buckets, err := service.Buckets.List(projectID).Do()
	if err != nil {
		return nil, err
	}

	return buckets.Items, nil
}

.Net

アプリケーションのデフォルト認証情報は、.Net 用 Google API クライアント ライブラリ バージョン 1.9.3 より利用することができます。Cloud Storage API など、Google Cloud Platform API へアクセスするために、次のような形で使用することができます。

/// <summary>
/// Creates an authorized Cloud Storage client service using Application 
/// Default Credentials.
/// </summary>
/// <returns>an authorized Cloud Storage client.</returns>
public StorageService CreateAuthorizedClient()
{
    GoogleCredential credential =
        GoogleCredential.GetApplicationDefaultAsync().Result;
    // Inject the Cloud Storage scope if required.
    if (credential.IsCreateScopedRequired)
    {
        credential = credential.CreateScoped(new[]
        {
            StorageService.Scope.DevstorageReadOnly
        });
    }
    return new StorageService(new BaseClientService.Initializer()
    {
        HttpClientInitializer = credential,
        ApplicationName = "DotNet Google Cloud Platform Auth Sample",
    });
}
/// <summary>
/// List the contents of a Cloud Storage bucket.
/// </summary>
/// <param name="bucket">the name of the Cloud Storage bucket.</param>
///<returns>a list of the contents of the specified bucket.</returns>
public Objects ListBucketContents(
    StorageService storage, string bucket)
{
    var request = new
        Google.Apis.Storage.v1.ObjectsResource.ListRequest(storage,
        bucket);
    var requestResult = request.Execute();
    return requestResult;
}

エラー処理

API リクエストの問題を解決するため、次のエラーコードの説明を利用してください。

エラーコード 説明
400 不正なリクエスト。リクエスト パラメータの一部が、無効です。
401 リクエストが認証されませんでした。認証トークンがない、もしくは無効、期限切れです。
403 アクセスが拒否されました。認証トークンの OAuth スコープが正しくない、クライアント プロジェクト用に API が有効化されていない、クライアント ID が リソースへアクセスできる適切な権限を有していない、などの可能性があります。
404 リソースが見つかりませんでした。もしくは、クライアントにアクセス権がありません。プライバシーの問題上、404 は 403 のアクセスの拒否の代わりとして使用される場合もあります。
409 競合しています。リソースの操作において、同時実行の競合が発生したためリクエストに失敗しました。
429 API 割り当て外。Google Cloud Platform Console を使用して、リクエストがアクセスしようとした API の割り当て使用量を確認してください。再試行するには、少なくとも 30 秒待ってください。
500 サーバー内部のエラー。クライアントは指数バックオフで再試行してください。再試行するには少なくとも 1 秒待ってください。
503 現在、サーバーが利用できない状態です。クライアントは指数バックオフで再試行してください。再試行するには少なくとも 1 秒待ってください。
504 期限の超過。この問題が頻繁に発生する場合は、期限要件に対応するためリクエストの複雑性を軽減してください。
592 リクエストがタイムアウトになりました。クライアントは指数バックオフで再試行してください。

外出先でもリソースをモニタリング

Google Cloud Console アプリを入手して、プロジェクトの管理にお役立てください。

フィードバックを送信...