サービス アカウントについて

背景

サービス アカウントは特別なタイプの Google アカウントで、Google API のデータにアクセスして認証を受ける必要がある人間以外のユーザーを表します。

通常、サービス アカウントは次のような場合に使用されます。

  • 仮想マシン(VM)でのワークロードの実行。
  • Google API を呼び出すオンプレミスのワークステーションまたはデータセンターでのワークロードの実行。
  • 1 人のユーザーのライフサイクルに結び付けられていないワークロードの実行。

アプリケーションは Google API の呼び出しにサービス アカウントの ID を使用するため、ユーザーは直接関与しません。

サービス アカウントの管理

サービス アカウントが必要になったときは、そのサービス アカウントをどのように使用するかを把握するために次の事項をご確認ください。

  • サービス アカウントでアクセス可能なリソース
  • サービス アカウントに必要な権限
  • サービス アカウントの ID を前提とするコードが実行される場所(Google Cloud かオンプレミスか)

次のフローチャートを使って、上記の確認事項への答えを整理してください。

サービス アカウントのフローチャート

サービス アカウントは、リソースとしても ID としても扱うことができます。

サービス アカウントを ID として考える際は、プロジェクトなどのリソースにアクセスできるようにするために、サービス アカウントに役割を付与できます。

サービス アカウントをリソースとして考える際は、そのサービス アカウントに対するアクセスやアカウント管理を行うために、他のユーザーに役割を付与できます。

サービス アカウントへのアクセス権の付与

リソースにアクセスするためのアクセス権をサービス アカウントに付与する操作は、他の ID にアクセス権を付与する操作と同じです。たとえば、Compute Engine 上で実行するアプリケーションにのみ、Cloud Storage 内でオブジェクトを作成するための権限を付与したい場合は、そのアプリケーションのサービス アカウントを作成し、そのサービス アカウントにストレージのオブジェクト作成者のロールを付与します。次の図は、この例を示しています。

サービス アカウントのフローチャート

サービス アカウントを含むすべてのタイプのメンバーにロールを付与する方法をご確認ください。

サービス アカウントの管理

時間の経過とともに、作成したサービス アカウントの数が増えてくると、どのサービス アカウントがどのような目的に使われているかの区別が難しくなることがあります。

サービス アカウントの表示名は、サービス アカウントの目的や担当者など、そのサービス アカウントに関する追加情報を管理するために利用できます。新しいサービス アカウントの場合は、サービス アカウントの作成時に表示名を入力できます。既存のサービス アカウントの場合は、serviceAccounts.update() メソッドを使用して表示名を変更します。

未使用のサービス アカウントの識別

未使用のサービス アカウントは不要なセキュリティ リスクをもたらすため、未使用のサービス アカウントを無効にすることをおすすめします。また、サービス アカウントが不要になった場合は、そのサービス アカウントを削除するようにしてください。未使用のサービス アカウントは次の方法で識別できます。

サービス アカウントの削除と再作成

サービス アカウントを削除した後に、同じ名前で新しいサービス アカウントを作成できます。

サービス アカウントを削除しても、そのアカウントのロール バインディングがすぐに削除されるわけではありません。代わりに、ロール バインディングはサービス アカウントの先頭に deleted: という接頭辞を付けます。例については、削除されたメンバーを含むポリシーをご覧ください。

最近削除されたサービス アカウントと同じ名前で新しいサービス アカウントを作成した場合、古いバインディングが削除されていない可能性があります。ただし、両方のアカウントのメールアドレスが同じでも、新しいサービス アカウントに古いバインディングは適用されません。この現象は、作成時にサービス アカウントに Identity and Access Management(IAM)内で一意の ID が付与されるために発生します。内部的には、すべてのロール バインディングはサービス アカウントのメールアドレスではなく、これらの ID を使用して付与されます。したがって、削除されたサービス アカウントのロール バインディングは、同じメールアドレスを使用する新しいサービス アカウントには適用されません。

同様に、リソースに対するサービス アカウントの関連付けを行ってからそのサービス アカウントを削除し、同じ名前で新しいサービス アカウントを作成した場合、新しいサービス アカウントはリソースに関連付けられません

予期しない動作を回避するには、サービス アカウントごとに新しい一意の名前を使用します。サービス アカウントを誤って削除した場合は、新しいサービス アカウントを作成せずにサービス アカウントの削除を取り消すこともできます。

元のサービス アカウントの削除を取り消すことができないときに、同じ名前とロールで新しいサービス アカウントを作成する必要がある場合は、そのロールを新しいサービス アカウントに付与する必要があります。詳細については、削除されたメンバーを含むポリシーをご覧ください。

新しいサービス アカウントを元のサービス アカウントと同じリソースに関連付ける必要がある場合は、次のいずれかを行います。

サービス アカウントの権限

このセクションでは、サービス アカウントに付与される権限、またはサービス アカウントに成り代わる権限があるユーザー アカウントの一般的なシナリオについて説明します。

サービス アカウントに最小限の権限を付与する

他のタイプのメンバーと同様に、サービス アカウントには、そのサービス アカウントの目的を達成するために必要な最低限の権限セットのみ付与するようにします。サービス アカウントを含むすべてのタイプのメンバーにロールを付与する方法をご確認ください。

サービス アカウントにアクセスするための権限をユーザーに付与する際には、そのサービス アカウントが権限を持つすべてのリソースにユーザーがアクセスできることを念頭に置く必要があります。そのため、サービス アカウントの権限の構成は慎重に行い、チームのどのユーザーがサービス アカウントとして操作できるのか、またはサービス アカウントになり代わることができるのかを厳密に決める必要があります。Compute Engine と App Engine のデフォルト サービス アカウントなど、高度な権限を付与されたサービス アカウントにユーザーがなり代わることを許可する場合は特に注意してください。

App Engine と Compute Engine のインスタンスを更新する IAM ロールを付与されたユーザー(App Engine のデプロイ担当者Compute インスタンス管理者など)は実質的に、これらのインスタンスの実行に使用されるサービス アカウントとしてコードを実行できるため、これらのサービス アカウントがアクセス権を持つすべてのリソースに間接的にアクセスできます。同様に、Compute Engine インスタンスに対する SSH アクセス権を与えると、そのインスタンスとしてコードを実行できるようになる可能性があります。

一般的なシナリオのサービス アカウント権限

サービス アカウントはさまざまなシナリオで使用でき、それぞれに特定の権限が必要です。このセクションでは、一般的なシナリオと必要な権限について説明します。

サービス アカウントをリソースに関連付ける

サービス アカウントとして認証する長時間実行ジョブを開始する場合は、ジョブを実行するリソースにサービス アカウントを関連付ける必要があります。

権限:

  • リソースを作成する権限
  • iam.serviceAccounts.actAs

これらの権限を含むロールを検索するには、ロールリストで権限を検索します。

長時間実行ジョブをサービス アカウントとして実行できる複数の異なる Google Cloud リソースが存在します。こうしたリソースの例として次のものがあります。

  • Compute Engine VM
  • App Engine アプリ
  • Cloud Functions

これらのリソースを作成するときに、サービス アカウントを関連付けることもできます。このサービス アカウントは、リソースの ID として機能します。

リソースを作成してサービス アカウントを関連付けるには、対象のリソースを作成する権限と、リソースに関連付けるサービス アカウントになり代わる権限が必要です。サービス アカウントになり代わる権限は、iam.serviceAccounts.actAs 権限を含むロールによって付与されます。

リソースを作成し、サービス アカウントを関連付けると、リソースに対して長時間実行ジョブを開始できます。ジョブは、リソースに関連付けられたサービス アカウントとして実行され、そのサービス アカウントを使用して Google Cloud APIs へのリクエストを承認します。

リソースに対するサービス アカウントの関連付けの詳細については、サービス アカウントをリソースに関連付けるをご覧ください。

サービス アカウントに直接なり代わる

権限:

  • iam.serviceAccounts.getAccessToken
  • iam.serviceAccounts.signBlob
  • iam.serviceAccounts.signJwt
  • iam.serviceAccounts.implicitDelegation

ロール:

  • roles/iam.serviceAccountTokenCreator(サービス アカウント トークン作成者)

必要な権限が付与されると、ユーザーまたはサービスは、いくつかの一般的なシナリオでサービス アカウントの ID を直接成り代わる(表明する)ことができます。

まずユーザーは、iam.serviceAccounts.getAccessToken 権限を使用して、generateAccessToken() メソッドを呼び出すことによって、サービス アカウントの短期認証情報を取得できます。短期認証情報を使用することによって、ユーザーは Google Cloud にコマンドを発行し、そのサービス アカウントがアクセス権を持つすべてのリソースにアクセスできます。たとえば、このフローに従うと、ユーザーは gcloud --impersonate-service-account フラグを使用して、ダウンロードされた外部サービス アカウント キーを使用することなくサービス アカウントになり代わることができます。

次に、ユーザーは、iam.serviceAccounts.signBlob 権限を使用し、signBlob() または signJwt() メソッドを呼び出すことによって、サービス アカウントの Google が管理する秘密鍵で署名されたアーティファクトを取得できます。Google が管理する秘密鍵は常にエスクローに保管され、直接公開されることはありません。signBlob() は、任意のペイロード(Cloud Storage で署名された URL など)の署名を許可しますが、signJwt() は正しい形式の JWT の署名のみを許可します。

最後に、ユーザーはサービス アカウントの認証情報を取得することなく、サービス アカウントの代理操作や表明を行うことができます。これは高度な使用例であり、generateAccessToken() メソッドを使用したプログラムによるアクセスでのみサポートされています。少なくとも A、B、C の 3 つのサービス アカウントがあるシナリオでは、サービス アカウント A は、サービス アカウント A が B に対する iam.serviceAccounts.implicitDelegation 権限を付与されている場合にサービス アカウント C のアクセス トークンを取得することができ、B は C に対して iam.serviceAccounts.getAccessToken 権限が付与されます。

OpenID Connect(OIDC)ID トークンの生成

権限:

  • iam.serviceAccounts.getOpenIdToken

ロール:

  • roles/iam.serviceAccountTokenCreator(サービス アカウント トークン作成者)

ユーザーまたはサービスは、iam.serviceAccounts.getOpenIdToken 権限を使用してサービス アカウントの ID を表す Google OIDC プロバイダ(accounts.google.com)によって署名された OpenID Connect(OIDC)と互換性のある JWT トークンを生成できます。

これらのトークンは、あなたの組織が Google へのアクセスを許可するために追加の ID 連携をデプロイしないと、ほとんどの Google API に直接受け入れられることはありません。ユーザー実行アプリケーションへの OIDC ベースのアクセスを許可する Identity-Aware Proxy などのような例外もいくつかあります。

外部秘密鍵の生成

権限:

  • iam.serviceAccountKeys.create

ロール:

  • roles/editor(編集者)
  • roles/iam.serviceAccountAdmin(サービス アカウント管理者)

ユーザーまたはサービスは、サービス アカウントとして Google に直接認証する場合に使用できる外部秘密鍵マテリアル(RSA)を生成できます。この鍵マテリアルは、アプリケーションのデフォルト認証情報(ADC)ライブラリまたは gcloud auth activate-service-account コマンドで使用できます。鍵のマテリアルにアクセスできる人は、サービス アカウントが完全アクセス権を持つすべてのリソースに制限なくアクセスできます。そのような秘密鍵のマテリアルは最も注意して扱われるべきであり、マテリアルの存在が長いほど安全性が低くなると想定されます。したがって、秘密鍵のマテリアルをローテーションすることは、強固なセキュリティを維持するためには不可欠です。

サービス アカウント キーの管理

サービス アカウント キーには次の 2 種類があります。

  • Google Cloud が管理するキー。これらのキーは、App Engine や Compute Engine などの Google Cloud サービスで使用されます。これらをダウンロードすることはできません。また、これらのキーは自動的にローテーションされ、最長 2 週間署名のために使用されます。ローテーション プロセスは確率論的です。新しいキーの使用期間はキーの存続期間に応じて多少増減します。現在のキーセットに常にアクセスできるように、サービス アカウントの公開鍵セットのキャッシュ保存は、最長 24 時間に設定することをおすすめします。

  • ユーザーが管理するキー。これらのキーは、ユーザーによって作成、ダウンロード、管理されます。サービス アカウントから削除したキーは、認証に使用できなくなります。

ユーザーが管理するキーの場合は、以下のようなキー管理要件に対応するプロセスが用意されていることを確認する必要があります。

  • キーの保管
  • キーの配布
  • キーの取り消し
  • キーのローテーション
  • 不正ユーザーからのキーの保護
  • キーの復旧

サービス アカウントの有効な秘密鍵にアクセスできるユーザーは、サービス アカウントを介してリソースにアクセスできます。サービス アカウントに対するキーのアクセスのライフサイクル、つまりサービス アカウントがアクセスできるデータは、ダウンロードしたユーザーのライフサイクルとは無関係です。

デベロッパーがキーをソースコードに組み込んだり、ワークステーションのダウンロード ディレクトリに置いたままにしたりしないように指示してください。

キーのセキュリティを強化するため、次のガイダンスを遵守してください。

  • IAM Service Account API を使用して、サービス アカウント キーを自動的にローテーションします。キーをローテーションするには、新しいキーを作成し、アプリケーションでその新しいキーを使用するよう切り替えた後、古いキーを削除します。serviceAccount.keys.create() メソッドと serviceAccount.keys.delete() メソッドを組み合わせて使用して、ローテーションを自動化します。Google Cloud が管理するキーは、ほぼ毎週ローテーションされます。

Compute Engine でのサービス アカウントの使用

Compute Engine のインスタンスがその他の Google Cloud のリソースにアクセスするには、同インスタンスをサービス アカウントとして実行する必要があります。Compute Engine インスタンスの保護を強化するため、次の対応策を講じることをご検討ください。

  • 同じプロジェクトの複数の VM をそれぞれ異なるサービス アカウントで作成します。作成後に VM のサービス アカウントを変更するには、instances.setServiceAccount メソッドを使用します。

  • サービス アカウントに IAM のロールを付与することで、サービス アカウントでアクセスできるリソースを明確にします。これにより、多くのケースでスコープに依存する必要がなくなり、インスタンスを作成し直さなくても VM のサービス アカウントの権限を変更できるようになります。

  • インスタンスの Google Cloud リソースへのアクセス権はサービス アカウントによって決まるため、実行中のインスタンスで使用されているサービス アカウントは削除しないようにしてください。サービス アカウントを削除すると、インスタンスのオペレーションが失敗する場合があります。

ベスト プラクティス

  • サービス アカウントとして活動できるユーザーを指定します。サービス アカウントのサービス アカウント ユーザーであるユーザーは、そのサービス アカウントからアクセスできるすべてのリソースにアクセスできるようになります。そのため、serviceAccountUser のロールをユーザーに付与する際は十分な注意が必要です。

  • サービス アカウントには、そのサービス アカウントの目的を達成するために必要な最低限の権限セットのみ付与するようにします。サービス アカウントを含むすべてのタイプのメンバーにロールを付与する方法をご確認ください。

  • それぞれのサービス向けに、そのサービスで必要な権限のみを持つサービス アカウントを作成してください。

  • サービス アカウントの表示名を使ってサービス アカウントを管理してください。サービス アカウントの作成時に、そのサービス アカウントの使用目的がわかる表示名を入力します。

  • サービス アカウントの命名規則を定義してください。

  • ユーザー管理のサービス アカウント キーのローテーションを自動化するプロセスを実装します。

  • IAM Service Account API を使用して、キーのローテーションを実装します。

  • サービス アカウントとキーを監査するには、serviceAccount.keys.list() メソッドまたはコンソールの ログビューア ページを使用します。

  • アプリケーションがサービス アカウントにアクセスできないようにする場合を除いて、App Engine または Compute Engine で実行中のインスタンスによって使用されているサービス アカウントは削除しないでください。