IAM 認証でユーザーを管理する

このページでは、IAM データベース認証を使用するユーザーまたはサービス アカウントをデータベースに追加する方法と、それらのユーザー アカウントとサービス アカウントを管理する方法について説明します。IAM の統合の詳細については、IAM データベース認証の概要をご覧ください。

始める前に

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Install the Google Cloud CLI.
  5. To initialize the gcloud CLI, run the following command:

    gcloud init
  6. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  7. Make sure that billing is enabled for your Google Cloud project.

  8. Install the Google Cloud CLI.
  9. To initialize the gcloud CLI, run the following command:

    gcloud init
  10. Enable the Cloud Key Management Service API.

    Enable the API

  11. ユーザー アカウントに Cloud SQL 管理者のロールがあることを確認します。

    IAM ページに移動

  12. Cloud SQL インスタンスで IAM データベース認証を有効にします
  13. ユーザーがアクセスする必要があるデータベースを含むプロジェクトごとに、IAM アクセス権を必要とするユーザーに権限を付与してください。詳しくは、リソースに対するアクセス権の付与、変更、取り消しの手順をご覧ください。
  14. プロジェクト内のデータベースにアクセスする必要があるサービスごとに、サービス アカウントが追加されていることを確認します。

IAM ユーザーまたはサービス アカウントをデータベースに追加する

データベース インスタンスへのアクセスを許可する IAM ユーザーごとに、新しいデータベース ユーザーを作成する必要があります。データベース ユーザー名は、IAM ユーザーのメールアドレス(test-user@gmail.com など)にする必要があります。

REST コマンドを使用する場合、ユーザー名には特殊文字(@.)が含まれるため、引用符を使用する必要があります。

サービス アカウントの形式は service-account-name@project-id.iam.gserviceaccount.com です。

IAM ユーザーまたはサービス アカウントを追加するには、新しいデータベース ユーザーを追加し、認証方法として IAM を選択します。

コンソール

  1. Google Cloud コンソールで Cloud SQL の [インスタンス] ページに移動します。

    Cloud SQL の [インスタンス] に移動

  2. インスタンスの [概要] ページを開くには、インスタンス名をクリックします。
  3. SQL ナビゲーション メニューから [ユーザー] を選択します。
  4. [ユーザー アカウントを追加] をクリックします。[ユーザー アカウントをインスタンス instance_name に追加] タブが開きます。
  5. [Cloud IAM] ラジオボタンをクリックします。
  6. [プリンシパル] フィールドに追加するユーザーまたはサービス アカウントのメールアドレスを追加します。
  7. [追加] をクリックします。ユーザーがユーザーリストに表示されるようになりました。
  8. ユーザーが Cloud SQL インスタンス ユーザーのロールに割り当てられていない場合、ユーザー名の左側に 三角形 アイコンが表示されます。

    ユーザーにログイン権限を付与するには、アイコンをクリックしてから [IAM ロールを追加] を選択します。アイコンが消えます。これで、ユーザーがロールのメンバーになりました。

gcloud

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

メールアドレス(test-user@gmail.com など)を使用してユーザーを識別します。

次のように置き換えます。

  • USERNAME: ユーザーのメールアドレス。
  • INSTANCE_NAME: ユーザーにアクセスを許可するインスタンスの名前。
gcloud sql users create USERNAME \
--instance=INSTANCE_NAME \
--type=cloud_iam_user

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

次のように置き換えます。

  • SERVICE_ACCT: サービス アカウントのメールアドレス。
  • INSTANCE_NAME: サービス アカウントによるアクセスを許可するインスタンスの名前。
gcloud sql users create SERVICE_ACCT \
--instance=INSTANCE_NAME \
--type=cloud_iam_service_account

REST v1

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

リクエストのデータを使用する前に、次のように置き換えます。

  • project-id: 実際のプロジェクト ID
  • instance-id: ユーザーを追加するインスタンスのインスタンス ID
  • username: ユーザーのメールアドレス
  • operation-id: オペレーションの ID

HTTP メソッドと URL:

POST https://sqladmin.googleapis.com/v1/projects/project-id/instances/instance-id/users

JSON 本文のリクエスト:

{
  "name": "username",
  "type": "CLOUD_IAM_USER"
  }

リクエストを送信するには、次のいずれかのオプションを展開します。

次のような JSON レスポンスが返されます。

{
  "kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/v1/projects/project-id/instances/instance-id",
  "status": "DONE",
  "user": "user@example.com",
  "insertTime": "2020-02-07T22:44:16.656Z",
  "startTime": "2020-02-07T22:44:16.686Z",
  "endTime": "2020-02-07T22:44:20.437Z",
  "operationType": "CREATE_USER",
  "name": "operation-id",
  "targetId": "instance-id",
  "selfLink": "https://sqladmin.googleapis.com/v1/projects/project-id/operations/operation-id",
  "targetProject": "project-id"
}

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

リクエストのデータを使用する前に、次のように置き換えます。

  • service-acct: サービス アカウントのメールアドレス
  • project-id: 実際のプロジェクト ID
  • instance-id: サービス アカウントを追加するインスタンスのインスタンス ID
  • operation-id: オペレーションの ID

HTTP メソッドと URL:

POST https://sqladmin.googleapis.com/v1/projects/project-id/instances/instance-id/users

JSON 本文のリクエスト:

{
    "name": "service-acct",
    "type": "CLOUD_IAM_SERVICE_ACCOUNT"
}

リクエストを送信するには、次のいずれかのオプションを展開します。

次のような JSON レスポンスが返されます。

{
"kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/v1/projects/project-id/instances/instance-id",
  "status": "DONE",
  "user": "user@example.com",
  "insertTime": "2020-11-20T04:08:00.211Z",
  "startTime": "2020-11-20T04:08:00.240Z",
  "endTime": "2020-11-20T04:08:02.003Z",
  "operationType": "CREATE_USER",
  "name": "operation-id",
  "targetId": "instance-id",
  "selfLink": "https://sqladmin.googleapis.com/v1/projects/project-id/operations/operation-id",
  "targetProject": "project-id"
}

REST v1beta4

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

リクエストのデータを使用する前に、次のように置き換えます。

  • project-id: 実際のプロジェクト ID
  • instance-id: ユーザーを追加するインスタンスのインスタンス ID
  • username: ユーザーのメールアドレス
  • operation-id: オペレーションの ID

HTTP メソッドと URL:

POST https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/instance-id/users

JSON 本文のリクエスト:

{
  "name": "username",
  "type": "CLOUD_IAM_USER"
  }

リクエストを送信するには、次のいずれかのオプションを展開します。

次のような JSON レスポンスが返されます。

{
  "kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/instance-id",
  "status": "DONE",
  "user": "user@example.com",
  "insertTime": "2020-02-07T22:44:16.656Z",
  "startTime": "2020-02-07T22:44:16.686Z",
  "endTime": "2020-02-07T22:44:20.437Z",
  "operationType": "CREATE_USER",
  "name": "operation-id",
  "targetId": "instance-id",
  "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/operations/operation-id",
  "targetProject": "project-id"
}

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

リクエストのデータを使用する前に、次のように置き換えます。

  • service-acct: サービス アカウントのメールアドレス
  • project-id: 実際のプロジェクト ID
  • instance-id: サービス アカウントを追加するインスタンスのインスタンス ID
  • operation-id: オペレーションの ID

HTTP メソッドと URL:

POST https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/instance-id/users

JSON 本文のリクエスト:

{
    "name": "service-acct",
    "type": "CLOUD_IAM_SERVICE_ACCOUNT"
}

リクエストを送信するには、次のいずれかのオプションを展開します。

次のような JSON レスポンスが返されます。

{
"kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/instance-id",
  "status": "DONE",
  "user": "user@example.com",
  "insertTime": "2020-11-20T04:08:00.211Z",
  "startTime": "2020-11-20T04:08:00.240Z",
  "endTime": "2020-11-20T04:08:02.003Z",
  "operationType": "CREATE_USER",
  "name": "operation-id",
  "targetId": "instance-id",
  "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/operations/operation-id",
  "targetProject": "project-id"
}

IAM ユーザーにデータベース権限を付与する

デフォルトでは、IAM ユーザーがデータベース インスタンスに追加されると、その新しいユーザーにはデータベースに対する権限が付与されません。

ユーザーまたはサービス アカウントがデータベースに接続すると、PUBLIC にアクセス権がある任意のデータベース オブジェクトに対してクエリを実行できます。

追加のアクセス権が必要な場合は、GRANT ステートメントを使用してより多くの権限を付与できます。ユーザーとサービス アカウントに付与できる権限の一覧については、GRANT リファレンス ページをご覧ください。コマンドラインから GRANT を実行します。

次のように置き換えます。

  • USERNAME: ユーザーのメールアドレス。メールアドレスには特殊文字(@.)が含まれているため、引用符で囲む必要があります。
  • TABLE_NAME: ユーザーにアクセス権を付与するテーブルの名前。
    grant select on TABLE_NAME to "USERNAME";
    

データベースから IAM ユーザーまたはサービス アカウントを削除する

データベースからユーザーまたはサービス アカウントを削除するには、アカウントをインスタンスから削除します。

コンソール

  1. Google Cloud コンソールで Cloud SQL の [インスタンス] ページに移動します。

    Cloud SQL の [インスタンス] に移動

  2. インスタンスの [概要] ページを開くには、インスタンス名をクリックします。
  3. SQL ナビゲーション メニューから [ユーザー] を選択します。
  4. 削除するユーザーの をクリックします。
  5. [削除] を選択します。これにより、このインスタンスへのアクセス権のみが取り消されます。

gcloud

ユーザーを取り消す

メールアドレス(test-user@gmail.com など)を使用してユーザーを識別します。

次のように置き換えます。

  • USERNAME: @ 以下のドメイン名を含まないメールアドレス。
  • INSTANCE_NAME: ユーザーを削除するインスタンスの名前。
gcloud sql users delete USERNAME \
--instance=INSTANCE_NAME

サービス アカウントを削除する

次のように置き換えます。

  • SERVICE_ACCT: サービス アカウントのメールアドレス。
  • INSTANCE_NAME: ユーザーを削除するインスタンスの名前。
gcloud sql users delete SERVICE_ACCT \
--instance=INSTANCE_NAME

REST v1beta4

以下のリクエストでは、users:delete メソッドを使用して、指定したユーザー アカウントを削除します。

リクエストのデータを使用する前に、次のように置き換えます。

  • project-id: 実際のプロジェクト ID
  • instance-id: 目的のインスタンス ID
  • username: ユーザーまたはサービス アカウントのメールアドレス

HTTP メソッドと URL:

DELETE https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/instance-id/users?host=&name=username

リクエストを送信するには、次のいずれかのオプションを展開します。

次のような JSON レスポンスが返されます。

{
  "kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/instance-id",
  "status": "DONE",
  "user": "user@example.com",
  "insertTime": "2020-02-07T22:38:41.217Z",
  "startTime": "2020-02-07T22:38:41.217Z",
  "endTime": "2020-02-07T22:38:44.801Z",
  "operationType": "DELETE_USER",
  "name": "operation-id",
  "targetId": "instance-id",
  "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/operations/operation-id",
  "targetProject": "project-id"
}

監査ログのログイン情報を表示する

監査ログを有効にして、データベースへの IAM ログインをキャプチャできます。ログインで問題が発生した場合は、監査ログを使用して問題を診断できます。

注: 監査ロギングには追加費用が発生します。詳細については、データロギングの料金をご覧ください。

構成が完了すると、ログ エクスプローラを使用して、成功したログインのデータアクセス監査ログを表示できます。

たとえば、ログに次のような情報が含まれる場合があります。

{
 insertId: "..."
 logName: "projects/.../logs/cloudaudit.googleapis.com%2Fdata_access"
 protoPayload: {
  @type: "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
   principalEmail: "..."
  }
  authorizationInfo: [
   0: {
    granted: true
    permission: "cloudsql.instances.login"
    resource: "instances/..."
    resourceAttributes: {
    }
   }
  ]
  methodName: "cloudsql.instances.login"
  request: {
   @type: "type.googleapis.com/google.cloud.sql.authorization.v1.InstancesLoginRequest"
   clientIpAddress: "..."
   database: "..."
   databaseSessionId: ...
   instance: "projects/.../locations/us-central1/instances/..."
   user: "..."
  }
  requestMetadata: {
   callerIp: "..."
   destinationAttributes: {
   }
   requestAttributes: {
    auth: {
    }
    time: "..."
   }
  }
  resourceName: "instances/..."
  serviceName: "cloudsql.googleapis.com"
  status: {
  }
 }
 receiveTimestamp: "..."
 resource: {
  labels: {
   database_id: "...:..."
   project_id: "..."
   region: "us-central"
  }
  type: "cloudsql_database"
 }
 severity: "INFO"
 timestamp: "..."
}

ログイン失敗のトラブルシューティング

ログインの試行が失敗すると、PostgreSQL はセキュリティ上の理由から、最小限のエラー メッセージを返します。例:

PGPASSWORD=not-a-password psql --host=... --username=... --dbname=...
psql: error: could not connect to server: FATAL:  Cloud SQL IAM user authentication failed for user "..."
FATAL:  pg_hba.conf rejects connection for host "...", user "...", database "...", SSL off

エラーの詳細については、PostgreSQL のエラーログを確認してください。詳細については、ログの表示をご覧ください。

たとえば、前述のエラーについて、次のログエントリで問題解決のアクションについて説明されています。

F ... [152172]: [1-1] db=...,user=... FATAL:  Cloud SQL IAM user authentication failed for user "..."
I ... [152172]: [2-1] db=...,user=... DETAIL:  Request is missing required authentication credential. Expected OAuth 2 access token, log in cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.

表示されたエラー メッセージを確認します。メッセージに「Cloud SQL IAM ユーザー認証」または「Cloud SQL IAM サービス アカウント認証」を使用したことが示されていない場合は、ログインに使用したデータベース ユーザータイプが CLOUD_IAM_USER または CLOUD_IAM_SERVICE_ACCOUNT のいずれかかどうか確認します。確認するには、Google Cloud コンソールまたは gcloud sql users list コマンドを使用します。IAM ユーザーのデータベース ユーザー名が IAM ユーザーのメールアドレスであることを確認します。

IAM データベース認証を使用した場合は、エラー メッセージの詳細を確認します。エラー メッセージはデータベースのエラーログで確認できます。パスワードとして送信したアクセス トークン(OAuth 2.0)が無効であることが示されている場合は、gcloud auth application-default print-access-token gcloud コマンドで詳細を確認できます。

curl -H "Content-Type: application/x-www-form-urlencoded" \
-d "access_token=$(gcloud auth application-default print-access-token)" \
https://www.googleapis.com/oauth2/v1/tokeninfo

トークンが目的の IAM ユーザーまたはサービス アカウントのものであり、有効期限が切れていないことを確認します。

詳細情報に権限不足が示されている場合は、インスタンスのプロジェクトの IAM ポリシーで定義した Cloud SQL Instance User 事前定義ロールまたはカスタムロールを使用して、IAM ユーザーまたはサービス アカウントに cloudsql.instances.login 権限が付与されていることを確認します。サポートが必要な場合は、IAM ポリシーのトラブルシューティングをご覧ください。

IAM データベース認証が利用できないためにログインに失敗した場合は、デフォルトの PostgreSQL のユーザー名とパスワードを使用してログインできます。このログイン方法でもデータベース全体にアクセスできます。接続がセキュリティ保護されていることを確認します。

次のステップ