Proteger y almacenar datos sensibles con el conector Secret Manager

Secret Manager es un sistema práctico y seguro para almacenar claves de API, contraseñas, certificados y otros datos sensibles. Secret Manager ofrece una única fuente de información centralizada para acceder a los secretos, gestionarlos y auditarlos en todos los componentes de Google Cloud.

Puedes usar el conector de la API Secret Manager de Workflows para acceder a Secret Manager en un flujo de trabajo. De esta forma, se simplifica la integración, ya que el conector gestiona el formato de las solicitudes y proporciona métodos y argumentos para que no tengas que conocer los detalles de la API Secret Manager. El conector también tiene un comportamiento integrado para gestionar los reintentos y las operaciones de larga duración. Para obtener más información sobre cómo usar los conectores de Workflows, consulta Información sobre los conectores.

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

Secret Manager usa Gestión de Identidades y Accesos (IAM) para el control de acceso. Para crear, gestionar, enumerar o acceder a un secreto, se deben conceder los permisos de gestión de identidades y accesos adecuados a nivel de proyecto y a nivel de recurso individual. Para obtener más información, consulta Control de acceso con IAM.

Workflows usa cuentas de servicio para dar acceso a los workflows a losGoogle Cloud recursos. Para acceder a una versión de un secreto, debes asignar el rol Permiso para acceder a los recursos de Secret Manager (roles/secretmanager.secretAccessor) a la cuenta de servicio en el secreto, el proyecto, la carpeta o la organización. Consulta más información sobre cómo implementar un flujo de trabajo con una cuenta de servicio gestionada por el usuario.

Habilitar las APIs

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

Consola

Habilitar las APIs

gcloud

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

Invocar una llamada de conector

Al igual que al invocar un endpoint HTTP, una llamada de conector requiere los campos call y args. Para obtener más información, consulta 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. Es más sencillo que usar la API access, ya que los datos secretos se decodifican automáticamente en formato de cadena.

También puedes usar el método auxiliar addVersionString para añadir un nuevo valor de secreto a un secreto que ya tengas. Es más sencillo que usar la API addVersion, ya que los datos secretos se codifican automáticamente en una cadena en base64, que es necesaria para addVersion.

Recuperar un secreto con el conector Secret Manager

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

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

Siguientes pasos