複数のサービス アカウントに有効期間の短い認証情報を作成する

このページでは、サービス アカウントの委任チェーンに基づいて、サービス アカウントに有効期間の短い認証情報を作成する方法について説明します。この方法は、タスクの実行に必要な権限を持つトークンを取得するために、一連のトークン生成呼び出しを発行する必要がある場合に使用できます。

有効期間の短い認証情報を取得したら、それを使用してサービス アカウントの権限を借用できます。

1 回のトークン生成呼び出しで必要な権限を含むトークンを生成できる場合は、そのサービス アカウントに有効期間の短い認証情報を直接作成する必要があります。

有効期間の短い認証情報の作成について

作成するトークンの種類に応じて、有効期間の短い認証情報を使用して Google API、サードパーティ製 API、または ID トークンを必要とするアプリケーションの呼び出しを認証できます。有効期間の短い認証情報は存続期間が限定されています(数時間程度)。また、自動的に更新されることはありません。有効期間の短いサービス アカウント認証情報は、信頼できるサービス アカウントに対してリソースへのアクセスを制限する必要がある場合に便利です。また、サービス アカウント キーなど、長期間有効な認証情報よりもリスクが低くなります。

サービス アカウントには、次の種類の有効期間の短い認証情報を作成できます。

  • OAuth 2.0 アクセス トークン

    ほとんどの Google API で、認証にアクセス トークンを利用できます。サービス アカウントのアクセス トークンを生成すると、そのアクセス トークンには更新トークンが含まれません。つまり、トークンの有効期限が切れると、トークンの作成プロセスを繰り返して新しいトークンを生成する必要があります。

    詳細については、アクセス トークンをご覧ください。

  • OpenID Connect(OIDC)ID トークン

    ID トークンは、OpenID Connect(OIDC)仕様に準拠しています。ID トークンは一部のサービスとアプリケーションで使用できます。

    詳細については、ID トークンCloud Run または Cloud Run functions でホストされているアプリケーションの認証をご覧ください。

  • 自己署名 JSON ウェブトークン(JWT)

    自己署名 JWT を使用すると、承認サーバーからアクセス トークンを取得しなくても、一部の Google API に対する認証を行うことができます。API Gateway を使用してデプロイされた API では、これらが必要です。

  • 自己署名バイナリ blob

    自己署名 blob は、通常は認証目的で任意のバイナリデータを安全に送信する必要がある場合に便利です。

委任リクエスト フロー

委任リクエスト フローを使用すると、複数の直接リクエストを順番に行う代わりに、1 つのリクエストを使用して直接リクエストを連結できます。このフローでは、サービス アカウント認証情報のリクエストが委任チェーン内の 1 つ以上のサービス アカウントに委任されてから、最終的なサービス アカウントの認証情報が生成されます。生成された認証情報は最終的なサービス アカウントのみを表します。委任チェーンの中間サービス アカウントを表すものではありません。

委任チェーン内の各サービス アカウントには、リクエストを渡すことができるように、チェーン内の次のサービス アカウントに必要な権限を付与されている必要があります。

1 つのサービス アカウントに必要な権限がすべて付与されている場合は、サービス アカウントから有効期間の短い認証情報を作成するで説明されている簡単なフローを使用する必要があります。

始める前に

必要な権限を提供する

委任リクエストには、呼び出し元、委任チェーン内の 1 つ以上のサービス アカウント、認証情報が作成されたサービス アカウント、という 3 つ以上の ID が含まれます。このフローで、次の ID があるとします。

  • サービス アカウント 1(SA_1)。有効期間が短い認証情報をリクエストする呼び出し元。
  • サービス アカウント 2(SA_2): 最初のリクエストを SA_3 に委任する仲介サービス アカウント。このアカウントはリクエストのみを渡します。SA_1 または SA_3 に追加のアクセス権は付与しません。
  • サービス アカウント 3(SA_3): 認証情報が作成される権限が制限されたアカウント。

委任を許可するには、各アカウントでチェーン内の前のアカウントにサービス アカウント トークン作成者のロール(roles/iam.serviceAccountTokenCreator)を付与する必要があります。

この例では、SA_1SA_2 のサービス アカウント トークン作成者のロール(roles/iam.serviceAccountTokenCreator)を付与する必要があります。これは、リソースとして扱われる SA_2 サービス アカウントの例です。SA_2 にロールを付与する場合は、他のリソースを更新する場合と同様に許可ポリシーを更新します。

このフローの例では、仲介サービス アカウントは 1 つだけです。複数のサービス アカウントを介してアクセスを委任するには、チェーン内のその他のサービス アカウントにもこのロールを割り当てる必要があります。

次に、SA_2 には SA_3 のサービス アカウント トークン作成者のロール(roles/iam.serviceAccountTokenCreator)も付与する必要があります。これにより、SA_2SA_3 の有効期間が短い認証情報を作成できます。

次の手順では、REST API を使用してロールを付与します。Google Cloud コンソールまたは gcloud CLI も使用できます。

API

まず、SA_2(仲介サービス アカウント)の許可ポリシーを取得します。

serviceAccounts.getIamPolicy メソッドで、サービス アカウントの許可ポリシーを取得します。

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

  • PROJECT_ID: Google Cloud プロジェクト ID。プロジェクト ID は英数字からなる文字列です(例: my-project)。
  • SA_2: サービス アカウント 2 の名前。
  • POLICY_VERSION: 返されるポリシー バージョン。リクエストでは、最新のポリシー バージョン(ポリシー バージョン 3)を指定する必要があります。詳細については、ポリシーの取得時にポリシー バージョンを指定するをご覧ください。

HTTP メソッドと URL:

POST https://iam.googleapis.com/v1/projects/PROJECT_ID/serviceAccounts/SA_2@PROJECT_ID.iam.gserviceaccount.com:getIamPolicy

リクエストの本文(JSON):

{
  "options": {
    "requestedPolicyVersion": POLICY_VERSION
  }
}

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

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

{
  "version": 1,
  "etag": "BwWKmjvelug=",
  "bindings": [
    {
      "role": "roles/serviceAccountAdmin",
      "members": [
        "user:my-user@example.com"
      ]
    }
  ]
}

サービス アカウントにロールを付与していない場合、レスポンスには etag 値のみが含まれます。この etag 値を次のステップに含めます。

次に、許可ポリシーを変更して SA_1 にサービス アカウント トークン作成者のロールroles/iam.serviceAccountTokenCreator)を付与します。

たとえば、前の手順のサンプル レスポンスを変更するには、次のコードを追加します。

{
  "version": 1,
  "etag": "BwWKmjvelug=",
  "bindings": [
    {
      "role": "roles/serviceAccountAdmin",
      "members": [
        "user:my-user@example.com"
      ]
    },
    {
      "role": "roles/iam.serviceAccountTokenCreator",
      "members": [
        "serviceAccount:SA_1@PROJECT_ID.iam.gserviceaccount.com"
      ]
    }
  ]
}

次に、SA_2 に対する更新された許可ポリシーを書き込みます。

serviceAccounts.setIamPolicy メソッドは、サービス アカウントに更新後の許可ポリシーを設定します。

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

  • PROJECT_ID: Google Cloud プロジェクト ID。プロジェクト ID は英数字からなる文字列です(例: my-project)。
  • SA_2: サービス アカウント 2 の名前。
  • POLICY: 設定するポリシーの JSON 表現。ポリシーの形式については、ポリシー リファレンスをご覧ください。

    たとえば、前の手順で示した許可ポリシーを設定するには、POLICY を次のコードに置き換えます。

    {
      "version": 1,
      "etag": "BwWKmjvelug=",
      "bindings": [
        {
          "role": "roles/serviceAccountAdmin",
          "members": [
            "user:admin@example.com"
          ]
        },
        {
          "role": "roles/iam.serviceAccountTokenCreator",
          "members": [
            "serviceAccount:SA_1@PROJECT_ID.iam.gserviceaccount.com"
          ]
        }
      ]
    }

HTTP メソッドと URL:

POST https://iam.googleapis.com/v1/projects/PROJECT_ID/serviceAccounts/SA_2@PROJECT_ID.iam.gserviceaccount.com:setIamPolicy

リクエストの本文(JSON):

{
  "policy": POLICY
}

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

レスポンスには、更新された許可ポリシーが含まれます。

次に、SA_3(認証情報が作成されるサービス アカウント)の許可ポリシーを取得します。

serviceAccounts.getIamPolicy メソッドで、サービス アカウントの許可ポリシーを取得します。

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

  • PROJECT_ID: Google Cloud プロジェクト ID。プロジェクト ID は英数字からなる文字列です(例: my-project)。
  • SA_3: サービス アカウント 3 の名前。
  • POLICY_VERSION: 返されるポリシー バージョン。リクエストでは、最新のポリシー バージョン(ポリシー バージョン 3)を指定する必要があります。詳細については、ポリシーの取得時にポリシー バージョンを指定するをご覧ください。

HTTP メソッドと URL:

POST https://iam.googleapis.com/v1/projects/PROJECT_ID/serviceAccounts/SA_3@PROJECT_ID.iam.gserviceaccount.com:getIamPolicy

リクエストの本文(JSON):

{
  "options": {
    "requestedPolicyVersion": POLICY_VERSION
  }
}

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

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

{
  "version": 1,
  "etag": "BwWKmjvelug=",
  "bindings": [
    {
      "role": "roles/serviceAccountAdmin",
      "members": [
        "user:my-user@example.com"
      ]
    }
  ]
}

サービス アカウントにロールを割り当てていない場合、レスポンスには etag 値のみが含まれます。この etag 値を次のステップに含めます。

次に、許可ポリシーを変更して SA_2 にサービス アカウント トークン作成者のロールroles/iam.serviceAccountTokenCreator)を付与します。

たとえば、前の手順のサンプル レスポンスを変更するには、次のコードを追加します。

{
  "version": 1,
  "etag": "BwWKmjvelug=",
  "bindings": [
    {
      "role": "roles/serviceAccountAdmin",
      "members": [
        "user:my-user@example.com"
      ]
    },
    {
      "role": "roles/iam.serviceAccountTokenCreator",
      "members": [
        "serviceAccount:SA_2@PROJECT_ID.iam.gserviceaccount.com"
      ]
    }
  ]
}

最後に、更新された許可ポリシーを作成します。

serviceAccounts.setIamPolicy メソッドは、サービス アカウントに更新後の許可ポリシーを設定します。

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

  • PROJECT_ID: Google Cloud プロジェクト ID。プロジェクト ID は英数字からなる文字列です(例: my-project)。
  • SA_3: サービス アカウント 3 の名前。
  • POLICY: 設定するポリシーの JSON 表現。ポリシーの形式については、ポリシー リファレンスをご覧ください。

    たとえば、前の手順で示した許可ポリシーを設定するには、POLICY を次のコードに置き換えます。

    {
      "version": 1,
      "etag": "BwWKmjvelug=",
      "bindings": [
        {
          "role": "roles/serviceAccountAdmin",
          "members": [
            "user:my-user@example.com"
          ]
        },
        {
          "role": "roles/iam.serviceAccountTokenCreator",
          "members": [
            "serviceAccount:SA_2@PROJECT_ID.iam.gserviceaccount.com"
          ]
        }
      ]
    }

HTTP メソッドと URL:

POST https://iam.googleapis.com/v1/projects/PROJECT_ID/serviceAccounts/SA_3@PROJECT_ID.iam.gserviceaccount.com:setIamPolicy

リクエストの本文(JSON):

{
  "policy": POLICY
}

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

レスポンスには、更新された許可ポリシーが含まれます。

有効期間の短い認証情報をリクエストする

各 ID に適切なロールを付与した後、目的のサービス アカウントの有効期間が短い認証情報をリクエストできます。サポートされている認証情報タイプは、次のとおりです。

これらのリクエストの委任チェーンを指定する方法については、このページの委任チェーンの指定をご覧ください。

OAuth 2.0 アクセス トークンを生成する

デフォルトでは、OAuth 2.0 アクセス トークンは最大 1 時間(3,600 秒)有効です。ただし、これらのトークンの最大有効期間は 12 時間(43,200 秒)まで延長できます。これを行うには、トークンの有効時間を延長する必要があるサービス アカウントを指定して、constraints/iam.allowServiceAccountCredentialLifetimeExtension リスト型制約が含まれる組織のポリシーに、指定したサービス アカウントを追加します。そうすると、それらのサービス アカウント用にトークンを作成するときに最大 43,200 秒の有効期間を指定できます。

サービス アカウントの OAuth 2.0 アクセス トークンを生成するには、次の手順に従います。

API

Service Account Credentials API の serviceAccounts.generateAccessToken メソッドによって、サービス アカウントの OAuth 2.0 アクセス トークンが生成されます。

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

  • SA_NAME: トークンを作成するサービス アカウントの名前。
  • PROJECT_ID: Google Cloud プロジェクト ID。プロジェクト ID は英数字からなる文字列です(例: my-project)。
  • DELEGATES: 委任されたリクエスト フローを使用している場合は、このページの委任チェーンの指定をご覧ください。委任がない直接リクエスト フローを使用している場合は、リクエスト本文の delegates フィールドを省略します。
  • LIFETIME: アクセス トークンが期限切れになるまでの秒数。例: 300s

    デフォルトでは、トークンの最大有効期間は 1 時間(3,600 秒)です。これらのトークンの最大有効期間を 12 時間(43,200 秒)まで延長するには、constraints/iam.allowServiceAccountCredentialLifetimeExtension リスト型制約が含まれる組織のポリシーにサービス アカウントを追加します。

HTTP メソッドと URL:

POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SA_NAME@PROJECT_ID.iam.gserviceaccount.com:generateAccessToken

リクエストの本文(JSON):

{
  "delegates": [
    DELEGATES
  ],
  "scope": [
    "https://www.googleapis.com/auth/cloud-platform"
  ],
  "lifetime": "LIFETIME"
}

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

generateAccessToken リクエストが成功した場合、レスポンスの本文には OAuth 2.0 アクセス トークンと有効期限が含まれます。expireTime に達するまで、サービス アカウントの代わりに accessToken をリクエストの認証に使用できます。

{
  "accessToken": "eyJ0eXAi...NiJ9",
  "expireTime": "2020-04-07T15:01:23.045123456Z"
}

OpenID Connect ID トークンを生成する

OpenID Connect ID トークンは、1 時間(3,600 秒間)有効です。サービス アカウントの ID トークンを生成するには、次の手順に従います。

API

Service Account Credentials API の serviceAccounts.generateIdToken メソッドによって、サービス アカウントの OIDC ID トークンが生成されます。

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

  • PRIV_SA: 有効期間の短いトークンが作成される権限保持サービス アカウントのメールアドレス。
  • AUDIENCE_NAME: トークンのオーディエンス。通常は、トークンのアクセスに使用されるアプリケーションまたはサービスの URL です。

HTTP メソッドと URL:

POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/PRIV_SA:generateIdToken

リクエストの本文(JSON):

{
  "audience": "AUDIENCE_NAME",
  "includeEmail": "true"
}

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

generateId リクエストが成功した場合、レスポンス本文には 1 時間有効な ID トークンが含まれます。サービス アカウントの代わりに token をリクエストの認証に使用できます。

{
  "token": "eyJ0eXAi...NiJ9"
}

自己署名 JSON Web Token(JWT)を作成する

自己署名 JSON ウェブトークン(JWT)は、次のようなさまざまなシナリオにおいて有用です。

  • Google の認証ガイドに従って Google API の呼び出しを認証する。
  • App Engine アプリケーションなど、Google Cloud または Google 以外のサービス間で安全に通信する。このシナリオでは、1 つのアプリケーションが、認証目的で別のアプリケーションによって確認できるトークンに署名できます。
  • ユーザー、アカウント、デバイスに関する任意のクレームを含む JWT に署名することにより、サービス アカウントを ID プロバイダとして扱う。

サービス アカウントの自己署名 JWT を生成するには、次の手順を行います。

API

Service Account Credentials API の serviceAccounts.signJwt メソッドでは、サービス アカウントのシステムで管理する秘密鍵を使用して JWT に署名します。

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

  • SA_NAME: トークンを作成するサービス アカウントの名前。
  • PROJECT_ID: Google Cloud プロジェクト ID。プロジェクト ID は英数字からなる文字列です(例: my-project)。
  • DELEGATES: 委任されたリクエスト フローを使用している場合は、このページの委任チェーンの指定をご覧ください。委任がない直接リクエスト フローを使用している場合は、リクエスト本文の delegates フィールドを省略します。
  • JWT_PAYLOAD: 署名する JWT ペイロード。これは JWT クレームセットを含む JSON オブジェクトです。ご希望のユースケースに必要なクレームを含め、呼び出すサービスの検証要件を満たしてください。Google API を呼び出す場合は、クレーム要件について Google の認証ガイドをご覧ください。

    exp(有効期限)クレームは、今後 12 時間以内にする必要があります。Google API を呼び出す場合は、exp クレームは 1 時間以内に設定する必要があります。

    次の例のペイロードには、Google API を呼び出すクレームが含まれています。ここで、EXP は有効期限を表す整数タイムスタンプです。

    { \"iss\": \"SA_NAME@PROJECT_ID.iam.gserviceaccount.com\", \"sub\": \"SA_NAME@PROJECT_ID.iam.gserviceaccount.com\", \"aud\": \"https://firestore.googleapis.com/\", \"iat\": 1529350000, \"exp\": EXP }

HTTP メソッドと URL:

POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SA_NAME@PROJECT_ID.iam.gserviceaccount.com:signJwt

リクエストの本文(JSON):

{
  "delegates": [
    DELEGATES
  ],
  "payload": "JWT_PAYLOAD"
}

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

signJwt リクエストが成功した場合、レスポンスの本文には、署名付きの JWT と JWT の署名に使用された署名鍵 ID が含まれています。サービス アカウントの代わりに、signedJwt 値を署名なしトークンとして使用してリクエストを直接認証できます。トークンは、リクエストで指定された有効期限まで有効です。

{
  "keyId": "42ba1e...fc0a",
  "signedJwt": "eyJ0eXAi...NiJ9"
}

自己署名 blob を作成する

自己署名 blob は、通常は認証目的で任意のバイナリデータを安全に送信する必要がある場合に便利です。たとえば、カスタム プロトコル / トークンタイプ(JWT ではなく)を使用する場合は、ダウンストリーム サービスで使用するためにそのデータを署名付き blob に含めることができます。

サービス アカウントの自己署名 blob を生成するには、次の手順に沿って操作します。

API

Service Account Credentials API の serviceAccounts.signBlob メソッドでは、サービス アカウントのシステムで管理する秘密鍵を使用して blob に署名します。

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

  • SA_NAME: トークンを作成するサービス アカウントの名前。
  • PROJECT_ID: Google Cloud プロジェクト ID。プロジェクト ID は英数字からなる文字列です(例: my-project)。
  • DELEGATES: 委任されたリクエスト フローを使用している場合は、このページの委任チェーンの指定をご覧ください。委任がない直接リクエスト フローを使用している場合は、リクエスト本文の delegates フィールドを省略します。
  • BLOB_PAYLOAD: base64 でエンコードされたバイトの文字列。例: VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cu

HTTP メソッドと URL:

POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SA_NAME@PROJECT_ID.iam.gserviceaccount.com:signBlob

リクエストの本文(JSON):

{
  "delegates": [
    DELEGATES
  ],
  "payload": "BLOB_PAYLOAD"
}

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

signBlob リクエストが成功した場合、レスポンスの本文には、署名 blob と blob の署名に使用された署名鍵 ID が含まれています。サービス アカウントの代わりに、signedBlob 値を署名なしトークンとして使用してリクエストを直接認証できます。トークンは、サービス アカウントのシステムで管理する秘密鍵が期限切れになるまで有効です。この鍵の ID はレスポンスの keyId フィールドの値です。

{
  "keyId": "42ba1e...fc0a",
  "signedBlob": "eyJ0eXAi...NiJ9"
}

委任チェーンを指定する

委任されたリクエスト フローを使用して有効期間の短いサービス アカウント認証情報を作成する場合、各 API のリクエストの本文で次の形式のサービス アカウントの委任チェーンを正しい順序で指定する必要があります。

projects/-/serviceAccounts/SA_ID

SA_ID は、サービス アカウントの一意の数値 ID またはサービス アカウントのメールアドレスで置き換えます。

たとえば、SA_1(発信者)から SA_2(委任)、SA_3(委任)、SA_4 の順につながる委任チェーンの場合、delegates[] フィールドには SA_2SA_3 が次の順序で含まれます。

{
  "delegates": [
    "projects/-/serviceAccounts/SA_2@PROJECT_ID.iam.gserviceaccount.com",
    "projects/-/serviceAccounts/SA_3@PROJECT_ID.iam.gserviceaccount.com"
  ]
}

呼び出し元と認証情報が作成されるサービス アカウントは、委任チェーンに含まれません。