アクセス制御の設定

アクセス制御は、Google Cloud プロジェクトのサービスとリソースにアクセスする権限を持つユーザーを決定します。App Engine には、アクセス制御の設定に関していくつかの個別のユースケースがあります。

  • Google Cloud プロジェクトへのアクセス権をチームメンバーに付与し、サービスをセットアップしてアプリをデプロイできるようにする。

  • Cloud Storage などの Google Cloud サービスへのアクセス権をアプリに付与する。すべての Cloud サービスでは、App Engine アプリからの呼び出しを含むすべての API 呼び出しに対して認証と認可が必要です。

  • Google Cloud プロジェクトのリソースへのアクセス権をユーザーに付与する。このユースケースは一般的ではないですが、アプリがユーザーの代わりに Cloud リソースへのアクセスをリクエストする必要がある場合もあります。たとえば、アプリはユーザーに属するデータにアクセスする必要がある場合があります。

このページには、各ユースケースでのアクセス制御の設定の概要が記載されています。

Google Cloud Platform がアクセス制御を処理する方法に関する背景情報については、Identity and Access Management(IAM)の概要をご覧ください。

チームメンバーにアクセスを付与する

デベロッパーが Google Cloud プロジェクトにアクセスできるようにするには、次のいずれかまたは両方を作成します。

  • Google アカウントに関連付けられており、プロジェクトの特定の個人を表すユーザー アカウント

    ユーザー アカウントは、次のツールの認証に使用できます。

    • Google Cloud コンソール
    • Google Cloud CLI
    • gcloud CLI を使用して App Engine アプリをテストしてデプロイする IDE とビルドツール
  • 個人ではなくアプリケーションまたはプロセスを表すサービス アカウント。特に複数のデベロッパーがこれらのプロセスを実行できる場合は、自動化されたビルド、テスト、デプロイ プロセスでサービス アカウントを使用します。

    サービス アカウントは、次のツールの認証に使用できます。

    • gcloud CLI
    • gcloud CLI のツールを使用して App Engine アプリをテストしデプロイする IDE とビルドツール

ユーザー アカウントを作成する

  1. Google Cloud コンソールで [IAM] ページを開きます。

    [IAM] ページを開く

  2. [プロジェクトを選択] をクリックし、プロジェクトを選択して [開く] をクリックします。

  3. [追加] をクリックします。

  4. メールアドレスを入力します。

  5. App Engine 機能へのアクセス権を付与する役割を選択します。

    ユーザーが他のクラウド サービスにもアクセスする必要がある場合は、他のクラウド サービスへのアクセス権を付与する役割を選択します。

  6. [保存] をクリックします。

これでユーザーが、Google Cloud コンソールにログインし、gcloud CLI を承認できるようになりました。

gcloud、REST API、またはクライアント ライブラリからユーザー アカウントを作成することもできます。

サービス アカウントを作成する

  1. Google Cloud コンソールで [サービス アカウント] ページを開きます。

    [サービス アカウント] ページを開く

  2. プロジェクトを選択し、[開く] をクリックします。

  3. [サービス アカウントを作成] をクリックします。

  4. サービス アカウント名を入力します。表示用のわかりやすい名前にしてください。

  5. [作成] をクリックします。

  6. App Engine 機能へのアクセス権を付与する役割を選択します。

    サービス アカウントが他の Cloud サービスにもアクセスする必要がある場合は、他の Cloud サービスへのアクセス権を付与する役割を選択します。

  7. [続行] をクリックします。

  8. 必要に応じて、サービス アカウントを管理できるユーザー アカウントを指定します。サービス アカウントを使用して、サービス アカウントからアクセス可能なすべてのリソースに間接的にアクセスできるユーザー アカウントを指定することもできます。

  9. [保存] をクリックします。

    既存のサービス アカウントのリストが表示されます。

  10. Google Cloud の外部でサービス アカウントを使用する必要がある場合は、サービス アカウント キーの作成の手順を行います。

次のステップ

  • 自動化されたビルドとデプロイ プロセスでサービス アカウントを使用している場合、gcloud CLI をサービス アカウントで承認します
  • IDE でサービス アカウントを使用している場合は、IDE の指示に従ってください。
  • 他の Google Cloud サービスにアクセスするとき、またはタスクを実行するときに、App Engine アプリのバージョンに一意の ID を使用する必要がある場合は、App Engine でユーザー管理のサービス アカウントを指定できます。

アプリにクラウド サービスへのアクセスを許可

App Engine アプリから Cloud Storage などの他の Cloud サービスへの呼び出しを含め、Cloud サービスへのすべての呼び出しを認証および承認する必要があります。

デフォルトでは、App Engine アプリから同じプロジェクト内のサービスへの呼び出しが許可されます。デフォルト フローの仕組みは次のとおりです。

  1. Cloud サービスへの呼び出しを開始するには、アプリでクライアント オブジェクトを作成します。クライアント オブジェクトには、アプリがサービスと対話するために必要な認証情報やデータが含まれます。クライアントのコンストラクタで認証情報を指定しない場合、クライアントはアプリの環境で認証情報を探します。

    Cloud Storage のクライアントの作成例を次に示します。

    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)
    	}
    	defer storageClient.Close()
    
    	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 NewService to create the client.
    	kmsService, err := cloudkms.NewService(ctx)
    	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.
    async function listBuckets() {
      try {
        const results = await storage.getBuckets();
    
        const [buckets] = results;
    
        console.log('Buckets:');
        buckets.forEach(bucket => {
          console.log(bucket.name);
        });
      } catch (err) {
        console.error('ERROR:', err);
      }
    }
    listBuckets();

    PHP

    // Imports the Cloud Storage client library.
    use Google\Cloud\Storage\StorageClient;
    
    /**
     * Authenticate to a cloud client library using a service account implicitly.
     *
     * @param string $projectId The Google project ID.
     */
    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

    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;
    }
    
  2. デフォルトでは、アプリの環境にはデフォルト App Engine サービス アカウントの認証情報が含まれています。

    このサービス アカウントは、App Engine アプリを作成するときに Google が作成し、Google Cloud プロジェクト内のすべての Cloud サービスを管理および使用する権限をすべて付与します。

このデフォルトのフローは、次のいずれかの方法でオーバーライドできます。

  • GOOGLE_APPLICATION_CREDENTIALS 環境変数を設定します。この変数が設定されている場合、Cloud サービスはデフォルトのサービス アカウントの代わりに変数で指定された認証情報を使用します。

  • Cloud サービスの Client オブジェクトをインスタンスにするときに認証情報を指定します。たとえば、アプリが別のプロジェクトで Cloud サービスを呼び出す場合は、手動で認証情報を渡す必要があります。

コード内に GOOGLE_APPLICATION_CREDENTIALS 環境変数を設定するか認証情報を渡す場合は、次のいずれかの方法で認証情報を保存することをおすすめします。

  • Datastore モードの Firestore(Datastore)などの安全な場所に認証情報を保存して実行時に取得する。
  • コード内に認証情報を保存して Cloud KMS などのキーストアで暗号化する。

各アプローチの利点については、シークレット管理ソリューションの選択をご覧ください。

ユーザーに Cloud リソースへのアクセス権を付与する

アプリで別の Google サービスからユーザーデータを読み取るには、OAuth 2.0 for Web Server Applications を設定する必要があります。たとえば、Google ドライブからユーザーのデータを取得し、アプリで使用する場合、OAuth 2.0 for Web Server Applications を使用して特定のデータを共有しながら、ユーザー名やパスワードなどの他のデータは非公開のままにします。

Google Workspace ドメイン全体の権限の委任

Google Workspace(旧 G Suite)ドメインがある場合、ドメイン管理者は、Google Workspace ドメインのユーザーに代わってユーザーデータにアクセスするアプリケーションを認可できます。たとえば、Google Calendar API を使用して Google Workspace ドメイン内のすべてのユーザーのカレンダーに予定を追加するアプリケーションの場合、ユーザーの代わりにサービス アカウントを使用して Google Calendar API にアクセスします。

ドメイン内でユーザーに代わってデータにアクセスすることをサービス アカウントに承認することは、サービス アカウントへの「ドメイン全体の権限の委任」と呼ばれることもあります。これも OAuth 2.0 を使用し、Google Workspace ドメインの管理者がサービス アカウントにドメイン全体の権限を認可することを必要とします。

サービス アカウントを指定する

App Engine では、2 種類のサービス アカウントを使用できます。

  • バージョンごとのサービス アカウント: デプロイされたサービスの特定のバージョンの ID として構成されたサービス アカウントです。既存のバージョンまたは新しいバージョンをデプロイするときに、そのバージョンの ID として機能するサービス アカウントを指定できます。たとえば、アプリレベルのデフォルト サービス アカウントとは異なる権限がバージョンに必要な場合は、そのバージョンに固有のサービス アカウントを割り当てることができます。詳細については、App Engine サービス アカウントの構成をご覧ください。
  • アプリレベルのデフォルトのサービス アカウント: バージョンごとのサービス アカウントを構成しない場合、Google Cloud はデプロイされたすべてのサービスにアプリレベルのデフォルトのサービス アカウントを使用します。アプリレベルのデフォルトのサービス アカウントは、アプリの作成時に割り当てます。詳細については、アプリレベルのデフォルトのサービス アカウントを割り当てるをご覧ください。

    アプリレベルのデフォルト サービス アカウントを割り当てない場合は、Google Cloud は自動的に作成された App Engine のデフォルト サービス アカウントPROJECT_ID@appspot.gserviceaccount.com)を使用します。

    組織のポリシーの構成によっては、デフォルトのサービス アカウントにプロジェクトの編集者のロールが自動的に付与される場合があります。iam.automaticIamGrantsForDefaultServiceAccounts 組織ポリシー制約を適用して、自動的なロール付与を無効にすることを強くおすすめします。2024 年 5 月 3 日以降に組織を作成した場合、この制約はデフォルトで適用されます。

    自動ロール付与を無効にする場合、デフォルトのサービス アカウントに付与するロールを決定し、これらのロールを付与する必要があります。

    デフォルトのサービス アカウントにすでに編集者ロールが設定されている場合は、編集者ロールを権限の低いロールに置き換えることをおすすめします。サービス アカウントのロールを安全に変更するには、Policy Simulator を使用して変更の影響を確認してから、適切なロールを付与または取り消す操作を行います。