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

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

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

アプリケーションの認証情報を指定する

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

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

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

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

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

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 credential = GoogleCredential.GetApplicationDefault();
    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;
}

Go

// implicit uses Application Default Credentials to authenticate.
func implicit() {
	ctx := context.Background()

	// 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)
	}

	_ = kmsService
}

Java

static void authImplicit() {
  // If you don't specify credentials when constructing the client, the client library will
  // look for credentials via the environment variable GOOGLE_APPLICATION_CREDENTIALS.
  Storage storage = StorageOptions.getDefaultInstance().getService();

  System.out.println("Buckets:");
  Page<Bucket> buckets = storage.list();
  for (Bucket bucket : buckets.iterateAll()) {
    System.out.println(bucket.toString());
  }
}

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 = new 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#

// Some APIs, like Storage, accept a credential in their Create()
// method.
public object AuthExplicit(string projectId, string jsonPath)
{
    // Explicitly use service account credentials by specifying
    // the private key file.
    var credential = GoogleCredential.FromFile(jsonPath);
    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;
}
// Other APIs, like Language, accept a channel in their Create()
// method.
public object AuthExplicit(string projectId, string jsonPath)
{
    var credential = GoogleCredential.FromFile(jsonPath)
        .CreateScoped(LanguageServiceClient.DefaultScopes);
    var channel = new Grpc.Core.Channel(
        LanguageServiceClient.DefaultEndpoint.ToString(),
        credential.ToChannelCredentials());
    var client = LanguageServiceClient.Create(channel);
    AnalyzeSentiment(client);
    return 0;
}

Go

// explicit reads credentials from the specified path.
func explicit(jsonPath, projectID string) {
	ctx := context.Background()
	client, err := storage.NewClient(ctx, option.WithCredentialsFile(jsonPath))
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Buckets:")
	it := client.Buckets(ctx, projectID)
	for {
		battrs, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(battrs.Name)
	}
}

Java

static void authExplicit(String jsonPath) throws IOException {
  // You can specify a credential file by providing a path to GoogleCredentials.
  // Otherwise credentials are read from the GOOGLE_APPLICATION_CREDENTIALS environment variable.
  GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(jsonPath))
        .createScoped(Lists.newArrayList("https://www.googleapis.com/auth/cloud-platform"));
  Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();

  System.out.println("Buckets:");
  Page<Bucket> buckets = storage.list();
  for (Bucket bucket : buckets.iterateAll()) {
    System.out.println(bucket.toString());
  }
}

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://github.com/GoogleCloudPlatform/google-cloud-node/blob/master/docs/authentication.md
const storage = new 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#

// Some APIs, like Storage, accept a credential in their Create()
// method.
public object AuthExplicitComputeEngine(string projectId)
{
    // Explicitly request service account credentials from the compute
    // engine instance.
    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;
}
// Other APIs, like Language, accept a channel in their Create()
// method.
public object AuthExplicitComputeEngine(string projectId)
{
    var credential = GoogleCredential.FromComputeCredential();
    var channel = new Grpc.Core.Channel(
        LanguageServiceClient.DefaultEndpoint.ToString(),
        credential.ToChannelCredentials());
    var client = LanguageServiceClient.Create(channel);
    AnalyzeSentiment(client);
    return 0;
}

Go

// explicitDefault finds the default credentials.
//
// It is very uncommon to need to explicitly get the default credentials in Go.
// Most of the time, client libraries can use Application Default Credentials
// without having to pass the credentials in directly. See implicit above.
func explicitDefault(projectID string) {
	ctx := context.Background()

	creds, err := google.FindDefaultCredentials(ctx, storage.ScopeReadOnly)
	if err != nil {
		log.Fatal(err)
	}
	client, err := storage.NewClient(ctx, option.WithCredentials(creds))
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Buckets:")
	it := client.Buckets(ctx, projectID)
	for {
		battrs, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(battrs.Name)
	}
}

Java

static void authCompute() {
  // Explicitly request service account credentials from the compute engine instance.
  GoogleCredentials credentials = ComputeEngineCredentials.create();
  Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();

  System.out.println("Buckets:");
  Page<Bucket> buckets = storage.list();
  for (Bucket bucket : buckets.iterateAll()) {
    System.out.println(bucket.toString());
  }
}

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());
    }
}

Go

// explicitDefault finds the default credentials.
//
// It is very uncommon to need to explicitly get the default credentials in Go.
// Most of the time, client libraries can use Application Default Credentials
// without having to pass the credentials in directly. See implicit above.
func explicitDefault(projectID string) {
	ctx := context.Background()

	creds, err := google.FindDefaultCredentials(ctx, storage.ScopeReadOnly)
	if err != nil {
		log.Fatal(err)
	}
	client, err := storage.NewClient(ctx, option.WithCredentials(creds))
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Buckets:")
	it := client.Buckets(ctx, projectID)
	for {
		battrs, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(battrs.Name)
	}
}

Java

static void authAppEngineStandard() throws IOException {
  // Explicitly request service account credentials from the app engine standard instance.
  GoogleCredentials credentials = AppEngineCredentials.getApplicationDefault();
  Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();

  System.out.println("Buckets:");
  Page<Bucket> buckets = storage.list();
  for (Bucket bucket : buckets.iterateAll()) {
    System.out.println(bucket.toString());
  }
}

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 のエラーをご覧ください。

次のステップ

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

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