新增區域性密鑰版本

Secret 資料是不可變動的內容,大多數的作業都是在 Secret 版本上進行。密鑰版本包含實際密鑰資料,以及密鑰的狀態和中繼資料。本頁說明如何新增密鑰版本。

如要進一步瞭解版本管理,請觀看這部影片

必要的角色

如要取得新增密鑰版本所需的權限,請要求管理員在密鑰上授予下列 IAM 角色:

如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和機構的存取權」。

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

無法在密鑰版本上授予 IAM 角色。

新增密鑰版本

如要新增私密版本,請使用下列其中一種做法:

控制台

  1. 前往 Google Cloud 控制台的「Secret Manager」頁面。

    前往 Secret Manager

  2. 在「Secret Manager」頁面中,按一下「Regional secrets」分頁,然後找出要新增版本的密鑰。

  3. 按一下該密鑰的 「Actions」(動作) 選單,然後點選「Add new version」(新增版本)。系統會顯示「新增版本」對話方塊。

  4. 在「Secret value」(密鑰值) 欄位中,輸入密鑰的值,例如 abcd1234。 或者,您也可以上傳內含密鑰值的檔案。

  5. 按一下「新增版本」

gcloud

請確認您已設定 Secret Manager 使用區域端點,以便管理區域密鑰。

從磁碟上的檔案內容新增密鑰版本

使用下方的任何指令資料之前,請先替換以下項目:

  • SECRET_ID:密鑰的 ID 或密鑰的完整 ID
  • LOCATION:密鑰的 Google Cloud 位置
  • FILE_PATH:包含版本詳細資料的檔案完整路徑 (包括檔案名稱)

執行下列指令:

Linux、macOS 或 Cloud Shell

gcloud secrets versions add SECRET_ID --location=LOCATION --data-file="FILE_PATH"

Windows (PowerShell)

gcloud secrets versions add SECRET_ID --location=LOCATION --data-file="FILE_PATH"

Windows (cmd.exe)

gcloud secrets versions add SECRET_ID --location=LOCATION --data-file="FILE_PATH"

回應包含新建立的密鑰版本。

直接在指令列新增密鑰版本

您也可以直接在指令列中新增密碼版本,但我們不建議這麼做,因為密碼會以純文字形式顯示在處理程序清單中,其他系統使用者可能會擷取密碼。請注意,含有純文字的指令也會出現在殼層記錄中。

  echo -n "SECRET_DATA" | \
      gcloud secrets versions add SECRET_ID --location=LOCATION --data-file=-

取代下列項目:

  • SECRET_DATA:您要儲存在密鑰版本中的資料
  • SECRET_ID:密鑰的 ID 或密鑰的完整 ID
  • LOCATION:密鑰的 Google Cloud 位置

選用:首次建立密鑰時,從檔案內容新增版本

使用下方的任何指令資料之前,請先替換以下項目:

  • SECRET_ID:密鑰的 ID 或密鑰的完整 ID
  • LOCATION:密鑰的 Google Cloud 位置
  • FILE_PATH:包含版本詳細資料的檔案完整路徑 (包括檔案名稱)

執行下列指令:

Linux、macOS 或 Cloud Shell

gcloud secrets create SECRET_ID --location=LOCATION --data-file="FILE_PATH"

Windows (PowerShell)

gcloud secrets create SECRET_ID --location=LOCATION --data-file="FILE_PATH"

Windows (cmd.exe)

gcloud secrets create SECRET_ID --location=LOCATION --data-file="FILE_PATH"

回應包含新建立的密鑰版本。

REST

以 Base64 編碼密鑰資料,並儲存為殼層變數。

$ SECRET_DATA=$(echo "seCr3t" | base64)

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

  • LOCATION:密鑰的 Google Cloud 位置
  • PROJECT_ID:專案 ID Google Cloud
  • SECRET_ID:密鑰的 ID 或密鑰的完整 ID

HTTP 方法和網址:

POST https://secretmanager.LOCATION.rep.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/secrets/SECRET_ID:addVersion

JSON 要求主體:

{"payload": {"data": "${SECRET_DATA}"}}

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

curl

將要求主體儲存在名為 request.json 的檔案中,然後執行下列指令:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://secretmanager.LOCATION.rep.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/secrets/SECRET_ID:addVersion"

PowerShell

將要求主體儲存在名為 request.json 的檔案中,然後執行下列指令:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://secretmanager.LOCATION.rep.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/secrets/SECRET_ID:addVersion" | Select-Object -Expand Content

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

{
  "name": "projects/PROJECT_ID/locations/LOCATION/secrets/SECRET_ID/versions/1",
  "createTime": "2024-03-25T08:24:13.153705Z",
  "state": "ENABLED",
  "etag": "\"161477e6071da9\""
}

Go

如要執行這段程式碼,請先設定 Go 開發環境,並安裝 Secret Manager Go SDK。在 Compute Engine 或 GKE 上,您必須使用 cloud-platform 範圍進行驗證

import (
	"context"
	"fmt"
	"hash/crc32"
	"io"

	secretmanager "cloud.google.com/go/secretmanager/apiv1"
	"cloud.google.com/go/secretmanager/apiv1/secretmanagerpb"
	"google.golang.org/api/option"
)

// addSecretVersion adds a new secret version to the given secret with the
// provided payload.
func AddRegionalSecretVersion(w io.Writer, projectId, locationId, secretId string) error {
	// parent := "projects/my-project/locations/my-location/secrets/my-secret"

	// Declare the payload to store.
	payload := []byte("my super secret data")
	// Compute checksum, use Castagnoli polynomial. Providing a checksum
	// is optional.
	crc32c := crc32.MakeTable(crc32.Castagnoli)
	checksum := int64(crc32.Checksum(payload, crc32c))

	// Create the client.
	ctx := context.Background()

	//Endpoint to send the request to regional server
	endpoint := fmt.Sprintf("secretmanager.%s.rep.googleapis.com:443", locationId)
	client, err := secretmanager.NewClient(ctx, option.WithEndpoint(endpoint))

	if err != nil {
		return fmt.Errorf("failed to create regional secretmanager client: %w", err)
	}
	defer client.Close()

	parent := fmt.Sprintf("projects/%s/locations/%s/secrets/%s", projectId, locationId, secretId)

	// Build the request.
	req := &secretmanagerpb.AddSecretVersionRequest{
		Parent: parent,
		Payload: &secretmanagerpb.SecretPayload{
			Data:       payload,
			DataCrc32C: &checksum,
		},
	}

	// Call the API.
	result, err := client.AddSecretVersion(ctx, req)
	if err != nil {
		return fmt.Errorf("failed to add regional secret version: %w", err)
	}
	fmt.Fprintf(w, "Added regional secret version: %s\n", result.Name)
	return nil
}

Java

如要執行這段程式碼,請先設定 Java 開發環境,並安裝 Secret Manager Java SDK。在 Compute Engine 或 GKE 上,您必須使用 cloud-platform 範圍進行驗證

import com.google.cloud.secretmanager.v1.SecretManagerServiceClient;
import com.google.cloud.secretmanager.v1.SecretManagerServiceSettings;
import com.google.cloud.secretmanager.v1.SecretName;
import com.google.cloud.secretmanager.v1.SecretPayload;
import com.google.cloud.secretmanager.v1.SecretVersion;
import com.google.protobuf.ByteString;
import java.io.IOException;
import java.util.zip.CRC32C;
import java.util.zip.Checksum;

public class AddRegionalSecretVersion {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.

    // Your GCP project ID.
    String projectId = "your-project-id";
    // Location of the secret.
    String locationId = "your-location-id";
    // Resource ID of the secret.
    String secretId = "your-secret-id";
    addRegionalSecretVersion(projectId, locationId, secretId);
  }

  // Add a new version to the existing regional secret.
  public static SecretVersion addRegionalSecretVersion(
      String projectId, String locationId, String secretId) 
      throws IOException {

    // Endpoint to call the regional secret manager sever
    String apiEndpoint = String.format("secretmanager.%s.rep.googleapis.com:443", locationId);
    SecretManagerServiceSettings secretManagerServiceSettings =
        SecretManagerServiceSettings.newBuilder().setEndpoint(apiEndpoint).build();

    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (SecretManagerServiceClient client = 
        SecretManagerServiceClient.create(secretManagerServiceSettings)) {
      SecretName secretName = 
          SecretName.ofProjectLocationSecretName(projectId, locationId, secretId);
      byte[] data = "my super secret data".getBytes();
      // Calculate data checksum. The library is available in Java 9+.
      // For Java 8, use:
      // https://cloud.google.com/appengine/docs/standard/java/javadoc/com/google/appengine/api/files/Crc32c
      Checksum checksum = new CRC32C();
      checksum.update(data, 0, data.length);

      // Create the secret payload.
      SecretPayload payload =
          SecretPayload.newBuilder()
              .setData(ByteString.copyFrom(data))
              // Providing data checksum is optional.
              .setDataCrc32C(checksum.getValue())
              .build();

      // Add the secret version.
      SecretVersion version = client.addSecretVersion(secretName, payload);
      System.out.printf("Added regional secret version %s\n", version.getName());

      return version;
    }
  }
}

Node.js

如要執行這段程式碼,請先設定 Node.js 開發環境,並安裝 Secret Manager Node.js SDK。在 Compute Engine 或 GKE 上,您必須使用 cloud-platform 範圍進行驗證

/**
 * TODO(developer): Uncomment these variables before running the sample.
 */
// const projectId = 'my-project';
// const locationId = 'location';
// const secretId = 'my-secret';

const parent = `projects/${projectId}/locations/${locationId}/secrets/${secretId}`;
// Imports the Secret Manager library
const {SecretManagerServiceClient} = require('@google-cloud/secret-manager');

// Adding the endpoint to call the regional secret manager sever
const options = {};
options.apiEndpoint = `secretmanager.${locationId}.rep.googleapis.com`;

// Instantiates a client
const client = new SecretManagerServiceClient(options);

// Payload is the plaintext data to store in the secret
const payload = Buffer.from('my super secret data', 'utf8');

async function addRegionalSecretVersion() {
  const [version] = await client.addSecretVersion({
    parent: parent,
    payload: {
      data: payload,
    },
  });

  console.log(`Added regional secret version ${version.name}`);
}

addRegionalSecretVersion();

Python

如要執行這段程式碼,請先設定 Python 開發環境,然後安裝 Secret Manager Python SDK。在 Compute Engine 或 GKE 上,您必須使用 cloud-platform 範圍進行驗證

from google.cloud import secretmanager_v1
import google_crc32c


def add_regional_secret_version(
    project_id: str,
    location_id: str,
    secret_id: str,
    payload: str,
) -> secretmanager_v1.SecretVersion:
    """
    Adds a new secret version to the given secret with the provided payload.
    """

    # Endpoint to call the regional secret manager sever.
    api_endpoint = f"secretmanager.{location_id}.rep.googleapis.com"

    # Create the Secret Manager client.
    client = secretmanager_v1.SecretManagerServiceClient(
        client_options={"api_endpoint": api_endpoint},
    )

    # Build the resource name of the parent secret.
    parent = f"projects/{project_id}/locations/{location_id}/secrets/{secret_id}"

    # Convert the string payload into a bytes. This step can be omitted if you
    # pass in bytes instead of a str for the payload argument.
    payload_bytes = payload.encode("UTF-8")

    # Calculate payload checksum. Passing a checksum in add-version request
    # is optional.
    crc32c = google_crc32c.Checksum()
    crc32c.update(payload_bytes)

    # Add the secret version.
    response = client.add_secret_version(
        request={
            "parent": parent,
            "payload": {
                "data": payload_bytes,
                "data_crc32c": int(crc32c.hexdigest(), 16),
            },
        }
    )

    # Print the new secret version name.
    print(f"Added secret version: {response.name}")
    return response

密鑰版本狀態

密鑰版本在任何時間點都可能處於下列其中一種狀態:

  • 已啟用:在這個狀態下,您可以存取及說明密鑰版本。 這是新密鑰版本的預設狀態。

  • 已停用:處於這個狀態時,無法存取密鑰版本,但密鑰內容仍存在。您可以重新啟用密鑰版本,恢復存取權。

  • 已刪除 - 處於這個狀態時,系統會捨棄密鑰版本的內容。密鑰版本無法變更為其他狀態。

無論密鑰版本是否啟用,系統都會向您收費。您不必為處於已刪除狀態的密鑰版本付費。

後續步驟