Crea y personaliza cargas de trabajo

Un autor de la carga de trabajo crea una carga de trabajo y procesa los datos confidenciales con los que los colaboradores de datos quieren trabajar.

Un autor de la carga de trabajo debe reunir los siguientes recursos para crear una carga de trabajo:

  • Una aplicación para procesar los datos confidenciales. Puedes escribir tu aplicación en cualquier lenguaje que elijas, siempre que compiles una imagen en contenedores que la admita.

  • Una imagen en contenedores para empaquetar la aplicación con Docker.

  • Un repositorio en Artifact Registry para almacenar la imagen de Docker.

  • Políticas de inicio establecidas en la imagen de contenedor que controlan cómo se puede ejecutar una carga de trabajo y restringen la capacidad de un operador de carga de trabajo malicioso.

Para implementar la carga de trabajo, un operador de carga de trabajo ejecuta una Confidential VM basada en la imagen de Confidential Space. Esto recupera la imagen en contenedores de Artifact Registry y la ejecuta.

Los colaboradores de datos deben validar las certificaciones de una carga de trabajo antes de que pueda acceder a sus datos.

Antes de comenzar

Escribir una carga de trabajo para Confidential Space es más que solo código y depuración. También debes hablar con los colaboradores de datos para evaluar sus necesidades, configurar tu entorno, empaquetar tu código en una imagen en contenedores y trabajar con un operador de carga de trabajo para asegurarte de que todo se implemente correctamente.

Habla con los colaboradores de datos

Antes de comenzar a escribir tu aplicación, debes hablar con tus colaboradores de datos sobre los datos privados con los que quieres que trabajes. Puedes hacer las siguientes preguntas:

  • ¿Cuáles son los IDs de organización involucrados?

  • ¿Cuáles son los números de proyecto involucrados?

  • ¿A qué recursos necesito acceder y cuáles son sus IDs y nombres? Google Cloud

  • ¿Hay recursos a los que necesito acceder que no administra Google Cloud IAM?

  • ¿Cómo debe comparar y procesar la aplicación los datos privados?

  • ¿En qué formato debe estar el resultado?

  • ¿Dónde se debe almacenar el resultado y debe estar encriptado?

  • ¿Todos los colaboradores de datos ven el mismo resultado o los resultados son únicos para cada uno?

Además, cada colaborador de datos también puede tener requisitos de privacidad únicos que debes cumplir. Es de vital importancia que no se expongan datos privados como resultado de una carga de trabajo.

Compila tu solución de Confidential Space

Es útil configurar dos (o más) proyectos con los permisos adecuados como un entorno de prueba, como en Crea tu primer entorno de Confidential Space. Intenta reflejar la configuración del proyecto de los colaboradores de datos lo mejor que puedas. Esto te permite adquirir experiencia con los permisos entre proyectos y recuperar los datos que necesitas de recursos específicos Google Cloud . También puede darte una idea de los roles del operador de carga de trabajo y del colaborador de datos y sus responsabilidades.

Durante la fase inicial de compilación, es útil observar las siguientes prácticas:

  • Cuando trabajes como colaborador de datos, mantén la validación de certificación al mínimo por el bien de la velocidad de desarrollo.

  • Cuando trabajes como operador de carga de trabajo, usa la imagen de depuración de Confidential Space en lugar de la producción cuando implementes la carga de trabajo. Esto te brinda más formas de solucionar problemas de la carga de trabajo.

A medida que tu aplicación madura y su estado se vuelve más predecible, puedes bloquear cada vez más tu solución con la validación de certificación y las políticas de inicio, y cambiar a la imagen de Confidential Space de producción.

Después de que la carga de trabajo funcione correctamente en tu entorno de prueba, puedes cambiar a las pruebas en los proyectos de tus colaboradores de datos con recursos reales, pero datos falsos para que puedas demostrarles a los colaboradores de datos cómo funciona todo. En este punto, puedes comenzar a trabajar con un operador de carga de trabajo independiente.

Cuando todo funcione y el resultado sea el esperado, puedes comenzar a realizar pruebas con datos de producción. Una vez que se completen las pruebas y todas las partes aprueben los resultados, la carga de trabajo estará lista para ponerse en producción.

Ten cuidado con el resultado

Mientras pruebas tu código, puede ser tentador depurar imprimiendo en STDOUT o STDERR. Si decides hacerlo, ten cuidado de no exponer datos privados que otras partes puedan leer accediendo a los registros. Antes de que tu código comience a funcionar en producción, asegúrate de que no genere nada más que lo estrictamente necesario.

Lo mismo sucede con el resultado final. Solo proporciona un resultado final que no comprometa la privacidad ni la sensibilidad de los datos originales.

Compila una imagen en contenedores con Docker

Las aplicaciones deben empaquetarse en una imagen en contenedores compilada por Docker, que se almacena en Artifact Registry. Cuando se implementa una carga de trabajo, la imagen de Docker se extrae del repositorio de Artifact Registry con la imagen de Confidential Space, se ejecuta y la aplicación puede comenzar a trabajar en los recursos del proyecto adecuados.

Cuando compiles tu imagen de Docker, ten en cuenta lo siguiente:

Funciones adicionales de Linux

La carga de trabajo de Confidential Space se ejecuta en un contenedor de Linux con containerd. Este contenedor se ejecuta con las funciones predeterminadas de Linux.

Para agregar funciones, puedes usar tee-added-capabilities.

Límites de disco y memoria

Confidential Space cambia automáticamente el tamaño de la partición con estado del disco de arranque cuando se usan tamaños de disco de arranque más grandes. El tamaño de la partición es aproximadamente el tamaño del disco de arranque menos 5 GB.

Como parte de las protecciones del sistema de archivos de integridad de Confidential Space, Confidential Space almacena etiquetas de integridad del disco en la memoria. Esto usa aproximadamente un 1% de sobrecarga de memoria para cada byte de disco. Por ejemplo, un disco de 100 GB requiere 1 GB de memoria y un disco de 10 TB requiere 100 GB de memoria.

Asegúrate de mantenerte dentro de los límites de memoria de la VM. La memoria de intercambio está inhabilitada en las VMs de Confidential Space, lo que significa que el uso excesivo de memoria puede causar fallas en la carga de trabajo. Asegúrate de que la selección de tu máquina admita el uso de memoria de la carga de trabajo, además de la sobrecarga de integridad del disco.

Tokens de OIDC vencidos

Un token de OIDC está disponible para que tu carga de trabajo lo consuma cuando se inicia. Contiene declaraciones de certificación verificadas sobre la VM de tu carga de trabajo y se almacena en el contenedor de la carga de trabajo en /run/container_launcher/attestation_verifier_claims_token. El token vence después de 60 minutos.

Si el token vence, se intenta una actualización en segundo plano con una retirada exponencial hasta que se realiza correctamente. Si falla una actualización (debido a problemas de red, una interrupción del servicio de certificación o de otro modo), el código de tu carga de trabajo debe poder controlar esa falla.

Tu carga de trabajo podría controlar una falla de actualización de token de una de las siguientes maneras:

  • Ignora el token vencido, suponiendo que ya no es necesario después del uso inicial.

  • Espera a que el token vencido se actualice correctamente.

  • Sal de la carga de trabajo.

Activaciones de espacio de trabajo en memoria

Confidential Space admite la adición de espacios de trabajo en memoria. Esto usa la memoria disponible en la VM de Confidential Space. Debido a que el espacio de trabajo usa la memoria de la Confidential VM, tiene las mismas propiedades de integridad y confidencialidad que la Confidential VM.

Puedes usar tee-dev-shm-size para aumentar el tamaño de la activación de memoria compartida /dev/shm para la carga de trabajo. El tamaño de /dev/shm se especifica en KB.

Puedes usar tee-mount para especificar activaciones de tmpfs en el contenedor en ejecución con configuraciones separadas por punto y coma. type y source siempre son tmpfs. The destination es el punto de activación, que interactúa con la tee.launch_policy.allow_mount_destinations política de inicio. De manera opcional, puedes especificar el tamaño de tmpfs en bytes. El tamaño predeterminado es el 50% de la memoria de la VM.

Puertos entrantes

De forma predeterminada, las VMs de Confidential Space operan con una regla de firewall para bloquear todos los puertos entrantes. Cuando usas una versión con imágenes de Confidential Space de 230,600 o más, puedes especificar puertos entrantes para que se mantengan abiertos en Dockerfile cuando compiles la imagen de carga de trabajo.

Para abrir puertos, agrega la palabra clave EXPOSE a tu Dockerfile, junto con el número de puerto que deseas mantener abierto y un protocolo opcional de tcp o udp. Si no especificas el protocolo para un puerto, se permiten TCP y UDP. Este es un ejemplo de Dockerfile que expone los puertos entrantes:

FROM alpine:latest
EXPOSE 80
EXPOSE 443/tcp
EXPOSE 81/udp
WORKDIR /test
COPY salary /test
ENTRYPOINT ["/test/salary"]
CMD []

Según la imagen base que uses, es posible que algunos puertos ya estén expuestos. Tu Dockerfile solo expone puertos adicionales; no puede bloquear los puertos que ya abrió la imagen base.

Los operadores de carga de trabajo deben asegurarse de que los puertos expuestos estén abiertos en su firewall de VPC antes de ejecutar la carga de trabajo. El autor de la carga de trabajo puede proporcionar los números de puerto o extraerlos de la información de la imagen de Docker.

Los puertos expuestos acceden a la consola y se redireccionan a Cloud Logging cuando se usa la tee-container-log-redirect variable de metadatos.

Políticas de inicio

Las políticas de inicio anulan las variables de metadatos de VM establecidas por los operadores de carga de trabajo para restringir las acciones maliciosas. Un autor de carga de trabajo puede establecer políticas con una etiqueta como parte de la compilación de su imagen de contenedor.

Por ejemplo, en un Dockerfile:

LABEL "tee.launch_policy.allow_cmd_override"="true"

En un archivo BUILD de Bazel:

container_image(
    ...
    labels={"tee.launch_policy.allow_cmd_override":"true"}
    ...
)

Las políticas de inicio disponibles se encuentran en la siguiente tabla:

Política Tipo Descripción

tee.launch_policy.allow_capabilities

Interactúa con:

Booleano (el valor predeterminado es false) Determina si el operador de carga de trabajo puede agregar funciones adicionales de Linux al contenedor de carga de trabajo.

tee.launch_policy.allow_cgroups

Interactúa con:

Booleano (el valor predeterminado es false) Determina si se permite que el contenedor de carga de trabajo incluya una activación de cgroup con espacio de nombres en /sys/fs/cgroup.

tee.launch_policy.allow_cmd_override

Interactúa con:

Booleano (el valor predeterminado es false) Determina si el CMD especificado en el Dockerfile del contenedor de carga de trabajo puede ser anulado por un operador de carga de trabajo con el valor de metadatos tee-cmd.

tee.launch_policy.allow_env_override

Interactúa con:

Cadena separada por comas Una cadena separada por comas de nombres de variable de entorno permitidos que pueden ser establecidos por un operador de carga de trabajo con tee-env-ENVIRONMENT_VARIABLE_NAME valores de metadatos.

tee.launch_policy.allow_mount_destinations

Interactúa con:

  • Operador de carga de trabajo: La tee-mount variable de metadatos.
Cadena separada por dos puntos

Una cadena separada por dos puntos de los directorios de activación permitidos a los que el operador de carga de trabajo puede activar con tee-mount.

Por ejemplo: /run/tmp:/var/tmp:/tmp

tee.launch_policy.log_redirect

Interactúa con:

Cadena definida

Determina cómo funciona el registro si tee-container-log-redirect se establece en true por un operador de carga de trabajo.

Los valores válidos son los siguientes:

  • debugonly (predeterminado): Solo permite stdout y stderr redireccionamientos cuando se usa una imagen de depuración.
  • always: Siempre permite redireccionamientos stdout y stderr.
  • never: Nunca permite stdout y stderr redireccionamientos.

tee.launch_policy.monitoring_memory_allow

Interactúa con:

Cadena definida

Determina cómo funciona la supervisión del uso de memoria de la carga de trabajo si tee-monitoring-memory-enable es establecido en true por un operador de carga de trabajo.

Los valores válidos son los siguientes:

  • debugonly (predeterminado): Solo permite la supervisión del uso de memoria cuando se usa una imagen de depuración.
  • always: Siempre permite la supervisión del uso de memoria.
  • never: Nunca permite la supervisión del uso de memoria.

Ejecuciones de múltiples cargas de trabajo

Para garantizar un entorno limpio, se debe reiniciar una VM para reiniciar una carga de trabajo. Esto encripta el disco de la VM con una clave efímera para abordar el vector de ataque de modificar una imagen de carga de trabajo en el disco después de que se descargó y midió.

Esto también agrega sobrecargas, como el tiempo de inicio y la extracción de la imagen de carga de trabajo, a cada ejecución de carga de trabajo. Si estas sobrecargas afectan demasiado el rendimiento de tu carga de trabajo, puedes codificar el reinicio de una carga de trabajo en la misma carga de trabajo, a costa de aumentar el perfil de riesgo.

Cgroups con espacio de nombres

La carga de trabajo de Confidential Space se ejecuta sin una activación de cgroup de forma predeterminada.

Para administrar cgroups dentro del contenedor de carga de trabajo, puedes usar tee-cgroup-ns. Esto crea una activación en /sys/fs/cgroup en el sistema de archivos del contenedor.

Imágenes de contenedor reproducibles

Compilar una imagen de contenedor de forma reproducible puede ayudar a aumentar la confianza entre las partes. Puedes compilar imágenes reproducibles con Bazel.

Recursos que no administra Google Cloud IAM

Para acceder a los recursos que no administra Google Cloud IAM, tu carga de trabajo debe especificar un público personalizado.

Para obtener más información, consulta Accede a recursos que no administra Google Cloud IAM.

Imágenes de contenedor firmadas

Puedes firmar una imagen de contenedor con una clave pública, que un colaborador de datos puede usar para la certificación en lugar de especificar un resumen de imagen en su política de WIP.

Esto significa que los colaboradores de datos no necesitan actualizar sus políticas de WIP cada vez que se actualiza una carga de trabajo, y la carga de trabajo puede seguir accediendo a los recursos protegidos sin interrupciones.

Puedes usar Sigstore Cosign para firmar la imagen de contenedor. Para asegurarse de que Confidential Space pueda recuperar las firmas, los operadores de carga de trabajo deben agregar la información de la firma a la variable de metadatos antes de implementar la carga de trabajo.tee-signed-image-repos

Durante el tiempo de ejecución, las firmas se envían al servicio de certificación de Confidential Space para su verificación. El servicio de certificación devuelve un token de declaraciones de certificación que contiene las declaraciones de firma verificadas. Este es un ejemplo de declaración de firma:

"image_signatures": [
  {
    "key_id": "hexadecimal-sha256-fingerprint-public-key1",
    "signature": "base64-encoded-signature",
    "signature_algorithm": "RSASSA_PSS_SHA256"
  },
  {
    "key_id": "hexadecimal-sha256-fingerprint-public-key2",
    "signature": "base64-encoded-signature",
    "signature_algorithm": "RSASSA_PSS_SHA256",
  },
  {
    "key_id": "hexadecimal-sha256-fingerprint-public-key3",
    "signature": "base64-encoded-signature",
    "signature_algorithm": "RSASSA_PSS_SHA256",
  }
]

Para configurar la firma de imágenes de contenedor, consulta Codelab sobre imágenes de contenedor firmadas.