たくあんポリポリ

勉強したことを載せていきます。最近、技術系の記事はZennに書いています。(https://zenn.dev/chittai)

【GCP】”IDとして”のサービスアカウントと”リソースとして”のサービスアカウント

サービスアカウントについて、どうしてもわからないところがあり、ドキュメントを読んで調べてみました。

わからなかったのは、下記記事にある

cloud.google.com

AM サービス アカウントの特長の 1 つは、リソースとしても ID としても扱うことができることです。

という記述についてです。

多くのサイトにサービスアカウントを使用した別サービスへのアクセス方法が書かれているのですが、これがIDとしてなのかリソースとしてなのか明確な記述がないため、どちらとして使われているのかよくわからず、ドキュメントを読んで自分なりの解釈をまとめることにしました。

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

まずは、ドキュメントからID・リソースとして扱う場合の記述があるので引用してみます。

サービス アカウントを ID として扱う場合は、サービス アカウントに役割を付与して、リソース(プロジェクトなど)にアクセスできるようにすることができます。

上記がIDとしてのサービスアカウントの説明です。

サービス アカウントをリソースとして扱う場合、そのサービス アカウントにアクセスする権限をユーザーに与えることができます。ユーザーには、サービス アカウントにアクセスするためのオーナー、編集者、閲覧者、サービス アカウント ユーザーの役割を付与することができます。

上記がリソースとしてのサービスアカウントの説明です。これらの説明を絵にしてみると、↓のようになるかと思います。(SAは”サービスアカウント”です)

f:id:c_taquna:20190813013440j:plain:w400

なんとなくですが、イメージがつかめてくるかと思います。ただ、まだどんな時にどちらを使用すればいいのかよくわかりません。

IDとしてのサービスアカウント

そもそも、IDとは何なのか確認します。

cloud.google.com

Google Cloud Platform(GCP)に備わっている Cloud IAM を使用すると、誰(ID)がどのリソースに対するどのようなアクセス権限(役割)を持つかを定義することで、アクセス制御を管理できます。

”誰が”という主語になるような対象がIDであることがわかります。同じドキュメントにその主語になるのがどんなものか記載があります。

Google アカウント

サービス アカウント

Google グループ

G Suite ドメイン

Cloud Identity ドメイン

確かに、この中にサービスアカウントの記述があります。つまり、IDとしてのサービスアカウントGoogle アカウント等と同列の存在であることがわかります。

f:id:c_taquna:20190813012507p:plain

これは、ドキュメントから持ってきた図ですが、このサービスアカウントのキーを使用して、認証をアプリケーション内で行うことで別のサービスへアクセスすることができます。このアクセス対象はサービスアカウントへ付与した役割に依存します。調べてみた感じ、使用方法として説明されているのはこのIDとしてのサービスアカウントが多いように思います。

リソースとしてのサービスアカウント

ここでもリソースという言葉の定義について確認してみます。

cloud.google.com

リソースの例として、プロジェクト、Compute Engine インスタンス、Cloud Storage バケットなどがあります。

つまり、リソースとしてのサービスアカウントはComputeEngineなどの、IDが操作する対象と同列の存在であることがわかります。ただ、これだけだとなんのためにあるのか、どう使えばいいのかよくわかりません。

下記は、ドキュメント内にあるリソースとしてのサービスアカウントの使用例です。

サービス アカウントとしての動作 たとえば、従業員が開始権限を持っている長期間実行ジョブがあり、その仕事を最後に開始した従業員が退社しても、その仕事が終了してしまうことがないようにするとします。

このようなときは、ジョブの開始と終了を行うためのサービス アカウントを作成すれば問題を解決することができます。手順は次のとおりです。

1. サービス アカウントを作成します。

2. サービス アカウントのサービス アカウント ユーザー(iam.serviceAccountUser)の役割を、ジョブを開始する権限が必要な従業員に付与します。このシナリオでは、サービスはリソースです。

3. Compute インスタンス管理者(roles/compute.instanceAdmin.v1)役割を同じ従業員に付与します。

4. 従業員は、そのサービス アカウントを実行する Compute Engine インスタンスを作成して接続し、サービス アカウントを使用してジョブを開始できます。次に例を示します。

gcloud compute instances create my-instance --scopes=cloud-platform \ --service-account=my-service-account@test9q.iam.gserviceaccount.com \ --zone=us-central1-a

さらに、下記の注意書きがあります。

注: サービス アカウント ユーザーおよび Compute インスタンス管理者の役割を持つユーザーは、サービス アカウントがアクセスできるすべてのリソースに間接的にアクセスし、Compute Engine インスタンスの作成、変更、削除を行うことができます。そのため、これらの役割をユーザーに付与する際は注意が必要です。

ここから下記が言えると思います。

  • リソースを操作するユーザにサービス アカウント ユーザー(iam.serviceAccountUser)の役割を付与する
  • 同じユーザに、操作するリソースの管理者役割を付与する(今回は Compute インスタンス管理者(roles/compute.instanceAdmin.v1))
  • サービス アカウント ユーザー(iam.serviceAccountUser)と Compute インスタンス管理者(roles/compute.instanceAdmin.v1)の役割を持っているユーザは、サービス アカウントがアクセスできるすべてのリソースに間接的にアクセスすることができる

Compute Engine インスタンスを作成する時に、紐づくサービスアカウントを指定することができるので、それらを加味して絵を修正すると

f:id:c_taquna:20190813022844j:plain:w400

こんな感じになるかなと。

まとめ

つまり、IDとしてのサービスアカウントはサービスアカウントが主体となりアプリケーションの中で認証を行いサービスへのアクセスを提供する。リソースとしてのサービスアカウントはサービスアカウントがサービスへのアクセスを提供するが、アプリケーションを実行するのはユーザ?

設計として、アプリケーションの実行をサービスアカウントで管理するのか、ユーザで管理するのかの違い??どう使い分ければよいのか、シナリオをもう少し探してみよう。