列出及取得服務帳戶金鑰

本文說明如何使用Trusted Cloud 控制台、Google Cloud CLIIdentity and Access Management API 或其中一個 Google Cloud 用戶端程式庫,列出及取得服務帳戶金鑰。

事前準備

必要的角色

如要取得列出及取得服務帳戶金鑰所需的權限,請要求管理員授予您專案或服務帳戶的「查看服務帳戶」 (roles/iam.serviceAccountViewer) IAM 角色,您要管理金鑰的服務帳戶必須屬於該專案或服務帳戶。如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和機構的存取權」。

您或許還可透過自訂角色或其他預先定義的角色取得必要權限。

詳情請參閱「服務帳戶角色」。

身分與存取權管理基本角色也包含管理服務帳戶金鑰的權限。您不應在正式版環境中授予基本角色,但可以在開發或測試環境中授予。

列出服務帳戶金鑰

您可以使用Trusted Cloud 控制台、gcloud CLI、serviceAccount.keys.list() 方法,或其中一個用戶端程式庫,列出服務帳戶的服務帳戶金鑰。

serviceAccount.keys.list() 方法常用於稽核服務帳戶和金鑰,或用於建構管理服務帳戶的自訂工具。

若要查詢金鑰屬於哪個專案,您可以先將金鑰以 JSON 檔案格式下載,然後在檔案中進行查詢。

您可能會看到自己未建立的金鑰。這些金鑰是由 Google 建立,並由 Service Account Credentials API 使用。詳情請參閱Google Cloud-powered key 配對

控制台

  1. 前往 Trusted Cloud 控制台的「Service accounts」(服務帳戶) 頁面。
  2. 選取專案。
  3. 在「Service accounts」(服務帳戶) 頁面中,按一下您要列出金鑰的服務帳戶電子郵件地址。
  4. 按一下「Keys」(金鑰)。 Trusted Cloud 控制台隨即會顯示服務帳戶的金鑰清單。

gcloud

執行 gcloud iam service-accounts keys list 指令,列出服務帳戶金鑰。

替換下列值:

  • SA_NAME:要列出金鑰的服務帳戶名稱。
  • PROJECT_ID:您的 Trusted Cloud 專案 ID。
gcloud iam service-accounts keys list \
    --iam-account=SA_NAME@PROJECT_ID.s3ns-system.iam.gserviceaccount.com

輸出:

KEY_ID CREATED_AT EXPIRES_AT 已停用 DISABLE_REASON EXTENDED_STATUS
8e6e3936d7024646f8ceb39792006c07f4a9760c 2021-01-01T21:01:42Z 9999-12-31T23:59:59Z      
937c98f870f5c8db970af527aa3c12fd88b1c20a 2021-01-01T20:55:40Z 9999-12-31T23:59:59Z 使用者選擇關機  
937c98f870f5c8db970af527aa3c12fd88b1c20a 2021-01-01T20:55:40Z 9999-12-31T23:59:59Z EXPOSED ['key':'SERVICE_ACCOUNT_KEY_EXTENDED_STATUS_KEY_EXPOSED' 'value':'{exposure URL}']

C++

如要瞭解如何安裝及使用 IAM 的用戶端程式庫,請參閱 IAM 用戶端程式庫。 詳情請參閱 IAM C++ API 參考說明文件

如要向 IAM 進行驗證,請設定應用程式預設憑證。 詳情請參閱「事前準備」。

執行程式碼範例前,請將 GOOGLE_CLOUD_UNIVERSE_DOMAIN 環境變數設為 s3nsapis.fr

namespace iam = ::google::cloud::iam_admin_v1;
[](std::string const& service_account_name,
   std::vector<std::string> const& key_type_labels) {
  iam::IAMClient client(iam::MakeIAMConnection());
  std::vector<google::iam::admin::v1::ListServiceAccountKeysRequest::KeyType>
      key_types;
  for (auto const& type : key_type_labels) {
    if (type == "USER_MANAGED") {
      key_types.push_back(google::iam::admin::v1::
                              ListServiceAccountKeysRequest::USER_MANAGED);
    } else if (type == "SYSTEM_MANAGED") {
      key_types.push_back(google::iam::admin::v1::
                              ListServiceAccountKeysRequest::SYSTEM_MANAGED);
    }
  }
  auto response =
      client.ListServiceAccountKeys(service_account_name, key_types);
  if (!response) throw std::move(response).status();
  std::cout << "ServiceAccountKeys successfully retrieved: "
            << response->DebugString() << "\n";
}

C#

如要瞭解如何安裝及使用 IAM 的用戶端程式庫,請參閱 IAM 用戶端程式庫。 詳情請參閱 IAM C# API 參考說明文件

如要向 IAM 進行驗證,請設定應用程式預設憑證。 詳情請參閱「事前準備」。

執行程式碼範例前,請將 GOOGLE_CLOUD_UNIVERSE_DOMAIN 環境變數設為 s3nsapis.fr


using System;
using System.Collections.Generic;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Iam.v1;
using Google.Apis.Iam.v1.Data;

public partial class ServiceAccountKeys
{
    public static IList<ServiceAccountKey> ListKeys(string serviceAccountEmail)
    {
        var credential = GoogleCredential.GetApplicationDefault()
            .CreateScoped(IamService.Scope.CloudPlatform);
        var service = new IamService(new IamService.Initializer
        {
            HttpClientInitializer = credential
        });

        var response = service.Projects.ServiceAccounts.Keys
            .List($"projects/-/serviceAccounts/{serviceAccountEmail}")
            .Execute();
        foreach (ServiceAccountKey key in response.Keys)
        {
            Console.WriteLine("Key: " + key.Name);
        }
        return response.Keys;
    }
}

Go

如要瞭解如何安裝及使用 IAM 的用戶端程式庫,請參閱 IAM 用戶端程式庫。 詳情請參閱 IAM Go API 參考說明文件

如要向 IAM 進行驗證,請設定應用程式預設憑證。 詳情請參閱「事前準備」。

執行程式碼範例前,請將 GOOGLE_CLOUD_UNIVERSE_DOMAIN 環境變數設為 s3nsapis.fr

import (
	"context"
	"fmt"
	"io"

	iam "google.golang.org/api/iam/v1"
)

// listKey lists a service account's keys.
func listKeys(w io.Writer, serviceAccountEmail string) ([]*iam.ServiceAccountKey, error) {
	ctx := context.Background()
	service, err := iam.NewService(ctx)
	if err != nil {
		return nil, fmt.Errorf("iam.NewService: %w", err)
	}

	resource := "projects/-/serviceAccounts/" + serviceAccountEmail
	response, err := service.Projects.ServiceAccounts.Keys.List(resource).Do()
	if err != nil {
		return nil, fmt.Errorf("Projects.ServiceAccounts.Keys.List: %w", err)
	}
	for _, key := range response.Keys {
		fmt.Fprintf(w, "Listing key: %v", key.Name)
	}
	return response.Keys, nil
}

Java

如要瞭解如何安裝及使用 IAM 的用戶端程式庫,請參閱 IAM 用戶端程式庫。 詳情請參閱 IAM Java API 參考說明文件

如要向 IAM 進行驗證,請設定應用程式預設憑證。 詳情請參閱「事前準備」。

執行程式碼範例前,請將 GOOGLE_CLOUD_UNIVERSE_DOMAIN 環境變數設為 s3nsapis.fr

import com.google.cloud.iam.admin.v1.IAMClient;
import com.google.iam.admin.v1.ListServiceAccountKeysRequest;
import com.google.iam.admin.v1.ServiceAccountKey;
import java.io.IOException;
import java.util.List;

public class ListServiceAccountKeys {

  public static void main(String[] args) throws IOException {
    // TODO(Developer): Replace the below variables before running.
    String projectId = "your-project-id";
    String serviceAccountName = "your-service-account-name";

    List<ServiceAccountKey> keys = listKeys(projectId, serviceAccountName);
    keys.forEach(key -> System.out.println("Key: " + key.getName()));
  }

  // Lists all keys for a service account.
  public static List<ServiceAccountKey> listKeys(String projectId, String accountName)
          throws IOException {
    // Initialize client that will be used to send requests.
    // This client only needs to be created once, and can be reused for multiple requests.
    String email = String.format("%s@%s.iam.gserviceaccount.com", accountName, projectId);
    try (IAMClient iamClient = IAMClient.create()) {
      ListServiceAccountKeysRequest req = ListServiceAccountKeysRequest.newBuilder()
              .setName(String.format("projects/%s/serviceAccounts/%s", projectId, email))
              .build();

      return iamClient.listServiceAccountKeys(req).getKeysList();
    }
  }
}

Python

如要瞭解如何安裝及使用 IAM 的用戶端程式庫,請參閱 IAM 用戶端程式庫。 詳情請參閱 IAM Python API 參考說明文件

如要向 IAM 進行驗證,請設定應用程式預設憑證。 詳情請參閱「事前準備」。

執行程式碼範例前,請將 GOOGLE_CLOUD_UNIVERSE_DOMAIN 環境變數設為 s3nsapis.fr

from typing import List

from google.cloud import iam_admin_v1
from google.cloud.iam_admin_v1 import types


def list_keys(project_id: str, account: str) -> List[iam_admin_v1.ServiceAccountKey]:
    """Creates a key for a service account.

    project_id: ID or number of the Google Cloud project you want to use.
    account: ID or email which is unique identifier of the service account.
    """

    iam_admin_client = iam_admin_v1.IAMClient()
    request = types.ListServiceAccountKeysRequest()
    request.name = f"projects/{project_id}/serviceAccounts/{account}"

    response = iam_admin_client.list_service_account_keys(request=request)
    return response.keys

REST

projects.serviceAccounts.keys.list 方法會列出服務帳戶的所有服務帳戶金鑰。

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

  • PROJECT_ID:您的 Trusted Cloud 專案 ID。專案 ID 為英數字串,例如 my-project
  • SA_NAME:要列出金鑰的服務帳戶名稱。
  • KEY_TYPES:選用。以半形逗號分隔的鍵類型清單,您想在回應中加入這些類型。金鑰類型會指出金鑰是由使用者管理 (USER_MANAGED) 還是系統管理 (SYSTEM_MANAGED)。如果留空,系統會傳回所有金鑰。

HTTP 方法和網址:

GET https://iam.googleapis.com/v1/projects/PROJECT_ID/serviceAccounts/SA_NAME@PROJECT_ID.s3ns-system.iam.gserviceaccount.com/keys?keyTypes=KEY_TYPES

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

您應該會收到如下的 JSON 回應:

{
  "keys": [
    {
      "name": "projects/my-project/serviceAccounts/my-service-account@my-project.s3ns-system.iam.gserviceaccount.com/keys/90c48f61c65cd56224a12ab18e6ee9ca9c3aee7c",
      "validAfterTime": "2020-03-04T17:39:47Z",
      "validBeforeTime": "9999-12-31T23:59:59Z",
      "keyAlgorithm": "KEY_ALG_RSA_2048",
      "keyOrigin": "GOOGLE_PROVIDED",
      "keyType": "USER_MANAGED"
    },
    {
      "name": "projects/my-project/serviceAccounts/my-service-account@my-project.s3ns-system.iam.gserviceaccount.com/keys/e5e3800831ac1adc8a5849da7d827b4724b1fce8",
      "validAfterTime": "2020-03-31T23:50:09Z",
      "validBeforeTime": "9999-12-31T23:59:59Z",
      "keyAlgorithm": "KEY_ALG_RSA_2048",
      "keyOrigin": "GOOGLE_PROVIDED",
      "keyType": "USER_MANAGED"
    },
    {
      "name": "projects/my-project/serviceAccounts/my-service-account@my-project.s3ns-system.iam.gserviceaccount.com/keys/b97699f042b8eee6a846f4f96259fbcd13e2682e",
      "validAfterTime": "2020-05-17T18:58:13Z",
      "validBeforeTime": "9999-12-31T23:59:59Z",
      "keyAlgorithm": "KEY_ALG_RSA_2048",
      "keyOrigin": "GOOGLE_PROVIDED",
      "keyType": "USER_MANAGED",
      "disabled": true
      "disable_reason": "SERVICE_ACCOUNT_KEY_DISABLE_REASON_EXPOSED"
      "extended_status": "SERVICE_ACCOUNT_KEY_EXTENDED_STATUS_KEY_EXPOSED"
      "extended_status_message": "exposed at: https://www.github.com/SomePublicRepo"
    }
  ]
}

取得服務帳戶金鑰

您可以使用 gcloud CLI 或 REST API,取得服務帳戶金鑰的公開金鑰資料。此外,您可以使用 Trusted Cloud 控制台、gcloud CLI 或 REST API 取得金鑰的中繼資料,例如金鑰使用的演算法,以及該金鑰是由您還是 Google 管理。

部分應用程式或工具可能需要存取服務帳戶金鑰的公開金鑰資料或中繼資料,以進行稽核,並與外部系統互通。舉例來說,Terraform 可能需要驗證 Trusted Cloud by S3NS中服務帳戶金鑰的狀態,是否與 Terraform 設定檔中定義的狀態相符。

控制台

如何取得服務帳戶金鑰的公開金鑰資料:

使用 gcloud CLI 或 REST API。Trusted Cloud 控制台不提供這項資料。

如何取得服務帳戶金鑰的中繼資料:

  1. 前往 Trusted Cloud 控制台的「Service accounts」(服務帳戶) 頁面。
  2. 選取專案。
  3. 在「Service accounts」(服務帳戶) 頁面中,按一下您要列出金鑰的服務帳戶電子郵件地址。
  4. 按一下「Keys」(金鑰)。 Trusted Cloud 控制台會顯示服務帳戶的金鑰清單,包括每個金鑰的中繼資料。

gcloud

如何取得服務帳戶金鑰的公開金鑰資料:

請執行 gcloud beta iam service-accounts keys get-public-key 指令。

gcloud beta iam service-accounts keys get-public-key KEY_ID \
    --iam-account=SA_NAME@PROJECT_ID.s3ns-system.iam.gserviceaccount.com \
    --output-file=FILENAME

提供以下這些值:

  • KEY_ID:要取得的公開金鑰 ID。 如要找出金鑰 ID,請列出服務帳戶的所有金鑰,找出要取得的金鑰,然後複製其 ID。
  • SA_NAME:要取得公開金鑰的服務帳戶名稱。
  • PROJECT_ID:您的 Trusted Cloud 專案 ID。
  • FILENAME:用於儲存公開金鑰資料的檔案。

根據預設,公開金鑰資料會以 X.509 PEM 格式儲存。如要取得原始公開金鑰,請執行指令並加上 --type=raw 旗標。

舉例來說,下列指令會取得屬於服務帳戶 my-service-account@my-project.s3ns-system.iam.gserviceaccount.com 的金鑰 c97cc34494c07c9b483701f28368f20145b9ef97 公開金鑰資料,然後將公開金鑰資料儲存至 public_key.pem 檔案:

gcloud beta iam service-accounts keys get-public-key \
    c97cc34494c07c9b483701f28368f20145b9ef97 \
    --iam-account=my-service-account@my-project.s3ns-system.iam.gserviceaccount.com \
    --output-file=public_key.pem

如何取得服務帳戶金鑰的中繼資料:

執行 gcloud iam service-accounts keys list 指令:

gcloud iam service-accounts keys list --iam-account=SA_NAME \
    --filter="name~KEY_ID" --format=json

提供以下這些值:

  • SA_NAME:要取得金鑰中繼資料的服務帳戶名稱。
  • KEY_ID:您要取得中繼資料的金鑰 ID。

舉例來說,下列指令會取得金鑰 c97cc34494c07c9b483701f28368f20145b9ef97 的中繼資料,該金鑰屬於服務帳戶 my-service-account@my-project.s3ns-system.iam.gserviceaccount.com

gcloud iam service-accounts keys list \
    --iam-account=my-service-account@my-project.s3ns-system.iam.gserviceaccount.com \
    --filter="name~c97cc34494c07c9b483701f28368f20145b9ef97" --format=json

REST

projects.serviceAccounts.keys.get 方法會傳回服務帳戶的公開金鑰相關資訊。

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

  • PROJECT_ID:您的 Trusted Cloud 專案 ID。專案 ID 為英數字串,例如 my-project
  • SA_NAME:要取得公開金鑰的服務帳戶名稱。
  • KEY_ID:要取得的公開金鑰 ID。如要找出金鑰 ID,請列出服務帳戶的所有金鑰,找出要取得的金鑰,然後從 name 欄位結尾複製其 ID。金鑰 ID 是 keys/ 後方的所有內容。
  • KEY_TYPE:傳回公開金鑰的格式。使用 TYPE_X509_PEM_FILE 取得 X.509 PEM 格式,或使用 TYPE_RAW_PUBLIC_KEY 取得原始公開金鑰。如果省略這個查詢參數,方法會傳回金鑰的中繼資料,但不會傳回公開金鑰資料。

HTTP 方法和網址:

GET https://iam.googleapis.com/v1/projects/PROJECT_ID/serviceAccounts/SA_NAME@PROJECT_ID.s3ns-system.iam.gserviceaccount.com/keys/KEY_ID?publicKeyType=KEY_TYPE

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

您應該會收到如下的 JSON 回應:

{
  "name": "projects/my-project/serviceAccounts/my-service-account@my-project.s3ns-system.iam.gserviceaccount.com/keys/f4a83933ac07cf52bb74e0e66d99662a09f51a36",
  "validAfterTime": "2021-12-10T17:32:06Z",
  "validBeforeTime": "9999-12-31T23:59:59Z",
  "publicKeyData": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvRENDQWVTZ0F3SUJBZ0lJT2lCdm9hR09nV0F3RFFZSktvWklodmNOQVFFRkJRQXdJREVlTUJ3R0ExVUUKQXhNVk1UQXhNVGsxTlRFMk5UWXlPRGszTmpFek1qQXpNQ0FYRFRJeE1USXhNREUzTXpJd05sb1lEems1T1RreApNak14TWpNMU9UVTVXakFnTVI0d0hBWURWUVFERXhVeE1ERXhPVFUxTVRZMU5qSTRPVGMyTVRNeU1ETXdnZ0VpCk1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQzdzeDBFcXVUMGNwSXhlczl1SW0yRy9DS3EKdnc4YTl2a2JkaWZZbDZHSDh1ZUxEWDhGNHVUeEVQMkNzU3JLTHZtOFo2My9IVUxnWjBtQXByb0JlM08vaVR1ZwpmYVZ0NVNtakhvWm9YQ1lpbjR0MS93SkpvdDhrRFdPeDZhOEdieUdqZ215ak8yYk1XdEtaQ2dqeGZ3cUV0MmN3CklnajA5VzJKYTlHTWRsdVA0VGVubTRKSkJoaFpFbTJ1bVAwYVZZdkRnUWF5d0RCYnJuNG8yY0EzSWplRDZGM1gKK0VHRDNKU0s4VW02Sk5sM21adGp6VWNZSHBrYkF0U1A2ZDI5d1RmZkdIRFY0THJRWlM3bG15d3hsb3p5WnpaawpCOFpHckMzSkF1MVNVRTdQOTN6bWtFb1B6MlRUNWhaYXZMWFQ5TGM2SExiRklRVHFnVEJVWHlNMkpIcGZBZ01CCkFBR2pPREEyTUF3R0ExVWRFd0VCL3dRQ01BQXdEZ1lEVlIwUEFRSC9CQVFEQWdlQU1CWUdBMVVkSlFFQi93UU0KTUFvR0NDc0dBUVVGQndNQ01BMEdDU3FHU0liM0RRRUJCUVVBQTRJQkFRQkhPNXlpUDY3NkE4UEN2RjdRSzdFMApYZVljbzdsSStFZkowaGJrWVlmdUtnSENPcXcvd3FBbCtOSithanljT2FPWDFPMlRZN3ZOc05pR2t3eWc2QXdqCklhL1NHVjd3NkxpS2JldFRuSVp4UlhRY25lcnVvZEwycUR5eWphMDJJSXJVTmVKY1o0MVJBNXRTL3NkcTFGNm4KM0NjSXFoZTI1OTA4TUNna3cwaFB1K0VLbFF6R1B5T3pVRHBLdXg0cnRBaHJTYTBUVW1wbEMxdTJnUk1YRkF6aApWUjU0V2dNa2tabURyalBNeWdBS3JmNkd0bHo2VHRTYTVLb1BWdGpsWExUQkxaSnlhdk4zc1F2dFlBK1NFQWpWCnA1N1ZabFBYZmR0dWN4ekJaOC9zS25SOHNyYU5hVWFjamg1NEE1Nm1URTE3b0IyUWkrTHBJUTYvNnVqVnNXaUYKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=",
  "keyAlgorithm": "KEY_ALG_RSA_2048",
  "keyOrigin": "GOOGLE_PROVIDED",
  "keyType": "USER_MANAGED"
}

後續步驟