Codelab de Trusted Space

Codelab de Trusted Space

Acerca de este codelab

subjectÚltima actualización: ago 12, 2025
account_circleEscrito por Meetrajsinh Vala

1. Descripción general

¿Todo listo para mejorar la seguridad y la privacidad de tus cargas de trabajo aceleradas por GPU? En este codelab, se te guiará por las capacidades de Trusted Space, una oferta que proporciona un sólido aislamiento del operador y compatibilidad con aceleradores para tus cargas de trabajo sensibles de IA/AA.

Proteger los datos, los modelos y las claves valiosos es más importante que nunca. Trusted Space ofrece una solución, ya que garantiza que tus cargas de trabajo operen en un entorno seguro y de confianza en el que ni siquiera el operador de la carga de trabajo tiene acceso.

Esto es lo que ofrece Espacio de confianza:

  • Privacidad y seguridad mejoradas: Trusted Space proporciona un entorno de ejecución confiable en el que tus recursos sensibles (p.ej., modelos, datos valiosos y claves) permanecen protegidos, respaldados por pruebas criptográficas.
  • Aislamiento del operador: Elimina las preocupaciones sobre la interferencia del operador. Con Trusted Space, ni siquiera los operadores de cargas de trabajo tienen acceso, lo que les impide usar SSH, acceder a datos, instalar software o manipular tu código.
  • Compatibilidad con aceleradores: Trusted Space está diseñado para funcionar sin problemas con una amplia gama de aceleradores de hardware, incluidas las GPUs como H100, A100, T4 y L4. Esto garantiza que tus aplicaciones de IA/AA críticas para el rendimiento se ejecuten sin problemas.

Qué aprenderás

  • Comprende las ofertas clave de Trusted Space.
  • Aprende a implementar y configurar un entorno de Trusted Space para proteger los recursos valiosos de tu carga de trabajo de IA/AA.

Requisitos

Protección de instrucciones sensibles de generación de código con Primus Company

En este codelab, nos pondremos en el lugar de Primus, una empresa que prioriza la privacidad y la seguridad de los datos de sus empleados. Primus quiere implementar un modelo de generación de código para ayudar a sus desarrolladores con sus tareas de programación. Sin embargo, les preocupa proteger la confidencialidad de las instrucciones que envían sus empleados, ya que estas suelen contener fragmentos de código sensibles, detalles internos de proyectos o algoritmos patentados.

¿Por qué la empresa Primus no confía en el operador?

Primus Corp opera en un mercado altamente competitivo. Su base de código contiene valiosa propiedad intelectual, incluidos algoritmos patentados y fragmentos de código sensibles que proporcionan una ventaja competitiva. Les preocupa la posibilidad de espionaje corporativo por parte de los operadores de cargas de trabajo. Además, las instrucciones para los empleados pueden incluir partes confidenciales del código que Primus Corp desea proteger.

Para abordar esta inquietud, Primus Corp aprovechará Trusted Space para aislar el servidor de inferencia que ejecuta el modelo de generación de código. Aquí te mostramos cómo funciona:

  • Encriptación de instrucciones: Antes de enviar una instrucción al servidor de inferencia, cada empleado la encriptará con una clave de KMS administrada por Primus Corp en Google Cloud. Esto garantiza que solo el entorno de Trusted Space, en el que está disponible la clave de desencriptación correspondiente, pueda desencriptarlo y acceder a la instrucción de texto sin formato. En una situación real, la encriptación del cliente puede controlarse con las bibliotecas disponibles (p.ej., tink). Como parte de este codelab, usaremos esta aplicación cliente de ejemplo con encriptación de sobre.
  • Aislamiento del operador: Solo el servidor de inferencia, que se ejecuta en un entorno de Trusted Space, tendrá acceso a la clave que se usa para la encriptación y podrá desencriptar la instrucción en un entorno de confianza. El acceso a la clave de encriptación estaría protegido por el grupo de identidades para cargas de trabajo. Debido a las garantías de aislamiento de Trusted Space, ni siquiera el operador de la carga de trabajo puede acceder a la clave que se usa para la encriptación ni al contenido desencriptado.
  • Inferencias seguras con aceleradores: El servidor de inferencias se iniciará en una VM protegida (como parte de la configuración del espacio de confianza), lo que garantizará que la instancia de carga de trabajo no se haya visto comprometida por software malicioso o rootkits a nivel del inicio o del kernel. Este servidor descifra la instrucción dentro del entorno de Trusted Space, realiza la inferencia con el modelo de generación de código y devuelve el código generado al empleado.

2. Configura los recursos de Cloud

Antes de comenzar

  • Clona este repositorio con el siguiente comando para obtener las secuencias de comandos necesarias que se usan como parte de este codelab.
git clone https://github.com/GoogleCloudPlatform/confidential-space.git
  • Cambia el directorio de este codelab.
cd confidential-space/codelabs/trusted_space_codelab/scripts
  • Asegúrate de haber configurado las variables de entorno del proyecto necesarias como se muestra a continuación. Para obtener más información sobre cómo configurar un proyecto de GCP, consulta este codelab. Puedes consultar este vínculo para obtener detalles sobre cómo recuperar el ID del proyecto y en qué se diferencia del nombre y el número del proyecto.
export PRIMUS_PROJECT_ID=<GCP project id of Primus>
  • Habilita la facturación para tus proyectos.
  • Habilita la API de Confidential Computing y las siguientes APIs para ambos proyectos.
gcloud services enable \
    cloudapis.googleapis.com \
    cloudresourcemanager.googleapis.com \
    cloudkms.googleapis.com \
    cloudshell.googleapis.com \
    container.googleapis.com \
    containerregistry.googleapis.com \
    iam.googleapis.com \
    confidentialcomputing.googleapis.com
  • Asigna valores a las variables para los nombres de recursos especificados anteriormente con el siguiente comando. Estas variables te permiten personalizar los nombres de los recursos según sea necesario y también usar los recursos existentes si ya se crearon. (p. ej., export PRIMUS_SERVICE_ACCOUNT='my-service-account')
  1. Puedes configurar las siguientes variables con nombres de recursos de Cloud existentes en el proyecto de Primus. Si se configura la variable, se usará el recurso de Cloud existente correspondiente del proyecto de Primus. Si no se configura la variable, el nombre del recurso de Cloud se generará a partir del nombre del proyecto y se creará un nuevo recurso de Cloud con ese nombre. A continuación, se muestran las variables admitidas para los nombres de recursos:

$PRIMUS_PROJECT_REGION

Es la región en la que se crearán los recursos regionales para la empresa Primus.

$PRIMUS_SERVICE_LOCATION

Ubicación en la que se crearían los recursos para la empresa Primus.

$PRIMUS_PROJECT_ZONE

Es la zona en la que se crearían los recursos zonales para la empresa Primus.

$PRIMUS_WORKLOAD_IDENTITY_POOL

Es el grupo de identidades para cargas de trabajo de la empresa Primus que se usa para proteger los recursos de la nube.

$PRIMUS_WIP_PROVIDER

Es el proveedor del grupo de identidades para cargas de trabajo de la empresa Primus, que incluye la condición de autorización para usar los tokens firmados por el servicio de verificación de certificación.

$PRIMUS_SERVICEACCOUNT

Es la cuenta de servicio de la empresa de Primus que $PRIMUS_WORKLOAD_IDENTITY_POOL usa para acceder a los recursos protegidos. En este paso, tiene permiso para ver los datos del cliente que se almacenan en el bucket $PRIMUS_INPUT_STORAGE_BUCKET.

$PRIMUS_ENC_KEY

La clave de KMS se usa para encriptar las instrucciones proporcionadas por los empleados de la empresa Primus.

$PRIMUS_ENC_KEYRING

El llavero de KMS que se usará para crear la clave de encriptación $PRIMUS_ENC_KEY para la empresa de Primus.

$PRIMUS_ENC_KEYVERSION

Es la versión de la clave de KMS de la clave de encriptación $PRIMUS_ENC_KEY. El valor predeterminado es 1. Actualiza este valor si usas una clave existente que se rotó en el pasado y se actualizó su versión.

$PRIMUS_ARTIFACT_REPOSITORY

Es el repositorio de artefactos en el que se enviará la imagen de Docker de la carga de trabajo.

$PRIMUS_PROJECT_REPOSITORY_REGION

Es la región del repositorio de artefactos que tendrá la imagen de Docker de la carga de trabajo publicada.

$WORKLOAD_VM

Es el nombre de la VM de carga de trabajo.

$WORKLOAD_IMAGE_NAME

Es el nombre de la imagen de Docker de la carga de trabajo.

$WORKLOAD_IMAGE_TAG

Es la etiqueta de la imagen del contenedor de la carga de trabajo.

$WORKLOAD_SERVICEACCOUNT

Es la cuenta de servicio que tiene permiso para acceder a la VM confidencial que ejecuta la carga de trabajo.

$CLIENT_VM

Nombre de la VM del cliente que ejecutaría la aplicación cliente del servidor de inferencia.

$CLIENT_SERVICEACCOUNT

La cuenta de servicio que usa $CLIENT_VM

  • Necesitarás los roles de administrador de Storage, administrador de Artifact Registry, administrador de Cloud KMS, administrador de cuentas de servicio y administrador de grupos de identidades para cargas de trabajo de IAM para el proyecto $PRIMUS_PROJECT_ID. Puedes consultar esta guía para obtener información sobre cómo otorgar roles de IAM con GCP Console.
  • Para $PRIMUS_PROJECT_ID, ejecuta la siguiente secuencia de comandos para establecer los nombres de las variables restantes en valores basados en el ID de tu proyecto para los nombres de recursos.
source config_env.sh

Configura los recursos de la empresa de Primus

Como parte de este paso, configurarás los recursos de la nube necesarios para Primus. Ejecuta la siguiente secuencia de comandos para configurar los recursos de Primus. Se crearán los siguientes recursos como parte de la ejecución de la secuencia de comandos:

  • Clave de encriptación ($PRIMUS_ENC_KEY) y llavero ($PRIMUS_ENC_KEYRING) en KMS para encriptar el archivo de datos del cliente de la empresa Primus.
  • Grupo de identidades para cargas de trabajo ($PRIMUS_WORKLOAD_IDENTITY_POOL) para validar las declaraciones en función de las condiciones de atributos configuradas en su proveedor.
  • La cuenta de servicio ($PRIMUS_SERVICE_ACCOUNT) adjunta al grupo de identidades de cargas de trabajo mencionado anteriormente ($PRIMUS_WORKLOAD_IDENTITY_POOL) tiene acceso para desencriptar datos con la clave de KMS (con el rol roles/cloudkms.cryptoKeyDecrypter), encriptar datos con la clave de KMS (con el rol roles/cloudkms.cryptoKeyEncrypter), leer datos del bucket de Cloud Storage (con el rol objectViewer) y conectar la cuenta de servicio al grupo de identidades de cargas de trabajo (con el rol roles/iam.workloadIdentityUser).
./setup_primus_resources.sh

3. Crear carga de trabajo

Crea una cuenta de servicio de carga de trabajo

Ahora, crearás una cuenta de servicio para la carga de trabajo con los roles y permisos requeridos. Ejecuta el siguiente script para crear una cuenta de servicio de carga de trabajo en el proyecto de Primus. La VM que ejecuta el servidor de inferencia usaría esta cuenta de servicio.

Esta cuenta de servicio de cargas de trabajo ($WORKLOAD_SERVICEACCOUNT) tendrá los siguientes roles:

  • confidentialcomputing.workloadUser para obtener un token de certificación
  • logging.logWriter para escribir registros en Cloud Logging.
./create_workload_service_account.sh

Crear carga de trabajo

Como parte de este paso, crearás una imagen de Docker de carga de trabajo. La carga de trabajo sería creada por la empresa Primus. La carga de trabajo que se usa en este codelab es código de Python que usa el modelo codegemma del bucket de GCS disponible públicamente (del jardín de modelos de Vertex). La carga de trabajo cargará el modelo de CodeGemma y lanzará el servidor de inferencia que atenderá las solicitudes de generación de código de los desarrolladores de Primus.

En la solicitud de generación de código, Workload obtendrá la DEK encapsulada junto con una instrucción encriptada. Luego, la carga de trabajo realizará la llamada a la API de KMS para desencriptar la DEK y, luego, desencriptará la instrucción con esta DEK. Las claves de encriptación (para la DEK) se protegerían a través del grupo de identidades para cargas de trabajo, y se otorgaría acceso a las cargas de trabajo que cumplan con las condiciones de atributo. Estas condiciones de atributos se describen con más detalle en la siguiente sección sobre la autorización de la carga de trabajo. Una vez que el servidor de inferencia tenga la instrucción descifrada, generará el código con un modelo cargado y devolverá la respuesta.

Ejecuta la siguiente secuencia de comandos para crear una carga de trabajo en la que se realizan los siguientes pasos:

  • Crea Artifact Registry($PRIMUS_ARTIFACT_REGISTRY) propiedad de Primus.
  • Actualiza el código de la carga de trabajo con los nombres de los recursos requeridos.
  • Compila la carga de trabajo del servidor de inferencia y crea un Dockerfile para compilar una imagen de Docker del código de la carga de trabajo. Aquí se encuentra el Dockerfile que se usa para este codelab.
  • Compila y publica la imagen de Docker en Artifact Registry ($PRIMUS_ARTIFACT_REGISTRY) propiedad de Primus.
  • Otorga permiso de lectura de $WORKLOAD_SERVICEACCOUNT para $PRIMUS_ARTIFACT_REGISTRY. Esto es necesario para que el contenedor de la carga de trabajo extraiga la imagen de Docker de la carga de trabajo desde Artifact Registry.
./create_workload.sh

Para tu referencia, aquí se encuentra el método generate() de la carga de trabajo que se crea y usa en este codelab (puedes encontrar el código completo de la carga de trabajo aquí).

def generate():
  try:
    data = request.get_json()
    ciphertext = base64.b64decode(data["ciphertext"])
    wrapped_dek = base64.b64decode(data["wrapped_dek"])
    unwrapped_dek_response = kms_client.decrypt(
        request={"name": key_name, "ciphertext": wrapped_dek}
    )
    unwrapped_dek = unwrapped_dek_response.plaintext
    f = Fernet(unwrapped_dek)
    plaintext = f.decrypt(ciphertext)
    prompt = plaintext.decode("utf-8")
    tokens = tokenizer(prompt, return_tensors="pt")
    outputs = model.generate(**tokens, max_new_tokens=128)
    generated_code = tokenizer.decode(outputs[0])
    generated_code_bytes = generated_code.encode("utf-8")

    response = f.encrypt(generated_code_bytes)
    ciphertext_base64 = base64.b64encode(response).decode("utf-8")
    response = {"generated_code_ciphertext": ciphertext_base64}
    return jsonify(response)

  except (ValueError, TypeError, KeyError) as e:
    return jsonify({"error": str(e)}), 500

4. Autoriza y ejecuta la carga de trabajo

Autoriza la carga de trabajo

Primus quiere autorizar cargas de trabajo para que accedan a su clave de KMS que se usa para la encriptación de instrucciones según los atributos de los siguientes recursos:

  • Qué: Código que se verifica
  • Dónde: Un entorno seguro
  • Quién: Un operador de confianza

Primus usa la federación de Workload Identity para aplicar una política de acceso basada en estos requisitos. La federación de identidades para cargas de trabajo te permite especificar condiciones de atributo. Estas condiciones restringen qué identidades pueden autenticarse con el grupo de identidades para cargas de trabajo (WIP). Puedes agregar el servicio de verificador de certificación al WIP como un proveedor de grupos de identidades para cargas de trabajo para presentar mediciones y aplicar la política.

El grupo de identidades para cargas de trabajo ya se creó antes como parte del paso de configuración de los recursos de la nube. Ahora Primus creará un nuevo proveedor de grupos de identidades para cargas de trabajo de OIDC. El --attribute-condition especificado autoriza el acceso al contenedor de la carga de trabajo. Requiere lo siguiente:

  • Qué: Se subió la versión más reciente de $WORKLOAD_IMAGE_NAME al repositorio de $PRIMUS_ARTIFACT_REPOSITORY.
  • Ubicación: El entorno de ejecución confiable de Confidential Space se ejecuta en la imagen de VM de Confidential Space totalmente compatible.
  • Quién: Cuenta de servicio de Primus $WORKLOAD_SERVICE_ACCOUNT.
export WORKLOAD_IMAGE_DIGEST=$(gcloud artifacts docker images describe ${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/$PRIMUS_PROJECT_ID/$PRIMUS_ARTIFACT_REPOSITORY/$WORKLOAD_IMAGE_NAME:$WORKLOAD_IMAGE_TAG  --format="value(image_summary.digest)" --project ${PRIMUS_PROJECT_ID})
gcloud iam workload-identity-pools providers create-oidc $PRIMUS_WIP_PROVIDER \
  --location="global" \
  --project="$PRIMUS_PROJECT_ID" \
  --workload-identity-pool="$PRIMUS_WORKLOAD_IDENTITY_POOL" \
  --issuer-uri="https://confidentialcomputing.googleapis.com/" \
  --allowed-audiences="https://sts.googleapis.com" \
  --attribute-mapping="google.subject='assertion.sub'" \
  --attribute-condition="assertion.swname == 'HARDENED_SHIELDED' && assertion.hwmodel == 'GCP_SHIELDED_VM' &&
assertion.submods.container.image_digest == '${WORKLOAD_IMAGE_DIGEST}' &&
 assertion.submods.container.image_reference == '${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/$PRIMUS_PROJECT_ID/$PRIMUS_ARTIFACT_REPOSITORY/$WORKLOAD_IMAGE_NAME:$WORKLOAD_IMAGE_TAG' &&
'$WORKLOAD_SERVICEACCOUNT@$PRIMUS_PROJECT_ID.iam.gserviceaccount.com' in assertion.google_service_accounts"

El comando anterior verifica que la carga de trabajo se ejecute en un entorno de espacio de confianza. Para ello, comprueba que hwmodel esté configurado como "GCP_SHIELDED_VM" y que swname esté configurado como "HARDENED_SHIELDED". Además, incluye aserciones específicas de la carga de trabajo, como image_digest y image_reference, para mejorar la seguridad y garantizar la integridad de la carga de trabajo en ejecución.

Ejecutar carga de trabajo

Como parte de este paso, ejecutaremos la carga de trabajo en la VM de Trusted Space, que tendrá un acelerador adjunto. Los argumentos de TEE obligatorios se pasan con la marca de metadatos. Los argumentos para el contenedor de la carga de trabajo se pasan con la parte "tee-cmd" de la marca. Para equipar la VM de la carga de trabajo con una GPU Nvidia Tesla T4, usaremos la marca --accelerator=type=nvidia-tesla-t4,count=1. De esta forma, se conectará una GPU a la VM. También deberemos incluir tee-install-gpu-driver=true en las marcas de metadatos para activar la instalación del controlador de GPU adecuado.

gcloud compute instances create ${WORKLOAD_VM} \
  --accelerator=type=nvidia-tesla-t4,count=1 \
  --machine-type=n1-standard-16 \
  --shielded-secure-boot \
  --image-project=conf-space-images-preview \
  --image=confidential-space-0-gpupreview-796705b \
  --zone=${PRIMUS_PROJECT_ZONE} \
  --maintenance-policy=TERMINATE \
  --boot-disk-size=40 \
  --scopes=cloud-platform \
  --service-account=${WORKLOAD_SERVICEACCOUNT}@${PRIMUS_PROJECT_ID}.iam.gserviceaccount.com \
  --metadata="^~^tee-image-reference=${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/${PRIMUS_PROJECT_ID}/${PRIMUS_ARTIFACT_REPOSITORY}/${WORKLOAD_IMAGE_NAME}:${WORKLOAD_IMAGE_TAG}~tee-install-gpu-driver=true~tee-restart-policy=Never"

Ejecuta la consulta de inferencia

Después de que se inicie correctamente el servidor de inferencia de cargas de trabajo, los empleados de la empresa Primus podrán enviar solicitudes de generación de código al servidor de inferencia.

Como parte de este codelab, usaremos la siguiente secuencia de comandos para configurar la aplicación cliente que interactuará con el servidor de inferencia. Ejecuta esta secuencia de comandos para configurar la VM del cliente.

./setup_client.sh

En los siguientes pasos, se muestra cómo establecer una conexión SSH a la VM del cliente y ejecutar una aplicación cliente de muestra en un entorno virtual de Python. Esta aplicación de ejemplo utiliza la encriptación de sobre con la biblioteca de Fernet, pero ten en cuenta que las bibliotecas de encriptación específicas se pueden adaptar para satisfacer diferentes casos de uso.

gcloud compute ssh ${CLIENT_VM} --zone=${PRIMUS_PROJECT_ZONE}

Ejecuta los siguientes comandos para activar el entorno virtual de Python en la VM del cliente y ejecutar la aplicación cliente.

source venv/bin/activate
python3 inference_client.py

El resultado de esta aplicación cliente de muestra mostrará las solicitudes de mensajes de texto sin formato y de encriptación, y sus respuestas encriptadas y desencriptadas correspondientes.

5. Limpieza

Aquí se encuentra la secuencia de comandos que se puede usar para limpiar los recursos que creamos como parte de este codelab. Como parte de esta limpieza, se borrarán los siguientes recursos:

  • Cuenta de servicio de Primus ($PRIMUS_SERVICEACCOUNT).
  • Clave de encriptación de Primus ($PRIMUS_ENC_KEY).
  • Es el repositorio de artefactos de Primus ($PRIMUS_ARTIFACT_REPOSITORY).
  • Grupo de identidades para cargas de trabajo de Primus ($PRIMUS_WORKLOAD_IDENTITY_POOL) con su proveedor.
  • Cuenta de servicio de la carga de trabajo de Primus ($WORKLOAD_SERVICEACCOUNT).
  • VM de carga de trabajo ($WORKLOAD_VM) y VM del cliente ($CLIENT_VM).
./cleanup.sh

Si terminaste de explorar, considera borrar tu proyecto.

  • Ve a Cloud Platform Console.
  • Selecciona el proyecto que deseas cerrar y, luego, haz clic en "Borrar" en la parte superior para programar su eliminación.