Proteger e armazenar dados sensíveis usando o conector do Secret Manager

O Secret Manager é um sistema de armazenamento prático e seguro para chaves de API, senhas, certificados e outros dados sensíveis. Secret Manager fornece um local centralizado e uma fonte confiável para gerenciar, acessar e auditar secrets no Google Cloud.

Use o conector do Workflows para a API Secret Manager para acessar o Secret Manager em um fluxo de trabalho. Isso simplifica a integração para você, já que o conector processa a formatação das solicitações e fornece métodos e argumentos para que você não precise saber os detalhes da API Secret Manager. O conector também tem um comportamento integrado para lidar com novas tentativas e operações de longa duração. Para saber mais sobre como usar os conectores do Workflows, consulte Noções básicas sobre conectores.

Conceder à conta de serviço do Workflows acesso ao Secret Manager

O Secret Manager usa o Identity and Access Management (IAM) para controle de acesso. Para criar, gerenciar, listar ou acessar um secret, as permissões apropriadas do IAM precisam ser concedidas no nível do projeto e no nível do recurso individual. Para mais informações, consulte Controle de acesso com o IAM.

O Workflows usa contas de serviço para dar aos fluxos de trabalho acesso aos recursos do Google Cloud. Para acessar uma versão do secret, é necessário conceder o papel de acessador de secrets do Secret Manager (roles/secretmanager.secretAccessor) no secret, projeto, pasta ou organização para a conta de serviço. Saiba mais sobre como implantar um fluxo de trabalho com uma conta serviço gerenciado pelo usuário.

Ativar as APIs

Antes de usar o conector do Workflows para a API Secret Manager, ative as APIs Secret Manager e Workflows.

Console

Ativar as APIs

gcloud

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

Invocar uma chamada de conector

Assim como invocar um endpoint HTTP, uma chamada de conector requer os campos call e args. Para mais informações, consulte Invocar uma chamada de conector.

Além de usar uma etapa de chamada, é possível chamar os métodos auxiliares em uma expressão como esta:

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

Por exemplo, use o método auxiliar accessString para recuperar os dados do secret como uma string. Isso é mais simples do que usar a API access, já que os dados do secret são decodificados automaticamente para um formato de string.

Também é possível usar o método auxiliar addVersionString para adicionar um novo valor de secret a um já existente. Isso é mais simples do que usar a API addVersion, já que os dados do secret são codificados automaticamente para uma string base-64, exigida por addVersion.

Recuperar um secret usando o conector do Secret Manager

O fluxo de trabalho a seguir demonstra como usar o conector do Secret Manager para recuperar um 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))}"
      ]
    }
  }
]

A seguir