使用 Secret Manager 連接器保護及儲存機密資料

Secret Manager 是安全又便利的儲存系統,可以儲存 API 金鑰、密碼、憑證和其他機密資料。Secret Manager 提供單一可靠的資料來源,可讓您集中管理、存取及稽核 Google Cloud中的密鑰。

您可以使用 Workflows 的 Secret Manager API 連接器,在工作流程中存取 Secret Manager。這可簡化整合作業,因為連接器會處理要求的格式化作業,並提供方法和引數,因此您不必瞭解 Secret Manager API 的詳細資料。此外,連接器也內建處理重試和長時間執行的作業的行為。如要進一步瞭解如何使用 Workflows 連接器,請參閱「瞭解連接器」。

授予 Workflows 服務帳戶 Secret Manager 的存取權

Secret Manager 使用身分與存取權管理 (IAM) 來控管存取權。如要建立、管理、列出或存取密鑰,必須在專案層級和個別資源層級授予適當的 IAM 權限。詳情請參閱「使用身分與存取權管理功能控管存取權」一文。

Workflows 會使用服務帳戶,授予工作流程資源存取權。Google Cloud 如要存取密鑰版本,您必須將密鑰、專案、資料夾或機構的 Secret Manager 密鑰存取者角色 (roles/secretmanager.secretAccessor) 授予服務帳戶。進一步瞭解如何使用使用者管理的服務帳戶部署工作流程

啟用 API

使用 Workflows 的 Secret Manager API 連接器前,請務必啟用 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,以字串形式擷取密碼資料。與使用 access API 相比,這種做法更簡單,因為密鑰資料會自動解碼為字串格式。

您也可以使用輔助方法 addVersionString,在現有密鑰中新增密鑰值。與使用 addVersion API 相比,這個方法更簡單,因為系統會自動將密碼資料編碼為 Base64 字串,而這是 addVersion 的必要條件。

使用 Secret Manager 連接器擷取密鑰

以下工作流程說明如何使用 Secret Manager 連接器擷取密鑰。

YAML

# This workflow demonstrates how to use the Secret Manager connector:
# Retrieve a secret using three different methods
# Expected output: the secret data (thrice)
- 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"
# Add 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"
# Retrieve the secret in string format without base-64 decoding and assume
# that the secret data is a valid UTF-8 string; if not, raise an error
- access_string_secret:
    call: googleapis.secretmanager.v1.projects.secrets.versions.accessString
    args:
      secret_id: ${secret_id}
      version: ${version}  # if not set, "latest" is used
      project_id: ${project_id}
    result: str_secret
# Retrieve the secret in string format without base-64 decoding
- access_secret:
    call: googleapis.secretmanager.v1.projects.secrets.versions.access
    args:
      name: ${"projects/" + project_id + "/secrets/" + secret_id + "/versions/" + version}
    result: base64_encoded_secret
# Retrieve the secret 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}
      - ${text.decode(base64.decode(base64_encoded_secret.payload.data))}
      - ${secret_str_from_exp}

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}",
        "${text.decode(base64.decode(base64_encoded_secret.payload.data))}",
        "${secret_str_from_exp}"
      ]
    }
  }
]

後續步驟