添加区域级 Secret 版本

Secret 数据不可修改,大多数操作都在 Secret 版本上进行。Secret 版本包含实际的 Secret 数据,以及有关 Secret 的状态和元数据。本页介绍如何添加 Secret 版本。

如需详细了解版本控制,请观看此视频

所需的角色

如需获得添加 Secret 版本所需的权限,请让您的管理员为您授予以下 IAM 角色:

如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限

您也可以通过自定义 角色或其他预定义 角色来获取所需的权限。

不能对 Secret 版本授予 IAM 角色。

添加 Secret 版本

如需添加 Secret 版本,请使用以下方法之一:

控制台

  1. 在 Google Cloud 控制台中,前往 Secret Manager 页面。

    前往 Secret Manager

  2. Secret Manager 页面上,点击 区域级 Secret 标签页,然后 找到要为其添加新版本的 Secret。

  3. 点击与该 Secret 关联的 操作 菜单,然后点击 添加新版本。系统随即会显示 添加新版本 对话框。

  4. Secret 值 字段中,输入 Secret 的值,例如 abcd1234。 或者,您也可以上传包含 Secret 值的文件。

  5. 点击添加新版本

gcloud

确保您已将 Secret Manager 配置为使用区域级端点 来管理区域级 Secret。

从磁盘上文件的内容添加 Secret 版本

在使用下面的命令数据之前, 请先进行以下替换:

  • SECRET_ID:Secret 的 ID
  • LOCATION:Secret 的 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"

响应中包含新创建的 Secret 版本。

直接在命令行中添加 Secret 版本

您也可以直接在命令行中添加 Secret 版本,但我们不建议这样做,因为 它会以明文形式显示 在进程列表中,并且可能会被其他系统用户捕获。请注意,包含明文的命令也会显示在您的 shell 历史记录中。

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

请替换以下内容:

  • SECRET_DATA:您要存储在 Secret 版本中的数据
  • SECRET_ID:Secret 的 ID 或 Secret 的完全限定标识符
  • LOCATION:Secret 的 Google Cloud 位置

可选:首次创建 Secret 时,从文件的内容添加版本

在使用下面的命令数据之前, 请先进行以下替换:

  • SECRET_ID:Secret 的 ID
  • LOCATION:Secret 的 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"

响应中包含新创建的 Secret 版本。

REST

对 Secret 数据进行 Base64 编码并将其另存为 shell 变量。

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

在使用任何请求数据之前, 请先进行以下替换:

  • LOCATION:Secret 的 Google Cloud 位置
  • PROJECT_ID: Google Cloud 项目 ID
  • SECRET_ID:Secret 的 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

Secret 版本状态

在任何给定时间,Secret 版本可能处于以下某种状态:

  • 已启用 - 处于此状态时,可以访问和描述 Secret 版本。 这是新 Secret 版本的默认状态。

  • 已停用 - 处于此状态时,Secret 版本无法访问,但 Secret 的内容仍然存在。您可以重新启用 Secret 版本以恢复访问权限。

  • 已销毁 - 在此状态下,Secret 版本的内容将被 舍弃。Secret 版本不能更改为其他状态。

您需要为已启用和已停用的 Secret 版本付费。对于处于已销毁状态的 Secret 版本,您无需付费。

后续步骤