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

本頁面說明如何根據服務帳戶的委派鏈,為服務帳戶建立短期憑證。如要發出一連串的權杖產生呼叫,以取得執行工作所需的權杖,即可使用這種方法。

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

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

關於建立短期憑證

視您建立的權杖類型而定,您可以使用短期憑證驗證對 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 就很實用。

委派要求流程

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

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

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

事前準備

提供必要權限

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

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

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

在本範例中,必須將SA_2的服務帳戶憑證建立者角色 (roles/iam.serviceAccountTokenCreator) 授予SA_1。本範例將 SA_2 服務帳戶視為資源:在 SA_2 上授予角色時,您會以更新任何其他資源的方式更新其允許政策。

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

接下來,還必須向「SA-2」授予「SA-3」的SA_2服務帳戶憑證建立者角色 (roles/iam.serviceAccountTokenCreator),SA_3這樣 SA_2 就可以為 SA_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 值。

接下來,請修改允許政策,將服務帳戶憑證建立者角色授予 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: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 值。

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

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

{
  "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 存取憑證。

使用任何要求資料之前,請先替換以下項目:

  • SA_NAME:要為其建立權杖的服務帳戶名稱。
  • PROJECT_ID:您的 Google Cloud 專案 ID。專案 ID 為英數字串,例如 my-project
  • DELEGATES:如果您使用委派要求流程,請參閱本頁的「指定委派鏈」。如果您使用無需委派的直接要求流程,請省略要求主體中的 delegates 欄位。
  • LIFETIME:存取權杖到期前的時間長度 (以秒為單位)。例如:300s

    根據預設,權杖生命週期上限為 1 小時 (3,600 秒)。如要將這些權杖的最大生命週期延長至 12 小時 (43,200 秒),請 將服務帳戶新增至機構政策 (須含 constraints/iam.allowServiceAccountCredentialLifetimeExtension 清單限制)。

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 存取權杖和到期時間。隨後可用於驗證代表服務帳戶的要求,直到到達 expireTimeaccessToken

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

產生 OpenID Connect ID 權杖

OpenID Connect ID 憑證的有效期間為 1 小時 (3,600 秒)。如要為服務帳戶產生 ID 權杖,請執行下列操作:

API

服務帳戶憑證 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 Cloud 或非 Google 服務之間進行安全通訊,例如 App Engine 應用程式。在本情境中,應用程式可簽署憑證,以讓其他應用程式驗證憑證。
  • 透過簽署包含有關使用者、帳戶或裝置之任意憑證附加資訊的 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"
  ]
}

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