サーバー間での本番環境アプリケーションの認証の設定

このガイドでは、サーバー間の本番環境アプリケーションの認証と承認について説明します。認証とは、クライアントの身元を判別するためのプロセスです。承認とは、特定のリソースに対して認証されたクライアントがどのような権限を持つかを決定するためのプロセスです。つまり、認証とはユーザーを識別するもので、承認とはユーザーが行えることを決定するものです。サポートされている認証方法と、それらの選択方法の詳細については、認証の概要をご覧ください。

Google は、認証情報を使用して、割り当てと課金に関してアプリケーションを識別します。また、認証情報は GCP API、リソース、および機能へのアクセスを承認するためにも使用されます。

アプリケーションに認証情報を提供する

GCP クライアント ライブラリでは、アプリケーションのデフォルト認証情報(ADC)と呼ばれる方式を使用してアプリケーションの認証情報が検出されます。コードでクライアント ライブラリが使用されると、この方式により、以下の順番で認証情報がチェックされます。

  1. まず、ADC は環境変数 GOOGLE_APPLICATION_CREDENTIALS が設定されているかどうかを確認します。変数が設定されている場合、ADC はその変数が指しているサービス アカウント ファイルを使用します。

  2. 環境変数が設定されていない場合、ADC は、サービスで実行されているアプリケーションに応じて、Compute Engine、Kubernetes Engine、App Engine、または Cloud Functions によって提供されているデフォルトのサービス アカウントを使用します。

  3. ADC が上記のどの認証情報も使用できない場合、エラーが生じます。

以下のサンプルコードは、この方式を表しています。サンプルでは、アプリケーション認証情報は明示的には指定されていません。しかし、ADC は、GOOGLE_APPLICATION_CREDENTIALS 環境変数が設定されているか、アプリケーションが Compute Engine、Kubernetes Engine、App Engine、または Cloud Functions で実行されていれば、認証情報を暗黙的に検出できます。

C#

public object AuthImplicit(string projectId)
{
    // If you don't specify credentials when constructing the client, the
    // client library will look for credentials in the environment.
    var storage = StorageClient.Create();
    // Make an authenticated API request.
    var buckets = storage.ListBuckets(projectId);
    foreach (var bucket in buckets)
    {
        Console.WriteLine(bucket.Name);
    }
    return null;
}

Go

// For API packages whose import path is starting with "cloud.google.com/go",
// such as cloud.google.com/go/storage in this case, if there are no credentials
// provided, the client library will look for credentials in the environment.
storageClient, err := storage.NewClient(ctx)
if err != nil {
	log.Fatal(err)
}

it := storageClient.Buckets(ctx, "project-id")
for {
	bucketAttrs, err := it.Next()
	if err == iterator.Done {
		break
	}
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(bucketAttrs.Name)
}

// For packages whose import path is starting with "google.golang.org/api",
// such as google.golang.org/api/cloudkms/v1, use the
// golang.org/x/oauth2/google package as shown below.
oauthClient, err := google.DefaultClient(ctx, cloudkms.CloudPlatformScope)
if err != nil {
	log.Fatal(err)
}

kmsService, err := cloudkms.New(oauthClient)
if err != nil {
	log.Fatal(err)
}

Node.js

// Imports the Google Cloud client library.
const Storage = require('@google-cloud/storage');

// Instantiates a client. If you don't specify credentials when constructing
// the client, the client library will look for credentials in the
// environment.
const storage = Storage();

// Makes an authenticated API request.
storage
  .getBuckets()
  .then((results) => {
    const buckets = results[0];

    console.log('Buckets:');
    buckets.forEach((bucket) => {
      console.log(bucket.name);
    });
  })
  .catch((err) => {
    console.error('ERROR:', err);
  });

PHP

namespace Google\Cloud\Samples\Auth;

// Imports the Google Cloud Storage client library.
use Google\Cloud\Storage\StorageClient;

function auth_cloud_implicit($projectId)
{
    $config = [
        'projectId' => $projectId,
    ];

    # If you don't specify credentials when constructing the client, the
    # client library will look for credentials in the environment.
    $storage = new StorageClient($config);

    # Make an authenticated API request (listing storage buckets)
    foreach ($storage->buckets() as $bucket) {
        printf('Bucket: %s' . PHP_EOL, $bucket->name());
    }
}

Python

def implicit():
    from google.cloud import storage

    # If you don't specify credentials when constructing the client, the
    # client library will look for credentials in the environment.
    storage_client = storage.Client()

    # Make an authenticated API request
    buckets = list(storage_client.list_buckets())
    print(buckets)

Ruby

# project_id = "Your Google Cloud project ID"

require "google/cloud/storage"

# If you don't specify credentials when constructing the client, the client
# library will look for credentials in the environment.
storage = Google::Cloud::Storage.new project: project_id

# Make an authenticated API request
storage.buckets.each do |bucket|
  puts bucket.name
end

サービス アカウントの認証情報の手動による取得と提供

コードをローカルで開発したり、アプリケーションをオンプレミスでデプロイしたり、別のパブリック クラウドにデプロイしたりする場合、サービス アカウントの認証情報を手動で作成し、取得することができます。

サービス アカウントの作成方法の詳細については、認証の開始をご覧ください。リンクされたガイドによって、オーナーレベルの権限を持つサービス アカウントを作成する手順は確認できますが、本番環境アプリケーションの場合、以下のアクセスを制限するセクションで説明されているように、アクセスを制限してください。

サービス アカウントを作成し、環境変数を設定すると、アプリケーションに認証情報を提供するで説明されているように、ADC は認証情報を暗黙的に判別できるようになります。コードの使用が少なくて済むため、この方法をおすすめします。

あるいは、以下のサンプルコードで示されているように、コードでサービス アカウント ファイルを明示的に指すようにすることもできます。

C#

public object AuthExplicit(string projectId, string jsonPath)
{
    // Explicitly use service account credentials by specifying the private key
    // file.
    GoogleCredential credential = null;
    using (var jsonStream = new FileStream(jsonPath, FileMode.Open,
        FileAccess.Read, FileShare.Read))
    {
        credential = GoogleCredential.FromStream(jsonStream);
    }
    var storage = StorageClient.Create(credential);
    // Make an authenticated API request.
    var buckets = storage.ListBuckets(projectId);
    foreach (var bucket in buckets)
    {
        Console.WriteLine(bucket.Name);
    }
    return null;
}

Node.js

// Imports the Google Cloud client library.
const Storage = require('@google-cloud/storage');

// Instantiates a client. Explicitly use service account credentials by
// specifying the private key file. All clients in google-cloud-node have this
// helper, see https://googlecloudplatform.github.io/google-cloud-node/#/docs/google-cloud/latest/guides/authentication
const storage = Storage({
  keyFilename: '/path/to/keyfile.json'
});

// Makes an authenticated API request.
storage
  .getBuckets()
  .then((results) => {
    const buckets = results[0];

    console.log('Buckets:');
    buckets.forEach((bucket) => {
      console.log(bucket.name);
    });
  })
  .catch((err) => {
    console.error('ERROR:', err);
  });

PHP

namespace Google\Cloud\Samples\Auth;

// Imports the Google Cloud Storage client library.
use Google\Cloud\Storage\StorageClient;

function auth_cloud_explicit($projectId, $serviceAccountPath)
{
    # Explicitly use service account credentials by specifying the private key
    # file.
    $config = [
        'keyFilePath' => $serviceAccountPath,
        'projectId' => $projectId,
    ];
    $storage = new StorageClient($config);

    # Make an authenticated API request (listing storage buckets)
    foreach ($storage->buckets() as $bucket) {
        printf('Bucket: %s' . PHP_EOL, $bucket->name());
    }
}

Python

def explicit():
    from google.cloud import storage

    # Explicitly use service account credentials by specifying the private key
    # file.
    storage_client = storage.Client.from_service_account_json(
        'service_account.json')

    # Make an authenticated API request
    buckets = list(storage_client.list_buckets())
    print(buckets)

Ruby

# project_id = "Your Google Cloud project ID"
# key_file   = "path/to/service-account.json"
require "google/cloud/storage"

# Explicitly use service account credentials by specifying the private key
# file.
storage = Google::Cloud::Storage.new project: project_id, keyfile: key_file

# Make an authenticated API request
storage.buckets.each do |bucket|
  puts bucket.name
end

Compute Engine、Kubernetes Engine、App Engine フレキシブル環境、および Cloud Functions での証情報の取得

アプリケーションが Compute EngineKubernetes EngineApp Engine フレキシブル環境、または Cloud Functions で実行されている場合、独自のサービス アカウントを作成する必要はありません。Compute Engine には自動で作成されるデフォルトのサービス アカウントガ含まれており、必要に応じて、インスタンスごとに異なるサービス アカウントを割り当てることができます。新しいインスタンスを作成すると、そのインスタンスは自動的にデフォルト サービス アカウントとして実行できるようになり、承認許可のデフォルト設定を使用できるようになります。詳細については、Compute Engine のデフォルトのサービス アカウントをご覧ください。

サービス アカウントをセットアップすると、上記のセクションで説明されているように、コードを変更しなくても、ADC は認証情報を暗黙的に検出できるようになります。Compute Engine 認証情報を明確に使用する必要がある場合は、以下のサンプルコードに示されているように、明示的にそれを行うことができます。

C#

public object AuthExplicitComputeEngine(string projectId)
{
    // Explicitly use service account credentials by specifying the
    // private key file.
    GoogleCredential credential =
        GoogleCredential.FromComputeCredential();
    var storage = StorageClient.Create(credential);
    // Make an authenticated API request.
    var buckets = storage.ListBuckets(projectId);
    foreach (var bucket in buckets)
    {
        Console.WriteLine(bucket.Name);
    }
    return null;
}

PHP

namespace Google\Cloud\Samples\Auth;

// Imports GCECredentials and the Google Cloud Storage client library.
use Google\Auth\Credentials\GCECredentials;
use Google\Cloud\Storage\StorageClient;

function auth_cloud_explicit_compute_engine($projectId)
{
    $gceCredentials = new GCECredentials();
    $config = [
        'projectId' => $projectId,
        'credentialsFetcher' => $gceCredentials,
    ];
    $storage = new StorageClient($config);

    # Make an authenticated API request (listing storage buckets)
    foreach ($storage->buckets() as $bucket) {
        printf('Bucket: %s' . PHP_EOL, $bucket->name());
    }
}

Python

def explicit_compute_engine(project):
    from google.auth import compute_engine
    from google.cloud import storage

    # Explicitly use Compute Engine credentials. These credentials are
    # available on Compute Engine, App Engine Flexible, and Container Engine.
    credentials = compute_engine.Credentials()

    # Create the client using the credentials and specifying a project ID.
    storage_client = storage.Client(credentials=credentials, project=project)

    # Make an authenticated API request
    buckets = list(storage_client.list_buckets())
    print(buckets)

Ruby

require "googleauth"
require "google/cloud/env"
require "google/cloud/storage"

# Explicitly use Compute Engine credentials and a project ID to create a new
# Cloud Storage client. These credentials are available on Compute Engine,
# App Engine Flexible, and Container Engine.
storage = Google::Cloud::Storage.new project: Google::Cloud.env.project_id,
                                     keyfile: Google::Auth::GCECredentials.new

# Make an authenticated API request
storage.buckets.each do |bucket|
  puts bucket.name
end

App Engine スタンダード環境での認証情報の取得

アプリケーションが App Engine スタンダード環境で実行されている場合、App Engine App Identity API を使用して認証情報を取得できます。

サービス アカウントをセットアップすると、上記のセクションで説明されているように、コードを変更しなくても、ADC は認証情報を暗黙的に検出できるようになります。App Engine 認証情報を明確に使用する必要がある場合は、以下のサンプルコードに示されているように、明示的にそれを行うことができます。

PHP

namespace Google\Cloud\Samples\Auth;

// Imports AppIdentityCredentials and the Google Cloud Storage client library.
use Google\Auth\Credentials\AppIdentityCredentials;
use Google\Cloud\Storage\StorageClient;

function auth_cloud_explicit_app_engine($projectId)
{
    # Learn more about scopes at https://cloud.google.com/storage/docs/authentication#oauth-scopes
    $scope = 'https://www.googleapis.com/auth/devstorage.read_only';
    $gaeCredentials = new AppIdentityCredentials($scope);
    $config = [
        'projectId' => $projectId,
        'credentialsFetcher' => $gaeCredentials,
    ];
    $storage = new StorageClient($config);

    # Make an authenticated API request (listing storage buckets)
    foreach ($storage->buckets() as $bucket) {
        printf('Bucket: %s' . PHP_EOL, $bucket->name());
    }
}

Python

def explicit_app_engine(project):
    from google.auth import app_engine
    import googleapiclient.discovery

    # Explicitly use App Engine credentials. These credentials are
    # only available when running on App Engine Standard.
    credentials = app_engine.Credentials()

    # Explicitly pass the credentials to the client library.
    storage_client = googleapiclient.discovery.build(
        'storage', 'v1', credentials=credentials)

    # Make an authenticated API request
    buckets = storage_client.buckets().list(project=project).execute()
    print(buckets)

アクセスを制限する

適用可能な GCP API、機能、またはリソースと対話するために必要な承認権限のみをアプリケーションに付与します。GCP では、アクセス制御に Cloud Identity and Access Management(Cloud IAM)が使用されます。サービス アカウントを作成するときに、Cloud IAM 役割を選択してアクセスを制限できます。認証の開始には、サービス アカウントを作成するときに Owner 役割を選択する手順が説明されています。この値は、いつでも変更できます。詳細については、サービス アカウントへの役割の付与をご覧ください。

認証情報を管理する際のベスト プラクティス

認証情報によって、機密データにアクセスできるようになります。以下の事項は、そのようなリソースへのアクセスを保護するのに役立ちます。

  • API キー、OAuth トークン、およびサービス アカウント認証情報など、認証に関する重要な情報をソースコード内に組み込まないでください。Cloud Key Management Service など、アプリケーションのソースコードの外部にある認証情報を指す環境変数を使用できます。

  • テスト環境と本番環境のように、異なるコンテキストには異なる認証情報を使用してください。

  • 認証情報が第三者に盗まれないように、認証情報の転送は必ず HTTPS 上で行ってください。けっして、テキストや URL の一部として転送しないようにしてください。

  • 長期間有効になっている認証情報をクライアント側アプリケーションに組み込まないでください。たとえば、モバイルアプリに、サービス アカウント認証情報を組み込まないでください。クライアント側アプリケーションを調べることができるため、認証情報が第三者によって簡単に見つけられて、使用されてしまう可能性があります。

  • 不要になったトークンは取り消してください。

API エラーのトラブルシューティング

失敗した API リクエストのトラブルシューティング方法について詳しくは、Cloud API のエラーをご覧ください。

次のステップ

このページは役立ちましたか?評価をお願いいたします。

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