Un autor de cargas de trabajo crea una carga de trabajo que procesa los datos confidenciales con los que quieren trabajar los colaboradores de datos.
El autor de una 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 el idioma que quieras, siempre que crees una imagen en contenedor que lo admita.
Una imagen en contenedor para empaquetar la aplicación con Docker.
Un repositorio en Artifact Registry para almacenar la imagen de Docker.
Las políticas de inicio se definen en la imagen de contenedor y controlan cómo se puede ejecutar una carga de trabajo, así como restringen la capacidad de un operador de carga de trabajo malintencionado.
Para desplegar la carga de trabajo, un operador de carga de trabajo ejecuta una VM confidencial basada en la imagen de Confidential Space. De esta forma, se obtiene la imagen en contenedor de Artifact Registry y se ejecuta.
Los colaboradores de datos deben validar las certificaciones de una carga de trabajo antes de que pueda acceder a sus datos.
Antes de empezar
Escribir una carga de trabajo para Confidential Space es más que escribir código y depurar. También debes hablar con los colaboradores de datos para evaluar sus necesidades, configurar tu entorno, empaquetar tu código en una imagen contenerizada y trabajar con un operador de cargas de trabajo para asegurarte de que todo se implementa correctamente.
Hablar con los colaboradores de datos
Antes de empezar a escribir tu aplicación, debes hablar con tus colaboradores de datos sobre los datos privados con los que quieres trabajar. Puedes hacer preguntas como las siguientes:
¿Cuáles son los IDs de organización implicados?
¿Cuáles son los números de proyecto implicados?
¿A qué Google Cloud recursos necesito acceder y cuáles son sus IDs y nombres?
¿Hay recursos a los que necesito acceder que no están gestionados por 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 la salida y si debe cifrarse?
¿Todos los colaboradores de datos ven el mismo resultado o los resultados son únicos para cada uno?
Además, cada colaborador de datos 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.
Crear una solución de Confidential Space
Es útil configurar dos (o más) proyectos con los permisos adecuados como entorno de pruebas, como se explica en el artículo Crear tu primer entorno de Confidential Space. Intenta replicar la configuración de los proyectos de los colaboradores de datos lo mejor posible. De esta forma, podrás adquirir experiencia con los permisos entre proyectos y recuperar los datos que necesites de recursos específicos de Google Cloud . También puede ayudarte a entender los roles de operador de cargas de trabajo y colaborador de datos y sus responsabilidades.
Durante la fase inicial de desarrollo, es útil seguir estas prácticas:
Cuando trabajes como colaborador de datos, reduce al mínimo la validación de la certificación para no ralentizar el desarrollo.
Cuando trabajes como operador de cargas de trabajo, usa la imagen de depuración de Confidential Space en lugar de la de producción al desplegar la carga de trabajo. De esta forma, tendrás más opciones para solucionar los problemas de la carga de trabajo.
A medida que tu aplicación madure y su estado sea más predecible, podrás proteger tu solución cada vez más con la validación de certificación y las políticas de lanzamiento, y cambiar a la imagen de espacio confidencial de producción.
Una vez que tu carga de trabajo funcione correctamente en tu entorno de pruebas, podrás pasar a probarla en los proyectos de tus colaboradores de datos con recursos reales, pero con datos falsos para que puedas mostrarles cómo funciona todo. En este momento, puedes empezar a trabajar con un operador de cargas de trabajo independiente.
Cuando todo funcione y el resultado sea el esperado, puede empezar a hacer pruebas con datos de producción. Una vez que se hayan completado las pruebas y todas las partes hayan dado su conformidad con los resultados, la carga de trabajo estará lista para pasar a producción.
Ten cuidado con los resultados
Durante las pruebas de tu código, puede que te resulte tentador depurar imprimiendo en STDOUT
o STDERR
. Si lo haces, ten cuidado de no exponer datos privados que terceros puedan leer accediendo a los registros. Antes de que tu código empiece a funcionar en producción, asegúrate de que no genere nada más que lo estrictamente necesario.
Lo mismo ocurre con el resultado final. Solo proporciona un resultado final que no ponga en peligro la privacidad ni la confidencialidad de los datos originales.
Crear una imagen en contenedores con Docker
Las aplicaciones deben empaquetarse en una imagen contenerizada creada por Docker, que se almacena en Artifact Registry. Cuando se implementa una carga de trabajo, la imagen Docker se extrae del repositorio de Artifact Registry mediante la imagen de Confidential Space, se ejecuta y la aplicación puede empezar a trabajar en los recursos del proyecto correspondientes.
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 Linux mediante containerd. Este contenedor se ejecuta con capacidades de Linux predeterminadas.
Para añadir funciones, puedes usar tee-added-capabilities
.
Límites de disco y memoria
Espacio Confidencial 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 de disco en la memoria. Esto supone una sobrecarga de memoria de aproximadamente el 1% por 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 no superar los límites de memoria de la máquina virtual. La memoria de intercambio está inhabilitada en las VMs de Confidential Space, lo que significa que un uso excesivo de la memoria puede provocar un fallo en la carga de trabajo. Asegúrate de que la máquina que elijas admita el uso de memoria de tu carga de trabajo, además de la sobrecarga de integridad del disco.
Tokens de OIDC caducados
Cuando se inicia tu carga de trabajo, se pone a su disposición un token de OIDC para que lo consuma. Contiene reclamaciones de certificación verificadas sobre la máquina virtual 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 caduca
al cabo de 60 minutos.
Si el token caduca, se intenta actualizar en segundo plano con un tiempo de espera exponencial hasta que se consigue. Si se produce un error en la actualización (debido a problemas de red, una interrupción del servicio de atestación o cualquier otro motivo), el código de tu carga de trabajo debe poder gestionar ese error.
Tu carga de trabajo puede gestionar un fallo de actualización de tokens de una de las siguientes formas:
Ignora el token caducado, ya que no es necesario después del uso inicial.
Espera a que el token caducado se actualice correctamente.
Sal de la carga de trabajo.
Montajes de espacio de trabajo en memoria
Confidential Space permite añadir espacios de borrador en la memoria. Para ello, se usa la memoria disponible en la VM de Confidential Space. Como el espacio de trabajo usa la memoria de la máquina virtual confidencial, tiene las mismas propiedades de integridad y confidencialidad que la máquina virtual confidencial.
Puedes usar
tee-dev-shm-size
para aumentar el tamaño del montaje de memoria compartida /dev/shm
de la carga de trabajo.
El tamaño /dev/shm
se especifica en KB.
Puedes usar tee-mount
para especificar montajes de tmpfs en el contenedor en ejecución mediante configuraciones separadas por punto y coma.
type
y source
siempre son tmpfs
. El destination
es el punto de montaje, que interactúa con la política de lanzamiento tee.launch_policy.allow_mount_destinations
. También puede especificar el tamaño tmpfs
en bytes. El tamaño predeterminado es el 50% de la memoria de la VM.
Puertos de entrada
De forma predeterminada, las máquinas virtuales de Confidential Space funcionan con una regla de cortafuegos que bloquea todos los puertos entrantes. Si usas una versión de imagen de Confidential Space 230600 o posterior, puedes especificar los puertos de entrada que deben permanecer abiertos en Dockerfile
al crear la imagen de tu carga de trabajo.
Para abrir puertos, añade la palabra clave EXPOSE
a tu Dockerfile
, junto con el número de puerto que quieras mantener abierto y un protocolo opcional de tcp
o udp
. Si no especificas el protocolo de un puerto, se permitirán tanto TCP como UDP. A continuación, se muestra un ejemplo de Dockerfile
que expone puertos de entrada:
FROM alpine:latest
EXPOSE 80
EXPOSE 443/tcp
EXPOSE 81/udp
WORKDIR /test
COPY salary /test
ENTRYPOINT ["/test/salary"]
CMD []
En función de la imagen base que utilices, es posible que algunos puertos ya estén expuestos. Tu
Dockerfile
solo expone puertos adicionales; no puede bloquear puertos que ya haya abierto la imagen base.
Los operadores de cargas de trabajo deben asegurarse de que los puertos expuestos estén abiertos en su cortafuegos 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 se registran en la consola y se redirigen a Cloud Logging cuando se usa la variable de metadatos tee-container-log-redirect
.
Políticas de lanzamiento
Las políticas de lanzamiento anulan las variables de metadatos de la VM definidas por los operadores de cargas de trabajo para restringir las acciones maliciosas. El autor de una carga de trabajo puede definir políticas con una etiqueta como parte de la creación de su imagen de contenedor.
Por ejemplo, en una 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"}
...
)
En la siguiente tabla se muestran las políticas de lanzamiento disponibles:
Política | Tipo | Descripción |
---|---|---|
Interactúa con:
|
Booleano (el valor predeterminado es false ) |
Determina si el operador de carga de trabajo puede añadir capacidades de Linux adicionales al contenedor de carga de trabajo. |
Interactúa con:
|
Booleano (el valor predeterminado es false ) |
Determina si el contenedor de carga de trabajo puede incluir un montaje de cgroup con espacio de nombres en /sys/fs/cgroup .
|
Interactúa con:
|
Booleano (el valor predeterminado es false ) |
Determina si el valor de
CMD
especificado en el campo Dockerfile del contenedor de la carga de trabajo se puede
sustituir por un operador de carga de trabajo con el valor de metadatos de
tee-cmd .
|
Interactúa con:
|
Cadena separada por comas |
Cadena separada por comas de nombres de variables de entorno permitidos que puede definir un operador de carga de trabajo con valores de metadatos
tee-env-ENVIRONMENT_VARIABLE_NAME .
|
Interactúa con:
|
Cadena separada por dos puntos |
Cadena separada por dos puntos de los directorios de montaje permitidos en los que el operador de la carga de trabajo puede montar con Por ejemplo: |
Interactúa con:
|
Cadena definida |
Determina cómo funciona el registro si
Los valores válidos son:
|
Interactúa con:
|
Cadena definida |
Determina cómo funciona la monitorización del uso de memoria de la carga de trabajo si un operador de carga de trabajo asigna el valor Los valores válidos son:
|
Varias ejecuciones de cargas de trabajo
Para garantizar un entorno limpio, se debe reiniciar una VM para reiniciar una carga de trabajo. De esta forma, se 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 haya descargado y medido.
Esto también añade sobrecarga, como el tiempo de arranque y la extracción de la imagen de la carga de trabajo en cada ejecución de la carga de trabajo. Si estos gastos generales afectan demasiado al rendimiento de tu carga de trabajo, puedes codificar un reinicio de la carga de trabajo en la propia carga de trabajo, lo que aumentará tu perfil de riesgo.
Cgroups con espacio de nombres
La carga de trabajo de Confidential Space se ejecuta sin un montaje de cgroup de forma predeterminada.
Para gestionar los cgroups en el contenedor de la carga de trabajo, puedes usar tee-cgroup-ns
. De esta forma, se crea un montaje en /sys/fs/cgroup
en el sistema de archivos del contenedor.
Imágenes de contenedor reproducibles
Crear una imagen de contenedor de forma reproducible puede ayudar a aumentar la confianza entre las partes. Puedes crear imágenes reproducibles con Bazel.
Recursos no gestionados por Google Cloud IAM
Para acceder a recursos que no gestiona Google Cloud IAM, tu carga de trabajo debe especificar una audiencia personalizada.
Para obtener más información, consulta Acceder a recursos no gestionados por 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 digest de imagen en su política WIP.
Esto significa que los colaboradores de datos no tienen que 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 obtener las firmas, los operadores de cargas de trabajo deben añadir la información de la firma a la variable de metadatos tee-signed-image-repos
antes de implementar la carga de trabajo.
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 reclamaciones de certificación que contiene las reclamaciones de firma verificadas. Aquí tienes un ejemplo de reclamació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 el codelab de imágenes de contenedor firmadas.