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

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

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

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

Secret Manager 使用 Identity and Access Management (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}"
      ]
    }
  }
]

後續步驟