使用 Secret Manager 连接器保护和存储敏感数据

Secret Manager 是一个安全便捷的存储系统,用于存储 API 密钥、密码、证书和其他敏感数据。Secret Manager 提供了一个集中、单一的数据源,便于您管理、访问和审核 Google Cloud 中的 Secret。

您可以使用 Workflows 的 Secret Manager API 连接器在工作流中访问 Secret Manager。这有助于简化集成,因为该连接器会处理请求的格式设置,并提供方法和参数,因此您无需了解 Secret Manager API 的详细信息。连接器还内置了用于处理重试和长时间运行的操作的行为。如需详细了解如何使用 Workflows 连接器,请参阅了解连接器

向 Workflows 服务帐号授予对 Secret Manager 的访问权限

Secret Manager 使用 Identity and Access Management (IAM) 进行访问权限控制。如需创建、管理、列出或访问 Secret,必须在项目层级和单个资源层级授予适当的 IAM 权限。如需了解详情,请参阅使用 IAM 进行访问权限控制

Workflows 使用服务帐号向工作流授予 Google Cloud 资源的访问权限。如需访问 Secret 版本,您必须向服务帐号授予 Secret、项目、文件夹或组织的 Secret Manager Secret Accessor 角色 (roles/secretmanager.secretAccessor)。详细了解如何使用用户代管式服务帐号部署工作流

启用 API

在使用适用于 Secret Manager API 的 Workflows 连接器之前,请确保启用 Secret Manager 和 Workflows API。

控制台

启用 API

gcloud

  gcloud services enable secretmanager.googleapis.com workflows.googleapis.com

调用连接器调用

与调用 HTTP 端点类似,连接器调用需要 callargs 字段。如需了解详情,请参阅调用连接器调用

除了使用调用步骤之外,您还可以在表达式中调用辅助方法,如下所示:

${googleapis.secretmanager.v1.projects.secrets.versions.accessString(secret_id, version, project_id)}

例如,您可以使用辅助方法 accessString 以字符串形式检索 Secret 数据。这比使用 access API 更简单,因为 Secret 数据会自动解码为字符串格式。

您还可以使用辅助方法 addVersionString 向现有 Secret 添加新的 Secret 值。这比使用 addVersion API 更简单,因为 Secret 数据会自动编码为 addVersion 所要求的 base-64 字符串。

使用 Secret Manager 连接器检索 Secret

以下工作流演示了如何使用 Secret Manager 连接器检索 Secret。

YAML

# This workflow demonstrates how to use the Cloud Secret Manager connector to.
# retrieve a secret.
# Expected successful output: the secret data.

- init:
    assign:
      - project_id: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
      - secret_id: "test-secret"  # Make sure you have this secret and it has a version of 1.
      - version: "1"
# We provide a helper method to add a secret data to an existing secret without base-64 encoding.
- add_version_string:
    call: googleapis.secretmanager.v1.projects.secrets.addVersionString
    args:
      secret_id: ${secret_id}
      project_id: ${project_id}
      data: "a new secret"
# We provide a helper method to access the secret in string format without base-64 decoding.
# To compare the usage between accessRaw() and access(), we list two demo steps to retrieve
# the same secret below.
#
# accessString assumes the secret data is a valid UTF-8 string and if it detects non-UTF-8
# bytes, an error will be raised.
- access_string_secret:
    call: googleapis.secretmanager.v1.projects.secrets.versions.accessString
    args:
      secret_id: ${secret_id}
      version: ${version}  # If not set, "latest" will be used.
      project_id: ${project_id}
    result: str_secret
- access_secret:
    call: googleapis.secretmanager.v1.projects.secrets.versions.access
    args:
      name: ${"projects/" + project_id + "/secrets/" + secret_id + "/versions/" + version}
    result: base64_encoded_secret
# Secret can also be retrieved by using positional arguments in an expression.
- expression:
    assign:
      - secret_str_from_exp: ${googleapis.secretmanager.v1.projects.secrets.versions.accessString(secret_id, version, project_id)}
- the_end:
    return:
      - ${str_secret}
      - ${secret_str_from_exp}
      - ${text.decode(base64.decode(base64_encoded_secret.payload.data))}

JSON

[
  {
    "init": {
      "assign": [
        {
          "project_id": "${sys.get_env(\"GOOGLE_CLOUD_PROJECT_ID\")}"
        },
        {
          "secret_id": "test-secret"
        },
        {
          "version": "1"
        }
      ]
    }
  },
  {
    "add_version_string": {
      "call": "googleapis.secretmanager.v1.projects.secrets.addVersionString",
      "args": {
        "secret_id": "${secret_id}",
        "project_id": "${project_id}",
        "data": "a new secret"
      }
    }
  },
  {
    "access_string_secret": {
      "call": "googleapis.secretmanager.v1.projects.secrets.versions.accessString",
      "args": {
        "secret_id": "${secret_id}",
        "version": "${version}",
        "project_id": "${project_id}"
      },
      "result": "str_secret"
    }
  },
  {
    "access_secret": {
      "call": "googleapis.secretmanager.v1.projects.secrets.versions.access",
      "args": {
        "name": "${\"projects/\" + project_id + \"/secrets/\" + secret_id + \"/versions/\" + version}"
      },
      "result": "base64_encoded_secret"
    }
  },
  {
    "expression": {
      "assign": [
        {
          "secret_str_from_exp": "${googleapis.secretmanager.v1.projects.secrets.versions.accessString(secret_id, version, project_id)}"
        }
      ]
    }
  },
  {
    "the_end": {
      "return": [
        "${str_secret}",
        "${secret_str_from_exp}",
        "${text.decode(base64.decode(base64_encoded_secret.payload.data))}"
      ]
    }
  }
]

后续步骤