有効期間が短いサービス アカウント認証情報の作成

このページでは、サービス アカウント ID を使用するための有効期間が短いサービス アカウント認証情報を作成する方法を説明します。

サービス アカウントは、有効期間が短い認証情報を使用して、Google Cloud Platform API やその他の Google 以外の API への呼び出しを認証できます。有効期間が短い認証情報の存続期間は限られており、その期間は数時間未満です。有効期間が短いサービス アカウント認証情報は、信頼できるサービス アカウントのリソースへのアクセスを制限する必要がある場合に便利です。また、サービス アカウント キーなどの有効期間が長い認証情報を使用する場合と比較してリスクを軽減できます。

サポートされている認証情報タイプには、OAuth 2.0 アクセス トークン、OpenID Connect ID トークン、自己署名 JSON ウェブトークン(JWT)、自己署名バイナリ オブジェクト(BLOB)などがあります。OAuth 2.0 アクセス トークンOpenID Connect(OIDC)ID トークンが、特によく使用されるタイプの認証情報です。いくつかのサンプル事例としては、次のようなものがあります。

  • OAuth 2.0 アクセス トークン: An OAuth 2.0 アクセス トークンは、Google Cloud Platform API に対してサービス アカウントの ID を認証する場合に便利です。次の使用例を考えてみます。プロジェクトの昇格した権限を取得するために、サービス管理者はサービス アカウントを使用し、そのサービス アカウントに属する OAuth 2.0 アクセス トークンを作成することで GCP API を呼び出します。トークンの有効期間は短いため、昇格した権限は一時的なものです。これは特に、本番環境で緊急事態が発生し、サービス管理者がデバッグのために有効期間が短い昇格した承認を必要とする場合に便利です。

  • OIDC ID トークン: OIDC ID トークンは、OpenID Connect を認可するサービスに対するサービス アカウント ID の認証に便利です。次の使用例を考えてみます。サービス アカウントに属する OIDC ID トークンを作成すると、GCP で実行されているサービスは、サードパーティ クラウド プロバイダにデプロイされた別のサービス(データ パイプライン ジョブなど)から認証を受けることができます。ターゲット サービスが OIDC で構成されている場合、認証は成功します。

始める前に

権限を制限したサービス アカウントの作成

開始するには、新しいサービス アカウントを作成します。

必要な権限の付与

呼び出し元がサービス アカウントの有効期間が短い認証情報を作成するには、2 つの異なるフローがあります。各フローには適切な権限が必要です。

  • 直接リクエスト: 呼び出し元は Google アカウントまたはサービス アカウントのいずれかとして認証され、有効期間が短い認証情報の作成を直接リクエストします。このフローには、呼び出し元と認証情報が作成されるサービス アカウントの 2 つの ID が含まれます。
  • 委任リクエスト: 呼び出し元は直接リクエスト フローの場合と同じように Google アカウントまたはサービス アカウントのいずれかとして認証されますが、リクエストは委任チェーン内の 1 つ以上のサービス アカウントに委任されます。このフローでは、複数のサービス アカウントが、元の呼び出し元と認証情報が作成されるサービス アカウントの間の仲介役として機能します。委任チェーン内の各サービス アカウントには、リクエストを渡すための権限が必要です。

    このフローが役立つのは、プロジェクト内に権限が制限された複数のサービス アカウントが何層にも重なっていて、各サービス アカウントが、特定のリソースに対して特定のファンクションや限定されたファンクションを行うように構成されている場合です。たとえば、あるサービス アカウントには Cloud Storage のリソースに対する権限のみが付与され、別のサービス アカウントには Compute Engine のリソースに対する権限のみが付与されている、といった状況です。サービス アカウント同士でリクエストの委任が正しく行われるようにするには、各サービス アカウントが委任チェーンの一覧に含まれていなければなりません。

直接リクエストの権限

前述のように、直接リクエストには、呼び出し元と認証情報が作成されるサービス アカウントの 2 つの ID のみが含まれます。このフローでは、次の ID があるとします。

  • サービス アカウント 1(SA-1): 有効期間が短い認証情報のリクエストを発行する呼び出し元。
  • サービス アカウント 2(SA-2): 認証情報が作成される権限を制限したアカウント。

SA-1 に有効期間が短い認証情報を作成するための権限を付与するには、SA-2 のサービス アカウント トークン作成者の役割(roles/iam.serviceAccountTokenCreator)を付与します。これは、ID ではなくリソースのように扱われるサービス アカウントの例です。SA-1 に、SA-2 の認証情報を発行するための権限が付与されている必要があります。ID またはリソースとしてサービス アカウントを扱う方法の詳細については、サービス アカウント権限をご覧ください。

次の手順では REST API で必要な権限を付与しますが、GCP Console や gcloud コマンドライン ツールを使用することもできます。

API

まず、SA-2 の Cloud IAM ポリシーを取得します。詳細については、serviceAccounts.getIamPolicy() リファレンスをご覧ください。

以下のコード スニペットで SA-2@PROJECT- ID.iam.gserviceaccount.comSA-2 を表し、SA-1@PROJECT-ID.iam.gserviceaccount.comSA-1(有効期間が短い認証情報をリクエストする呼び出し元)を表しています。

この API への各リクエストでは、ハイフン(.../projects/-/serviceAccounts...)が URL の最初の部分のプロジェクト ID に対するワイルドカードとして使用されます。

リクエスト:

POST https://iam.googleapis.com/v1/projects/-/serviceAccounts/SA-2@PROJECT-ID.iam.gserviceaccount.com:getIamPolicy

レスポンス:

{
  "etag": "BwUqLaVeua8=",
  "bindings": [
    {
      "role": "roles/iam.serviceAccountUser",
      "members": [
          "user:alice@gmail.com"
      ]
    }
  ]
}

役割をサービス アカウントにまだ割り当てていない場合、レスポンスには 1 つの etag 値だけが含まれます。

{
  "etag": "ACAB"
}

上記の手順で取得した etag 値は、それが BwUqLaVeua8=ACAB かを問わず、次の手順に含める必要があります。次に、SA-1 に、サービス アカウント トークン作成者の役割(roles/iam.serviceAccountTokenCreator)を付与するためのポリシーを作成します。

{
    "policy":
    {
        "etag": "BwUqLaVeua8=",
        "bindings": [
        {
            "role": "roles/iam.serviceAccountUser",
            "members": [
                "user:alice@gmail.com"
            ]
        },
        {
            "role": "roles/iam.serviceAccountTokenCreator",
            "members": [
                "serviceAccount:SA-1@PROJECT-ID.iam.gserviceaccount.com"
            ]
        },
        ]
    },
}

更新されるポリシーをリクエスト本文として使用し、serviceAccounts.setIamPolicy() リクエストを行ってポリシーを更新します。

POST https://iam.googleapis.com/v1/projects/-/serviceAccounts/SA-2@PROJECT-ID.iam.gserviceaccount.com:setIamPolicy

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

{
    "etag": "BwUqMqbViM8=",
    "bindings": [
      {
        "role": "roles/iam.serviceAccountUser",
        "members": [
            "user:alice@gmail.com"
        ]
      },
      {
        "role": "roles/iam.serviceAccountTokenCreator",
        "members": [
            "serviceAccount:SA-1@PROJECT-ID.iam.gserviceaccount.com"
        ]
      }
    ]
}

委任リクエストの権限

前述のように、委任リクエストには、呼び出し元、委任チェーン内の 1 つ以上のサービス アカウント、最後にサービス アカウントという 3 つ以上の ID が必要です。このフローでは、次の ID があるとします。

  • サービス アカウント 1(SA-1): 有効期間が短い認証情報のリクエストを発行する呼び出し元。
  • サービス アカウント 2(SA-2): 最初のリクエストを SA-3 に委任する仲介サービス アカウント。
  • サービス アカウント 3(SA-3): 認証情報が作成される権限を制限したアカウント。

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

この特定の例では、SA-1 に、SA-2 のサービス アカウント トークン作成者の役割(roles/iam.serviceAccountTokenCreator)を付与する必要があります。これは、ID ではなくリソースのように扱われるサービス アカウントの例です。SA-1 には、SA-2 へのアクセスを委任するための権限が付与されている必要があります。ID またはリソースとしてサービス アカウントを扱う方法の詳細については、サービス アカウント権限をご覧ください。

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

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

次の手順では REST API で必要な権限を付与しますが、GCP Console や gcloud コマンドライン ツールを使用することもできます。

API

まず、SA-2(仲介サービス アカウント)の Cloud IAM ポリシーを取得します。詳細については、serviceAccounts.getIamPolicy() リファレンスをご覧ください。

以下のコード スニペットで SA-2@PROJECT- ID.iam.gserviceaccount.com は SA-2 を表し、SA-1@PROJECT-ID.iam.gserviceaccount.com は SA-1(有効期間が短い認証情報をリクエストする呼び出し元)を表しています。

この API への各リクエストでは、ハイフン(.../projects/-/serviceAccounts...)が URL の最初の部分のプロジェクト ID に対するワイルドカードとして使用されます。

リクエスト:

POST https://iam.googleapis.com/v1/projects/-/serviceAccounts/SA-2@PROJECT-ID.iam.gserviceaccount.com:getIamPolicy

レスポンス:

{
  "etag": "BwUqLaVeua8=",
  "bindings": [
    {
      "role": "roles/iam.serviceAccountUser",
      "members": [
          "user:alice@gmail.com"
      ]
    }
  ]
}

役割をサービス アカウントにまだ割り当てていない場合、レスポンスには 1 つの etag 値だけが含まれます。

{
  "etag": "ACAB"
}

上記の手順で取得した etag 値は、それが BwUqLaVeua8=ACAB かを問わず、次の手順に含める必要があります。次に、SA-1 に、roles/iam.serviceAccountTokenCreator の役割を付与するためのポリシーを作成します。

{
    "policy":
    {
        "etag": "BwUqLaVeua8=",
        "bindings": [
          {
            "role": "roles/iam.serviceAccountUser",
            "members": [
                "user:alice@gmail.com"
            ]
          },
          {
            "role": "roles/iam.serviceAccountTokenCreator",
            "members": [
                "serviceAccount:SA-1@PROJECT-ID.iam.gserviceaccount.com"
            ]
        },
        ]
    },
}

更新されたポリシーを使用して、serviceAccounts.setIamPolicy() リクエストを実行します。

POST https://iam.googleapis.com/v1/projects/-/serviceAccounts/SA-2@PROJECT-ID.iam.gserviceaccount.com:setIamPolicy

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

{
    "etag": "BwUqMqbViM8=",
    "bindings": [
    {
        "role": "roles/iam.serviceAccountUser",
        "members": [
            "user:alice@gmail.com"
        ]
    },
    {
        "role": "roles/iam.serviceAccountTokenCreator",
        "members": [
            "serviceAccount:SA-1@PROJECT-ID.iam.gserviceaccount.com"
        ]
    }
    ]
}

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

リクエスト:

POST https://iam.googleapis.com/v1/projects/-/serviceAccounts/SA-3@PROJECT-ID.iam.gserviceaccount.com:getIamPolicy

レスポンス:

{
    "etag": "BwUqLaVeua8=",
    "bindings": [
    {
        "role": "roles/iam.serviceAccountUser",
        "members": [
            "user:alice@gmail.com"
        ]
    }
    ]
}

役割をサービス アカウントにまだ割り当てていない場合、レスポンスには 1 つの etag 値だけが含まれます。

{
  "etag": "ACAB"
}

上記の手順で取得した etag 値は、それが BwUqLaVeua8=ACAB かを問わず、次の手順に含める必要があります。次に、SA-2 に、roles/iam.serviceAccountTokenCreator の役割を付与するようにポリシーを更新します。

{
    "policy":
    {
        "etag": "BwUqLaVeua8=",
        "bindings": [
        {
            "role": "roles/iam.serviceAccountUser",
            "members": [
                "user:alice@gmail.com"
            ]
        },
        {
            "role": "roles/iam.serviceAccountTokenCreator",
            "members": [
                "serviceAccount:SA-2@PROJECT-ID.iam.gserviceaccount.com"
            ]
        },
        ]
    },
}

更新されたポリシーを使用して、serviceAccounts.setIamPolicy() リクエストを実行します。

POST https://iam.googleapis.com/v1/projects/-/serviceAccounts/SA-3@PROJECT-ID.iam.gserviceaccount.com:setIamPolicy

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

{
    "etag": "BwUqMqbViM8=",
    "bindings": [
    {
        "role": "roles/iam.serviceAccountUser",
        "members": [
            "user:alice@gmail.com"
        ]
    },
    {
        "role": "roles/iam.serviceAccountTokenCreator",
        "members": [
            "serviceAccount:SA-2@PROJECT-ID.iam.gserviceaccount.com"
        ]
    }
    ]
}

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

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

こうしたリクエストに委任チェーンを指定する方法を理解するには、以下の委任チェーンの指定をご覧ください。

OAuth 2.0 アクセス トークンの生成

OAuth 2.0 アクセス トークンは 1 時間(3,600 秒間)有効です。サービス アカウントの OAuth 2.0 アクセス トークンを生成するには:

API

generateAccessToken リクエストを実行します。SA-4@PROJECT-ID.iam.gserviceaccount.com は、トークンが作成されるサービス アカウントの名前です。

リクエストは、リクエストの Authorization ヘッダーにアクセス トークンを含めることによって認証される必要があります。Google API を呼び出すためのアクセス トークンの取得方法については、OAuth 2.0 の概要サービス アカウントの OAuth 2.0 をご覧ください。

POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SA-4@PROJECT-ID.iam.gserviceaccount.com:generateAccessToken

リクエスト本文に次のフィールドを指定します。

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

これらの各フィールドとその値の例を以下に示します。

  • delegates[]: 委任リクエスト フローを使用している場合は、以下の委任チェーンの指定をご覧ください。委任がない直接リクエスト フローを使用している場合は、リクエスト本文の delegates[] フィールドを省略します。
  • scope: リクエストの OAuth 2.0 スコープ。次のスコープは、generateAccessToken API を呼び出す場合に有効です。
    • https://www.googleapis.com/auth/iam
    • https://www.googleapis.com/auth/cloud-platform
    次の例は、scope フィールドの場合の例です。
    ...
    "scope": [
      "https://www.googleapis.com/auth/cloud-platform"
    ]
    ...
    
  • lifetime: トークンの期限が切れるまでのアクセス トークンの時間(秒単位)。トークンの最大存続時間は 1 時間(3,600 秒)です。

    次の例は、トークンの時間を 5 分に設定する lifetime フィールドの例です。
    ...
    "lifetime": "300s"
    ...
    

generateAccessToken リクエストが成功した場合、レスポンスの本文には OAuth 2.0 アクセス トークンと有効期限が含まれます。

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

その後、accessToken を使用して、expireTime に達するまでサービス アカウントに代わってリクエストを認証できます。

OpenID Connect ID トークンの生成

OpenID Conect ID トークンは、1 時間(3,600 秒間)有効です。サービス アカウントの ID トークンを生成するには:

API

generateIdToken リクエストを実行します。SA-4@PROJECT-ID.iam.gserviceaccount.com は、トークンが作成されるサービス アカウントの名前です。

リクエストは、リクエストの Authorization ヘッダーにアクセス トークンを含めることによって認証される必要があります。Google API を呼び出すためのアクセス トークンの取得方法については、OAuth 2.0 の概要サービス アカウントの OAuth 2.0 をご覧ください。

POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SA-4@PROJECT-ID.iam.gserviceaccount.com:generateIdToken

リクエスト本文に次のフィールドを指定します。

{
  "delegates": [],
  "audience": "SA-4@PROJECT-ID.iam.gserviceaccount.com",
  "includeEmail": "true"
}

これらの各フィールドとその値の例を以下に示します。

  • delegates[]: 委任リクエスト フローを使用している場合は、以下の委任チェーンの指定をご覧ください。委任がない直接リクエスト フローを使用している場合は、リクエスト本文の delegates[] フィールドを省略します。
  • audience: サービスの URL または認証情報が作成されるサービス アカウントのメールアドレス。次に例を示します。
    ...
    "audience": "SA-4@PROJECT-ID.iam.gserviceaccount.com"
    ...
    
  • includeEmail: true に設定すると、ID トークンの email クレームにサービス アカウントのメールが含まれます。また、email_verified クレームが true に設定され、ID トークンに含まれます。次に例を示します。
    ...
    "includeEmail": "true"
    ...
    

generateIdToken リクエストが成功した場合、レスポンス本文には 1 時間有効な ID トークンが含まれます。

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

その後、token を使用して、サービス アカウントに代わってリクエストを認証できます。

自己署名 JSON ウェブトークン(JWT)の作成

自己署名 JWT は、次のようなさまざまなシナリオで役立ちます。

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

サービス アカウントの自己署名 JSON ウェブトークン(JWT)を生成するには:

API

signJwt リクエストを実行します。SA-4@PROJECT-ID.iam.gserviceaccount.com は、JWT が作成されるサービス アカウントの名前です。

リクエストは、リクエストの Authorization ヘッダーにアクセス トークンを含めることによって認証される必要があります。Google API を呼び出すためのアクセス トークンの取得方法については、OAuth 2.0 の概要サービス アカウントの OAuth 2.0 をご覧ください。

POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SA-4@PROJECT-ID.iam.gserviceaccount.com:signJwt

リクエスト本文に次のフィールドを指定します。

{
  "delegates": [],
  "payload": "{ \"iss\": \"SA-4@PROJECT-ID.iam.gserviceaccount.com\", \"sub\": \"SA-4@PROJECT-ID.iam.gserviceaccount.com\", \"aud\": \"https://firestore.googleapis.com/google.firestore.v1beta1.Firestore\", \"iat\": 1529350000, \"exp\": 1529353600 }"
}

これらの各フィールドとその値の例を以下に示します。

  • delegates[]: 委任リクエスト フローを使用している場合は、以下の委任チェーンの指定をご覧ください。委任がない直接リクエスト フローを使用している場合は、リクエスト本文の delegates[] フィールドを省略します。
  • payload: 署名する JWT ペイロード。これは JWT クレームセットを含む JSON オブジェクトです。ご希望のユースケースに必要なクレームを含め、ダウンストリーム サービスの検証要件を満たしてください。Google API を呼び出す場合は、クレーム要件について Google の認証ガイドをご覧ください。

    exp(有効期限)クレームは、今後 12 時間以内に設定する必要があります。そうでない場合は、検証に失敗します。JWT を使用して Google API を呼び出す場合、exp クレームは 1 時間以内に設定する必要があります。

    注: クレームセットが引用符や句読点をエスケープするように正しく書式設定されていることを確認してください。

    次のクレームセットの例には、最大存続時間を 1 時間(3,600 秒)に設定して Google API を呼び出すクレームの例が含まれています。
    ...
    "payload": "payload": "{ "iss": "SA-4@PROJECT-ID.iam.gserviceaccount.com", "sub": "SA-4@PROJECT-ID.iam.gserviceaccount.com", "aud": "https://firestore.googleapis.com/google.firestore.v1beta1.Firestore", "iat": 1529350000, "exp": 1529353600 }"
    ...
    

signJwt リクエストが成功した場合、レスポンスの本文には、署名された JWT と JWT の署名に使用された署名鍵 ID が含まれています。トークンは、リクエストで指定された有効期限まで有効です。

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

次に signedJwt 値を署名なしトークンとして使用して、サービス アカウントに代わってリクエストを直接認証できます。

自己署名 blob の作成

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

サービス アカウントの自己署名 blob を生成するには:

API

signBlob リクエストを実行します。SA-4@PROJECT-ID.iam.gserviceaccount.com は、blob が作成されるサービス アカウントの名前です。

リクエストは、リクエストの Authorization ヘッダーにアクセス トークンを含めることによって認証される必要があります。Google API を呼び出すためのアクセス トークンの取得方法については、OAuth 2.0 の概要サービス アカウントの OAuth 2.0 をご覧ください。

POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SA-4@PROJECT-ID.iam.gserviceaccount.com:signBlob

リクエスト本文に次のフィールドを指定します。

{
  "delegates": [],
  "payload": "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cu"
}

これらの各フィールドとその値の例を以下に示します。

  • delegates[]: 委任リクエスト フローを使用している場合は、以下の委任チェーンの指定をご覧ください。委任がない直接リクエスト フローを使用している場合は、リクエスト本文の delegates[] フィールドを省略します。
  • payload: Base64 でエンコードされたバイトの文字列。次に例を示します。
    ...
    "payload": "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cu"
    ...
    

signBlob リクエストが成功した場合、レスポンスの本文には、署名 blob と blob の署名に使用された署名鍵 ID が含まれています。トークンは、リクエストで指定された有効期限まで有効です。

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

委任チェーンの指定

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

projects/-/serviceAccounts/ACCOUNT-EMAIL-OR-UNIQUEID

たとえば、SA-1(呼び出し元)から SA-2(委任)、SA-3(委任)、SA-4 と移動する委任チェーンでは、delegates[] フィールドに SA-2 と SA-3 が次の順序で含まれます。

...
"delegates": [
    "projects/-/serviceAccounts/SA-2@PROJECT-ID.iam.gserviceaccount.com",
    "projects/-/serviceAccounts/SA-3@PROJECT-ID.iam.gserviceaccount.com"
],
...

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

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Cloud IAM のドキュメント