0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GCPのサービスアカウントを徹底解説

0
Posted at

GCPを触り始めたときに、AWS経験者が特に混乱しやすい概念の1つが Service Account(サービスアカウント) です。

名前だけを見ると「ユーザーアカウントの一種?」と思いやすいですが、実際には違います。

GCPのService Accountは、ざっくり言うと、

VMやCloud Run、バッチ処理、アプリケーションなどがGCPリソースへアクセスするときに使う、システム用のIdentity

です。

AWSに慣れている人向けに言うと、

Service Account ≒ ワークロード用IAM Role

と考えるとかなり理解しやすくなります。

この記事では、Service Accountの基本からIAMとの関係、JSONキー、Compute Engine、Cloud Run、ローカル開発での使い方までまとめます。


Service Accountとは何か

GCPでは「誰が操作しているか」をIdentityとして扱います。

大きく分けると、人間とシステムがあります。

人間
  ↓
Googleアカウント
  ↓
GCPへアクセス

プログラム
  ↓
Service Account
  ↓
GCPへアクセス

例えば、人間であれば次のようなGoogleアカウントを使います。

tanaka@example.com

一方、プログラム用のService Accountは次のような形式です。

web-api-prod@my-project.iam.gserviceaccount.com

つまり、

Google Account
= 人間用Identity

Service Account
= システム・アプリ用Identity

という違いがあります。


AWSでいうと何に相当するのか

AWS経験者向けに整理すると、以下の対応関係が近いです。

AWS GCP
IAM User / IAM Identity Centerユーザー Googleアカウント
IAM Role Service Account
IAM Policy IAM Role
EC2 Instance Profile VMにService Accountをアタッチ
ECS Task Role Cloud Run / GKEなどのService Account
Lambda Execution Role Cloud FunctionsのService Account

ここで注意したいのが、GCPの「IAM Role」です。

AWSでは、

IAM Role

がIdentityと権限の両方を持っているように見えます。

一方GCPでは、

Service Account
= 誰として動くか

IAM Role
= 何をしてよいか

と分かれています。

例えば、

Service Account
web-api-prod@my-project.iam.gserviceaccount.com

      ↓

IAM Role
roles/storage.objectViewer

とすると、

web-api-prodというシステムIdentityはCloud Storageのオブジェクトを閲覧できる

という意味になります。


Service AccountとIAM Roleの関係

GCP IAMを理解するときは、次の3要素で考えると分かりやすいです。

Principal
   ↓
Role
   ↓
Resource

Principal

操作する主体です。

例えば、

Googleアカウント
Service Account
Google Group

などがあります。

Role

「何をしてよいか」という権限セットです。

例えば、

roles/storage.objectViewer
roles/storage.objectCreator
roles/storage.objectAdmin

などがあります。

Resource

対象となるGCPリソースです。

例えば、

Project
Cloud Storage Bucket
Compute Engine
Secret Manager

などです。

つまり、

web-api-prod
      ↓
Storage Object Viewer
      ↓
gs://my-images-prod

のような関係になります。


Service Accountは何に使うのか

代表的な用途は以下です。

Compute Engine
Cloud Run
Cloud Functions
GKE
バッチ処理
CI/CD
外部アプリケーション

例えばCompute Engine上のWebアプリがCloud Storageを読む場合、

Compute Engine
      ↓
Service Account
      ↓
Cloud Storage

という構成になります。

AWSでいう、

EC2
 ↓
IAM Role
 ↓
S3

とほぼ同じです。


VMにはService Accountを何個付けられるのか

Compute EngineのVMに直接アタッチできるService Accountは、基本的に1つです。

VM
 ↓
Service Account

ただし、そのService Accountには複数のIAM Roleを付与できます。

VM
 ↓
web-api-prod
 ├─ Storage Object Viewer
 ├─ Cloud SQL Client
 └─ Secret Manager Secret Accessor

そのため、

Service Accountを複数付ける

のではなく、

1つのService Accountに必要なRoleを複数付ける

という設計が一般的です。


処理ごとに権限を分けたい場合

1台のVM内でも、処理ごとに権限を分けたい場合があります。

例えば、

Webアプリ
→ Cloud Storage読み取りのみ

デプロイ処理
→ Artifact Registry書き込み

のようなケースです。

この場合はService Account Impersonationを利用できます。

VM
 ↓
vm-base Service Account
 ↓
Impersonation
 ├─ storage-reader
 └─ deployer

AWSでいう、

IAM Role
 ↓
sts:AssumeRole
 ↓
別IAM Role

に近い考え方です。


Service Account IDの形式

Service Accountは次のようなメールアドレス形式になります。

SERVICE_ACCOUNT_ID@PROJECT_ID.iam.gserviceaccount.com

例えば、

web-api-prod@my-project.iam.gserviceaccount.com

です。

このうち、

web-api-prod

がService Account IDです。

命名規則としては、例えば、

<system>-<role>-<env>

のようにすると管理しやすいです。

例:

web-api-prod
web-api-stg
batch-worker-prod
image-uploader-dev

Service AccountのJSONキーとは

Service Accountでは、JSON形式の秘密鍵を発行することもできます。

例えば、

{
  "type": "service_account",
  "project_id": "my-project",
  "private_key_id": "xxxxxxxx",
  "private_key": "-----BEGIN PRIVATE KEY-----\n...",
  "client_email": "web-api-dev@my-project.iam.gserviceaccount.com",
  "client_id": "1234567890"
}

このJSONファイルを使うことで、アプリケーションはそのService Accountとして認証できます。

AWSでいうと、

AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY

をファイル化したものに近いです。

特に重要なのが、

private_key

です。

この秘密鍵が漏洩すると、そのService Accountとしてアクセスされる可能性があります。


JSONキーはできるだけ使わない

GCP上で動作するアプリケーションでは、Service AccountのJSONキーは基本的に不要です。

例えばCompute Engineでは、

Compute Engine
 ↓
Service Account
 ↓
Metadata Server
 ↓
短期アクセストークン
 ↓
GCP API

という流れで認証されます。

AWSでいう、

EC2
 ↓
IAM Role
 ↓
Instance Metadata Service
 ↓
一時Credential

とほぼ同じです。

そのため、以下のような運用は避けた方がよいです。

service-account.jsonをVMに配置
service-account.jsonをGit管理
Docker ImageにJSONをCOPY

Compute Engineでのベストプラクティス

Compute EngineでCloud Storageへアクセスする場合は、

Compute Engine
 ↓
専用Service Account
 ↓
必要最小限のIAM Role
 ↓
Cloud Storage

とします。

例えば画像Bucketを読むだけなら、

Service Account
web-api-prod

↓

roles/storage.objectViewer

↓

gs://images-prod

のようにします。

Project全体に広い権限を付けるよりも、可能であればBucket単位で権限を付与します。


Cloud Storageでよく使うRole

Cloud Storageでよく利用するRoleは次の通りです。

用途 Role
オブジェクトを読む roles/storage.objectViewer
オブジェクトを追加する roles/storage.objectCreator
読み書き・削除 roles/storage.objectAdmin
Bucket設定まで管理 roles/storage.admin

例えば、

画像アップロードだけ

なら、

roles/storage.objectCreator

で十分な場合があります。

必要以上に、

roles/storage.admin

を付けないことが重要です。


ローカル開発ではどうするか

ローカル開発では、いくつか方法があります。

最も扱いやすいのはApplication Default Credentials、通称ADCです。

gcloud auth application-default login

を実行すると、Googleアカウントで認証できます。

その後、Pythonなどでは、

from google.cloud import storage

client = storage.Client()

だけで認証できます。

認証情報をコード側で明示的に指定する必要はありません。


本番と同じService Account権限で開発したい場合

ローカル環境でも、本番のService Accountと同じ権限でテストしたいことがあります。

その場合はService Account Impersonationが便利です。

gcloud auth application-default login \
  --impersonate-service-account=web-api-dev@my-project.iam.gserviceaccount.com

イメージとしては、

開発者
 ↓
Google Account
 ↓
Service AccountをImpersonate
 ↓
Cloud Storage

です。

AWSでいう、

SSO User
 ↓
sts:AssumeRole
 ↓
Application Role

に近いです。


JSONキーをローカルで使う場合

どうしてもJSONキーを使う場合は、環境変数で指定します。

export GOOGLE_APPLICATION_CREDENTIALS="$HOME/.config/gcp/web-api-dev.json"

するとGoogle Cloud SDKが自動的に読み込みます。

Python側は、

from google.cloud import storage

client = storage.Client()

だけで動きます。

つまり、

アプリ
 ↓
Application Default Credentials
 ↓
GOOGLE_APPLICATION_CREDENTIALS
 ↓
Service Account JSON

という流れです。


JSONキーを置いてはいけない場所

特に避けたいのが、プロジェクトディレクトリへの配置です。

悪い例:

my-project/
├── app/
├── public/
├── .env
└── service-account.json

より安全なのは、

~/.config/gcp/
└── web-api-dev.json

のように、ソースコードと完全に分離することです。

また、

GitHub
Docker Image
publicディレクトリ
共有フォルダ

などにも配置しないようにします。


開発環境と本番環境は分ける

Service Accountは、環境ごとに分ける設計が安全です。

例えば、

web-api-dev
 ↓
dev-bucket

web-api-prod
 ↓
prod-bucket

のようにします。

ローカル開発用Service Accountが侵害されても、本番環境へアクセスできないようにするためです。


1つのService Accountを使い回さない

よくない設計として、

common-service-account
 ├─ Storage Admin
 ├─ Compute Admin
 ├─ Cloud SQL Admin
 ├─ Secret Manager Admin
 └─ その他多数

のようなものがあります。

これは権限が大きくなりすぎるため危険です。

基本的には、

1 Service Account
=
1アプリケーション
または
1責務

くらいの粒度で分ける方が安全です。

例えば、

web-api-prod
image-uploader-prod
batch-worker-prod
backup-runner-prod

のように用途を分けます。


おすすめ構成

WebアプリケーションからCloud Storageへアクセスするケースでは、以下のような構成が分かりやすいです。

GCP Project
│
├─ Service Account
│   └─ web-api-prod
│
├─ Cloud Storage
│   └─ images-prod
│        └─ Storage Object Viewer
│             ↑
│             └─ web-api-prod
│
└─ Compute Engine / Cloud Run
     └─ web-api-prodをアタッチ

アプリケーション側ではADCを使います。

from google.cloud import storage

client = storage.Client()

これだけです。

開発環境では、

ADC
または
Service Account Impersonation

を利用します。

本番では、

Compute Engine / Cloud Run
 ↓
Service Account直接アタッチ

とするのが綺麗です。


AWS経験者向けまとめ

AWSとGCPを対応させると、次のように理解できます。

AWS
EC2
 ↓
IAM Role
 ↓
IAM Policy
 ↓
S3

GCP
Compute Engine
 ↓
Service Account
 ↓
IAM Role
 ↓
Cloud Storage

最重要ポイントは、

AWS IAM Role
≈
GCP Service Account + IAM Role

と考えることです。

より正確には、

GCP Service Account
= Identity

GCP IAM Role
= Permissions

です。

そして運用上は、

GCP上のアプリ
→ Service Accountを直接アタッチ

ローカル開発
→ ADC / Impersonation

外部クラウド
→ Workload Identity Federation

JSONキー
→ 可能な限り避ける

という方針にすると、安全かつ管理しやすい構成になります。

まとめ

Service Accountは、GCPにおけるシステム用Identityです。

単なる「APIキー」ではなく、

このプログラムは誰として動くのか

を表現するための重要な仕組みです。

特に覚えておきたいのは次の点です。

  • Service Accountはプログラム用Identity
  • GCPのIAM Roleは権限セット
  • VMやCloud RunにはService Accountを直接アタッチする
  • 必要最小限のRoleだけを付与する
  • Project全体ではなく、可能ならBucketなどリソース単位で権限を付ける
  • JSONキーは長期Credentialなのでできるだけ避ける
  • ローカルではADCやImpersonationを使う
  • 開発環境と本番環境でService Accountを分ける
  • 1つのService Accountに権限を集約しすぎない

AWSで、

EC2にAccess Keyを置かずIAM Roleを使う

のと同じ考え方で、

GCPでもJSON秘密鍵を置かずService Accountをワークロードに付与する

と理解すると、Service Accountの設計がかなり分かりやすくなります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?