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 funciones de Trusted Space, una oferta que proporciona aislamiento de operadores sólido y compatibilidad con aceleradores para tus cargas de trabajo de IA/AA sensibles.
Proteger los datos, los modelos y las claves valiosos es más importante que nunca. Trusted Space ofrece una solución que garantiza que tus cargas de trabajo funcionen en un entorno seguro y de confianza al que ni siquiera el operador de la carga de trabajo tiene acceso.
Estas son las funciones que ofrece el 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 y claves valiosos) permanecen protegidos, respaldados por una prueba criptográfica.
- Operador aislado: Elimina las preocupaciones sobre la interferencia del operador. Con el Espacio de confianza, ni siquiera los operadores de tu carga de trabajo tienen acceso, lo que les impide usar SSH, acceder a los datos, instalar software ni manipular tu código.
- Compatibilidad con aceleradores: Trusted Space está diseñado para funcionar sin problemas con una amplia variedad de aceleradores de hardware, incluidas las GPUs como H100, A100, T4 y L4. Esto garantiza que tus aplicaciones de IA/AA críticas de 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 o AA.
Requisitos
- Un proyecto de Google Cloud Platform
- Conocimientos básicos de Google Compute Engine y aceleradores
- Conocimientos básicos de cuentas de servicio, administración de claves, federación de identidades para cargas de trabajo y condiciones de atributos.
- Conocimientos básicos sobre contenedores y Artifact Registry
Protección de instrucciones de generación de código sensibles 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, le preocupa proteger la confidencialidad de las propuestas que envían sus empleados, ya que estas suelen contener fragmentos de código sensibles, detalles internos del proyecto o algoritmos propietarios.
¿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 propiedad intelectual valiosa, incluidos algoritmos propietarios y fragmentos de código sensibles que proporcionan una ventaja competitiva. Le 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 de código “necesarias para saber” que Primus Corp quiere proteger.
Para abordar esta inquietud, Primus Corp aprovechará Trusted Space para aislar el servidor de inferencia que ejecuta el modelo para la generación de código. Funciona de la siguiente manera:
- 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 solicitud de texto sin formato. En una situación real, las bibliotecas disponibles pueden controlar la encriptación del cliente (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 grupo de Workload Identity protegería el acceso a la clave de encriptación. Debido a las garantías de aislamiento de Trusted Space, ni siquiera el operador de la carga de trabajo puede acceder a la clave utilizada para la encriptación ni al contenido desencriptado.
- Inferencia segura con aceleradores: El servidor de inferencia se lanzaría en una VM protegida (como parte de la configuración de espacio de confianza), lo que garantizaría que la instancia de la carga de trabajo no se haya visto comprometida por software malicioso o rootkits a nivel de inicio o kernel. Este servidor desencripta la instrucción dentro del entorno de Trusted Space, realiza la inferencia con el modelo de generación de código y le muestra 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 requeridas 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 artículo 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 de 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 recursos existentes si ya se crearon. (p. ej.,
export PRIMUS_SERVICE_ACCOUNT='my-service-account'
)
- Puedes configurar las siguientes variables con nombres de recursos de nube existentes en el proyecto Primus. Si se configura la variable, se usará el recurso de nube existente correspondiente del proyecto Primus. Si no se establece la variable, el nombre del recurso de nube se generará a partir del nombre del proyecto y se creará un nuevo recurso de nube con ese nombre. A continuación, se muestran las variables admitidas para los nombres de recursos:
| Es la región en la que se crearían los recursos regionales para la empresa Primus. |
| Ubicación en la que se crearían los recursos para la empresa Primus. |
| Es la zona en la que se crearían los recursos zonales para la empresa Primus. |
| El grupo de Workload Identity de la empresa Primus para proteger los recursos de la nube |
| El proveedor del grupo de Workload Identity de la empresa Primus, que incluye la condición de autorización que se usará para los tokens firmados por el servicio de Verificador de Certificación |
| Es la cuenta de servicio de la empresa Primus que |
| La clave de KMS se usa para encriptar las instrucciones que proporcionan los empleados de la empresa Primus. |
| El llavero de KMS que se usará para crear la clave de encriptación |
| La versión de la clave de KMS de la clave de encriptación |
| Es el repositorio de artefactos al que se enviará la imagen de Docker de la carga de trabajo. |
| Es la región del repositorio de artefactos que tendría la imagen de Docker de la carga de trabajo publicada. |
| Es el nombre de la VM de la carga de trabajo. |
| Es el nombre de la imagen de Docker de la carga de trabajo. |
| Etiqueta de la imagen del contenedor de la carga de trabajo. |
| La cuenta de servicio que tiene permiso para acceder a la VM confidencial que ejecuta la carga de trabajo. |
| Es el nombre de la VM del cliente que ejecutaría la aplicación cliente del servidor de inferencia. |
| La cuenta de servicio que usa |
- Necesitarás los roles de administrador de almacenamiento, 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
. Consulta 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 los recursos.
source config_env.sh
Configura los recursos de Primus Company
Como parte de este paso, configurarás los recursos de 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 Workload Identity (
$PRIMUS_WORKLOAD_IDENTITY_POOL
) para validar reclamos 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 ($PRIMUS_WORKLOAD_IDENTITY_POOL
) mencionado anteriormente tiene acceso para desencriptar datos con la clave de KMS (con el rolroles/cloudkms.cryptoKeyDecrypter
), encriptar datos con la clave de KMS (con el rolroles/cloudkms.cryptoKeyEncrypter
), leer datos del bucket de Cloud Storage (con el rolobjectViewer
) y conectar la cuenta de servicio al grupo de identidades de cargas de trabajo (conroles/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 necesarios. Ejecuta la siguiente secuencia de comandos para crear una cuenta de servicio de carga de trabajo en el proyecto Primus. La VM que ejecuta el servidor de inferencia usará esta cuenta de servicio.
Esta cuenta de servicio de la carga de trabajo ($WORKLOAD_SERVICEACCOUNT
) tendrá los siguientes roles:
confidentialcomputing.workloadUser
para obtener un token de certificaciónlogging.logWriter
para escribir registros en Cloud Logging.
./create_workload_service_account.sh
Cómo crear una carga de trabajo
Como parte de este paso, crearás una imagen de Docker de carga de trabajo. La empresa Primus sería la autora de la carga de trabajo. La carga de trabajo que se usa en este codelab es código Python que usa el modelo codegemma del bucket de GCS disponible de forma pública (del jardín de modelos de vértices). La carga de trabajo cargará el modelo de codegemma y lanzará el servidor de inferencia que entregaría 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 unida junto con un mensaje encriptado. 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 los atributos. 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 desencriptada, generará el código con un modelo cargado y mostrará la respuesta.
Ejecuta la siguiente secuencia de comandos para crear una carga de trabajo en la que se realicen 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í está el Dockerfile que se usa para este codelab.
- Compila y publica la imagen de Docker en Artifact Registry (
$PRIMUS_ARTIFACT_REGISTRY
) que pertenece a Primus. - Otorga permiso de lectura a
$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 de Artifact Registry.
./create_workload.sh
A modo de referencia, este es el método generate() de la carga de trabajo que se crea y usa en este codelab (puedes encontrar todo el código 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 que las cargas de trabajo accedan a su clave de KMS que se usa para la encriptación inmediata según los atributos de los siguientes recursos:
- Qué: Código que se verifica
- Dónde: Un entorno seguro
- Who: Un operador de confianza
Primus usa la federación de Workload Identity para aplicar una política de acceso según estos requisitos. La federación de identidades para cargas de trabajo te permite especificar condiciones de atributos. Estas condiciones restringen qué identidades pueden autenticarse con el grupo de identidades de carga de trabajo (WIP). Puedes agregar el servicio de verificador de certificación a WIP como 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 recursos en la nube. Ahora, Primus creará un nuevo proveedor de grupos de identidades de cargas de trabajo de OIDC. El --attribute-condition
especificado autoriza el acceso al contenedor de la carga de trabajo. Requiere lo siguiente:
- Qué:
$WORKLOAD_IMAGE_NAME
más reciente subido al repositorio$PRIMUS_ARTIFACT_REPOSITORY
- Dónde: 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
$WORKLOAD_SERVICE_ACCOUNT
de Primus.
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 en "GCP_SHIELDED_VM" y swname
en "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 conectado. Los argumentos de TEE obligatorios se pasan con la marca de metadatos. Los argumentos del contenedor de cargas 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 tendremos que 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 inicia correctamente el servidor de inferencia de cargas de trabajo, los empleados de la empresa Primus pueden enviar las 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 de cliente de ejemplo en un entorno virtual de Python. Esta aplicación de ejemplo utiliza la encriptación de sobre con la biblioteca Fernet, pero ten en cuenta que las bibliotecas de encriptación específicas se pueden adaptar para adaptarse a 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 del cliente.
source venv/bin/activate
python3 inference_client.py
El resultado de esta aplicación cliente de ejemplo mostrará las solicitudes de indicaciones de texto simple y encriptado, 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 de la carga 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 de cliente ($CLIENT_VM
).
./cleanup.sh
Si ya terminaste de explorar, considera borrar tu proyecto.
- Ve a la consola de Cloud Platform.
- Selecciona el proyecto que deseas cerrar y, luego, haz clic en "Borrar" en la parte superior. De esta manera, se programará la eliminación del proyecto.