创建和自定义工作负载

工作负载由工作负载作者创建,用于处理数据协作者想要使用的机密数据。

工作负载作者需要将以下资源组合在一起才能创建工作负载:

  • 应用 ,用于处理机密数据。您可以使用自己选择的任何语言编写应用,前提是您构建的容器化映像支持该语言。

  • 容器化映像 ,用于将应用 打包到其中,使用 Docker。

  • Artifact Registry 中的代码库 ,用于存储 Docker 映像。

  • 在容器映像上设置的 **启动政策** ,用于控制工作负载的运行方式,并 限制恶意工作负载运维人员的行为。

如需部署工作负载,工作负载运维人员需要根据 Confidential Space 映像 运行机密虚拟机。这会从 Artifact Registry 中检索容器化映像并运行它。

数据协作者必须 先验证工作负载的证明 ,然后才能访问其数据。

准备工作

为 Confidential Space 编写工作负载不仅仅是编写代码和调试。您还需要与数据协作者沟通以评估他们的需求,设置环境,将代码打包到容器化映像中,并与工作负载运维人员合作以确保一切部署正确。

与数据协作者沟通

在开始编写应用之前,您需要与数据协作者沟通,了解他们希望您处理的私有数据。您可以询问以下问题:

  • 涉及哪些组织 ID?

  • 涉及哪些项目编号?

  • 我需要访问哪些 Google Cloud 资源,它们的 ID 和名称是什么?

  • 是否有我需要访问但不受 Google Cloud IAM 管理的资源?

  • 应用应如何比较和处理私有数据?

  • 输出应采用什么格式?

  • 输出应存储在哪里,是否应加密?

  • 所有数据协作者看到的结果是否相同,还是每个人的输出都是唯一的?

此外,每个数据协作者可能还有您需要满足的独特隐私权要求。至关重要的是,工作负载不得泄露任何私有数据。

构建 Confidential Space 解决方案

设置两个(或更多)具有适当权限的项目作为 测试环境非常有用,就像 创建您的第一个 Confidential Space 环境一样。 尽可能模仿数据协作者的项目设置。这样,您就可以获得跨项目权限方面的经验,并从特定 Google Cloud 资源中检索所需的数据。它还可以让您了解 工作负载运维人员和数据协作者的角色 及其职责。

在早期构建阶段,观察以下做法很有用:

  • 作为数据协作者时,为了提高开发速度,请将 证明验证 保持在最低限度。

  • 作为工作负载运维人员时,请在部署工作负载时使用 Confidential Space 调试映像 而不是生产映像 这样,您就可以有更多方法来排查工作负载问题。

随着应用的成熟和状态变得更加可预测,您可以使用 证明验证 和 启动政策来加强对解决方案的锁定,并切换到生产 Confidential Space 映像。

在测试环境中正确运行工作负载后,您可以切换到在数据协作者的项目中使用真实资源但使用虚假数据进行测试,以便向数据协作者演示一切如何运作。此时,您可能开始与独立的工作负载运维人员合作。

当一切正常运行且输出符合预期时,您可以开始测试生产数据。测试完成后,所有相关方都对结果进行签字确认,工作负载即可投入生产。

谨慎处理输出

在测试代码时,您可能会想通过输出到 STDOUTSTDERR 来进行调试。如果您选择这样做,请注意不要泄露其他方可以通过访问日志读取的私有数据。在代码开始在生产环境中运行之前,请确保它不会输出任何严格必要的内容以外的内容。

最终输出也是如此。仅提供不会损害原始数据的隐私和敏感性的最终结果。

使用 Docker 构建容器化映像

应用需要打包到由 Docker 构建的容器化映像中,该映像存储在 Artifact Registry 中。部署工作负载时,Confidential Space 映像会从 Artifact Registry 代码库中拉取 Docker 映像并运行它,然后应用就可以开始处理相应的项目资源。

构建 Docker 映像时,请考虑以下事项:

其他 Linux 功能

Confidential Space 工作负载在 Linux 容器中使用 containerd 运行。此 容器使用 默认 Linux 功能运行。

如需添加功能,您可以使用 tee-added-capabilities

磁盘和内存限制

使用较大的启动磁盘大小时,Confidential Space 会自动调整启动磁盘有状态分区的大小。分区大小大致等于启动磁盘大小减去 5 GB。

作为 Confidential Space 完整性文件系统保护的一部分,Confidential Space 会将磁盘完整性标记存储在内存中。这会为每个磁盘字节使用大约 1% 的内存开销。例如,100 GB 的磁盘需要 1 GB 的内存,而 10 TB 的磁盘需要 100 GB 的内存。

请确保不要超出虚拟机内存限制。交换内存已在 Confidential Space 虚拟机上停用,这意味着过度使用内存可能会导致工作负载崩溃。 除了磁盘完整性开销之外,还要确保您选择的机器支持工作负载内存用量。

OIDC 令牌过期

OIDC 令牌可供工作负载在启动时使用。该令牌包含有关工作负载虚拟机的经过验证的证明声明,它存储在工作负载容器的 /run/container_launcher/attestation_verifier_claims_token 中。该令牌会在 60 分钟后过期。

如果令牌过期,则系统会使用指数退避算法在后台尝试刷新,直到成功为止。如果刷新失败(由于网络问题、证明服务中断或其他原因),您的工作负载代码必须能够处理这样的情况。

您的工作负载可以通过以下任一方式处理令牌刷新失败问题:

  • 忽略过期的令牌(假设在初次使用后便不再需要使用该令牌)。

  • 等待过期的令牌成功刷新。

  • 退出工作负载。

内存中暂存装载

Confidential Space 支持添加内存中暂存空间。这会使用 Confidential Space 虚拟机中的可用内存。由于暂存空间使用机密虚拟机的内存,因此它具有与机密虚拟机相同的完整性和机密性属性。

您可以使用 tee-dev-shm-size 来增加工作负载的 /dev/shm 共享内存装载的大小。 /dev/shm 大小以 KB 为单位指定。

您可以使用 tee-mount来指定 在运行的容器中使用以分号分隔的配置来指定 tmpfs 装载。 typesource 始终为 tmpfs。The destination 是装载点, 它与 tee.launch_policy.allow_mount_destinations 启动政策交互。您可以选择以字节为单位指定 tmpfs 大小。默认大小为虚拟机内存的 50%。

入站端口

默认情况下,Confidential Space 虚拟机使用防火墙规则来阻止所有入站端口。使用 230600 或更高版本的 Confidential Space 映像时,可以在构建工作负载映像时指定入站端口在 Dockerfile 中保持打开状态。

如需开放端口,请将 EXPOSE 关键字添加到 Dockerfile 中,同时添加要保持开放的端口号以及可选的协议 tcpudp。如果您未为端口指定协议,则允许使用 TCP 和 UDP。以下是公开入站端口的示例 Dockerfile

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

根据您使用的基础映像,某些端口可能已公开。Dockerfile 仅公开其他端口;它无法阻止基础映像已开放的端口。

工作负载运维人员应确保在运行工作负载之前,其 VPC 防火墙中已开放公开的端口。端口号可由工作负载作者提供,也可以从 Docker 映像信息中提取。

公开的端口会记录在控制台中,并在使用 tee-container-log-redirect 元数据变量时重定向到 Cloud Logging 。

启动政策

启动政策会替换虚拟机元数据变量 ,以限制恶意操作。工作负载作者可以在 构建容器映像时使用标签 设置政策。

例如,在 Dockerfile 中:

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

在 Bazel BUILD 文件中:

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

可用的启动政策如下表所示:

政策 类型 说明

tee.launch_policy.allow_capabilities

与以下项交互

布尔值(默认值为 false 确定工作负载运维人员是否可以向工作负载容器添加其他 Linux 功能

tee.launch_policy.allow_cgroups

与以下项交互

布尔值(默认值为 false 确定是否允许工作负载容器在 /sys/fs/cgroup中包含命名空间型 cgroup 装载。

tee.launch_policy.allow_cmd_override

与以下项交互

布尔值(默认值为 false 确定工作负载运维人员是否可以使用 tee-cmd 元数据值替换工作负载容器的 Dockerfile 中指定的 CMD

tee.launch_policy.allow_env_override

与以下项交互

以逗号分隔的字符串 允许工作负载运维人员使用 tee-env-ENVIRONMENT_VARIABLE_NAME 元数据值设置的允许的环境变量名称的以逗号分隔的字符串。

tee.launch_policy.allow_mount_destinations

与以下项交互

  • 工作负载运维人员 tee-mount 元数据变量。
以英文冒号分隔的字符串

允许工作负载 运维人员使用 tee-mount 装载的允许的装载目录的以英文冒号分隔的字符串。

例如:/run/tmp:/var/tmp:/tmp

tee.launch_policy.log_redirect

与以下项交互

已定义的字符串

确定工作负载运维人员将 tee-container-log-redirect 设置为 true 时日志记录的工作方式。

有效值如下:

  • debugonly(默认值):仅在使用调试映像时允许 stdoutstderr 重定向。
  • always:始终允许 stdoutstderr 重定向。
  • never:绝不允许 stdoutstderr 重定向。

tee.launch_policy.monitoring_memory_allow

与以下项交互

已定义的字符串

确定工作负载运维人员将 tee-monitoring-memory-enable 设置为 true 时工作负载内存用量监控的工作方式。

有效值如下:

  • debugonly(默认值):仅在使用调试映像时允许内存用量监控。
  • always:始终允许内存用量监控。
  • never:绝不允许内存用量监控。

多个工作负载运行

为了确保环境整洁,必须重启虚拟机,才能重启工作负载。这意味着,系统会使用临时密钥加密虚拟机磁盘,以防有攻击途径在下载和衡量磁盘上的工作负载映像之后对其进行修改。

不过,这也会增加启动时间和将工作负载映像拉取到每个工作负载运行等开销。如果这些开销对工作负载性能的影响太大,您可以将一个工作负载重启操作编码到工作负载中,但代价是所承担的风险也会相应增加。

命名空间型 cgroup

默认情况下,Confidential Space 工作负载在没有 cgroup 装载的情况下运行。

如需在工作负载容器中管理 cgroup,您可以使用 tee-cgroup-ns。这会在容器文件系统中的 /sys/fs/cgroup 处创建一个装载。

可重现的容器映像

以可重现的方式构建容器映像有助于提高各方之间的信任度。您可以使用 Bazel 构建可重现的映像

不受 Google Cloud IAM 管理的资源

如需访问不受 Google Cloud IAM 管理的 资源,您的工作负载需要指定自定义受众群体。

如需了解详情,请参阅 访问不受 Google Cloud IAM管理的资源。

已签名的容器映像

您可以使用公钥对容器映像进行签名,然后数据协作者可以使用该公钥进行证明,而无需在其 WIP 政策中指定映像摘要。

这意味着,数据协作者无需在每次更新工作负载时更新其 WIP 政策,并且工作负载可以继续不间断地访问受保护的资源。

您可以使用 Sigstore Cosign 对容器 映像进行签名。为了确保 Confidential Space 可以提取签名,工作负载 运维人员必须在部署工作负载之前将签名信息添加到 tee-signed-image-repos 元数据变量中。

在运行时,签名会发送到 Confidential Space 证明服务进行验证。证明服务会返回一个证明声明令牌,其中包含经过验证的签名声明。以下是签名声明的示例:

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

如需配置容器映像签名,请参阅 Codelab:已签名的容器映像