Protege y almacena datos sensibles con el conector de Secret Manager

Secret Manager es un sistema de almacenamiento seguro y conveniente para guardar claves de API, contraseñas, certificados y otros datos sensibles. Secret Manager proporciona una ubicación central y una fuente de información única para administrar secretos de auditoría, acceder a ellos y administrarlos en Google Cloud.

Puedes usar el conector de Workflows para la API de Secret Manager para acceder a Secret Manager dentro de un flujo de trabajo. Esto simplifica la integración, ya que el conector controla el formato de las solicitudes y proporciona métodos y argumentos para que no necesites conocer los detalles de la API de Secret Manager. El conector también tiene un comportamiento integrado para controlar los reintentos y las operaciones de larga duración. Para obtener más información para usar los conectores de Workflows, consulta Información sobre los conectores.

Otorga acceso a Secret Manager a la cuenta de servicio de Workflows

Secret Manager usa Identity and Access Management (IAM) para el control de acceso. Para crear, administrar, enumerar o acceder a un secreto, se deben otorgar los permisos de IAM correspondientes a nivel de proyecto y a nivel de recurso individual. Consulta Control de acceso con IAM para obtener más información.

Workflows usa cuentas de servicio para que los flujos de trabajo accedan a los recursos de Google Cloud. Para acceder a una versión del secreto, debes otorgar la función de descriptor de acceso a secretos de Secret Manager (roles/secretmanager.secretAccessor) en el secreto, el proyecto, la carpeta o la organización a la cuenta de servicio. Obtén más información sobre cómo implementar un flujo de trabajo con una cuenta de servicio administrada por el usuario.

Habilita las APIs

Antes de usar el conector de Workflows para la API de Secret Manager, asegúrate de habilitar las APIs de Secret Manager y Workflows.

Console

Habilita las APIs

gcloud

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

Invocar una llamada al conector

Al igual que cuando se invoca un extremo HTTP, una llamada al conector requiere los campos call y args. Para obtener más información, consulta Invoca una llamada al conector.

Además de usar un paso de llamada, puedes llamar a los métodos auxiliares en una expresión como la siguiente:

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

Por ejemplo, puedes usar el método auxiliar accessString para recuperar los datos del secreto como una string. Esto es más simple que usar la API de access, ya que los datos del Secret se decodifican automáticamente en un formato de cadena.

También puedes usar el método auxiliar addVersionString para agregar un valor de secreto nuevo a uno existente. Esto es más simple que usar la API de addVersion, ya que los datos del secreto se codifican de forma automática en una string de base 64, que addVersion requiere.

Recupera un Secret con el conector de Secret Manager

En el siguiente flujo de trabajo, se muestra cómo usar el conector de Secret Manager para recuperar un secreto.

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))}"
      ]
    }
  }
]

¿Qué sigue?