為多個服務帳戶建立短期憑證

本頁說明如何根據服務帳戶的委派鏈,為服務帳戶建立短期憑證。如要取得具有所需權限的權杖來完成工作,您需要發出一連串的權杖產生呼叫,這時就可以使用這種做法。

取得短期憑證後,您可以使用該憑證模擬服務帳戶

如果單一權杖產生呼叫即可產生具備必要權限的權杖,您應直接為該服務帳戶建立短期憑證

建立短期憑證簡介

視您建立的權杖類型而定,您可以使用短期憑證驗證對 Google API、第三方 API 或需要 ID 權杖的應用程式的呼叫。短期憑證的生命週期有限,只有幾小時或更短,且不會自動重新整理。在需要為受信任的服務帳戶授予資源的有限存取權時,短期服務帳戶憑證就派得上用場。與長期憑證 (例如服務帳戶金鑰) 相比,短期憑證的風險也較低。

您可以為服務帳戶建立下列類型的短期憑證:

  • OAuth 2.0 存取憑證

    大多數 Google API 都接受存取權杖進行驗證。為服務帳戶產生存取權杖時,存取權杖不會附帶更新權杖,因此權杖過期時,您必須重複權杖建立程序,產生新的權杖。

    詳情請參閱「存取權杖」。

  • OpenID Connect (OIDC) ID 權杖

    ID 權杖遵循 OpenID Connect (OIDC) 規格。只有少數服務和應用程式接受 ID 權杖。

    詳情請參閱「ID 權杖」和「在 Cloud Run 或 Cloud Run 函式上代管的應用程式驗證」。

  • 自行簽署的 JSON Web Token (JWT)

    您可以使用自行簽署的 JWT 向部分 Google API 進行驗證,無須從授權伺服器取得存取權杖。使用 API Gateway 部署的 API 需要這些設定。

  • 自行簽署的二進位大型物件

    當您需要安全地傳輸任意二進位資料時,通常是為了進行驗證,這時自行簽署的 Blob 就很有用。

委派要求流程

透過委派要求流程,您可以使用單一要求串連直接要求,不必依序發出多個直接要求。在這個流程中,系統會將服務帳戶憑證要求委派給委派鏈中的一或多個服務帳戶,然後為最終服務帳戶產生憑證。產生的憑證只代表最終服務帳戶,不代表委派鏈中的中繼服務帳戶。

委派鏈中的每個服務帳戶都必須具備鏈中下一個服務帳戶的必要權限,才能傳送要求。

如果一個服務帳戶就能提供所有必要權限,建議使用「從服務帳戶建立短期憑證」一文所述的簡化流程。

事前準備

  • 如果尚未啟用 IAM 和服務帳戶憑證 API,請啟用。

    啟用 API 時所需的角色

    如要啟用 API,您必須具備 serviceusage.services.enable 權限。如果您建立了專案,可能已透過「擁有者」角色 (roles/owner) 取得這項權限。否則,您可以透過「服務使用情形管理員」角色 (roles/serviceusage.serviceUsageAdmin) 取得這項權限。瞭解如何授予角色

    啟用 API

  • 瞭解 IAM 服務帳戶

  • 如果尚未啟用帳單和 IAM API,請按照快速入門導覽課程中的步驟操作。

  • 找出您要在委派鏈中使用的服務帳戶。

    您可以建立新的服務帳戶,並視需要將其納入委派鏈。

提供必要權限

委派請求涉及兩個以上的身分:呼叫者、委派鏈中的一或多個服務帳戶,以及要建立憑證的服務帳戶。在這個流程中,請考慮下列身分:

  • 服務帳戶 1 (SA_1):提出短期憑證要求的呼叫者。
  • 服務帳戶 2 (SA_2):中介服務帳戶,會將初始要求委派給 SA_3。這個帳戶只會轉送要求,不會授予 SA_1SA_3 任何額外存取權。
  • 服務帳戶 3 (SA_3):要建立憑證的有限權限帳戶。

如要允許委派,每個帳戶都必須將服務帳戶權杖建立者角色 (roles/iam.serviceAccountTokenCreator) 授予鏈結中的前一個帳戶。

在這個特定範例中,必須向 SA_1 授予 SA_2 的服務帳戶權杖建立者角色 (roles/iam.serviceAccountTokenCreator)。以下是將 SA_2 服務帳戶視為資源的範例:在 SA_2 上授予角色時,您會更新其允許政策,就像更新任何其他資源一樣。

在本範例流程中,只有一個中介服務帳戶。如要透過多個服務帳戶委派存取權,您還必須指派這個角色給委派鏈中的任何其他服務帳戶。

接著,也必須在 SA_3 上授予 SA_2 服務帳戶權杖建立者角色 (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 方法和網址:

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 值。

接著,修改允許政策,將 服務帳戶權杖建立者角色 (roles/iam.serviceAccountTokenCreator) 授予 SA_1

舉例來說,如要修改上一步中的範例回應,請新增下列內容:

{
  "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:my-user@example.com"
          ]
        },
        {
          "role": "roles/iam.serviceAccountTokenCreator",
          "members": [
            "serviceAccount:SA_1@PROJECT_ID.iam.gserviceaccount.com"
          ]
        }
      ]
    }

HTTP 方法和網址:

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 方法和網址:

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 方法和網址:

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

JSON 要求主體:

{
  "policy": POLICY
}

請展開以下其中一個選項,以傳送要求:

回應包含更新後的允許政策。

要求短期憑證

為每個身分授予適當角色後,您就可以為所需服務帳戶要求短期憑證。系統支援下列憑證類型:

如要瞭解如何為這些要求指定委派鏈,請參閱本頁的「指定委派鏈」一節。

產生 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 存取權杖。

使用任何要求資料之前,請先修改下列項目的值:

HTTP 方法和網址:

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 存取權杖和到期時間。accessToken 即可用於代表服務帳戶驗證要求,直到達到 expireTime 為止:

{
  "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:權杖的對象,通常是權杖將用於存取的應用程式或服務網址。

HTTP 方法和網址:

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 Web Token (JWT) 適用於各種情境,例如:

  • 請依據 Google 驗證指南說明驗證對 Google API 的呼叫。
  • 在 Google 服務之間或 Google 服務與非 Google 服務之間安全通訊,例如 App Engine 應用程式。 Google Cloud 在此情境中,一個應用程式可以簽署權杖,供另一個應用程式驗證,以進行驗證。
  • 透過簽署包含有關使用者、帳戶或裝置之任意憑證附加資訊的 JWT,將服務帳戶視為識別資訊提供者。

如要為服務帳戶產生自行簽署的 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 方法和網址:

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 方法和網址:

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"
  ]
}

呼叫者和要建立憑證的服務帳戶不包含在委派鏈中。