Protege y almacena datos sensibles con el conector de Secret Manager

Secret Manager es un sistema de almacenamiento seguro y conveniente para 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, acceder y auditar secretos en Google Cloud.

Puedes usar el conector de flujos de trabajo para la API de Secret Manager para acceder a Secret Manager dentro de un flujo de trabajo. Esto simplifica el por ti, ya que el conector maneja el formateo de solicitudes, y proporciona métodos y argumentos para que no tengas que saber los detalles de la API de Secret Manager. El conector también tiene un comportamiento integrado para controlar reintentos y operaciones de larga duración. Para aprender para obtener más información sobre los conectores de Workflows, consulta Comprende los conectores.

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

Secret Manager usa la administración de identidades y accesos (IAM) para el control de acceso. Para crear, administrar, enumerar o acceder a un secreto, el servicio Los permisos de IAM deben otorgarse en el nivel de proyecto y en a nivel de los recursos individuales. Para obtener más información, consulta Control de acceso con IAM.

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

Habilitación de las API

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

Habilitar las API

gcloud

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

Cómo invocar una llamada de conector

De manera similar a la invocación de un extremo HTTP, una llamada al conector requiere campos call y args. Para obtener más información, consulta Cómo invocar una llamada de conector.

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

${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 secretos como una cadena. Esto es más sencillo que usar la API de access, ya que los datos secretos se decodifican automáticamente a un formato de cadena.

También puedes usar el método auxiliar addVersionString para agregar un nuevo valor secreto. a un Secret existente. Esto es más sencillo que usar la API de addVersion, ya que los datos secretos se codifican automáticamente en una cadena de base 64, que es obligatoria para addVersion.

Recupera un secreto con el conector de Secret Manager

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

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

¿Qué sigue?