创建和自定义工作负载


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

工作负载作者需要整合以下资源才能创建工作负载:

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

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

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

  • 在容器映像上设置的启动政策,用于控制工作负载的运行方式,并限制恶意工作负载操作者的功能。

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

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

准备工作

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

与数据协作者交谈

在开始编写应用之前,您需要与数据协作者讨论他们希望您处理的私有数据。您可以提出的问题包括:

  • 涉及的组织 ID 是什么?

  • 涉及的项目编号是什么?

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

  • 我需要访问的资源是否由 Google CloudIAM 管理?

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

  • 输出应采用什么格式?

  • 输出应存储在何处?是否应对其进行加密?

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

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

构建 Confidential Space 解决方案

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

在构建的早期阶段,遵循以下做法会很有帮助:

  • 作为数据协作者,为了加快开发速度,请尽量减少认证验证

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

随着应用的成熟及其状态变得更加可预测,您可以通过认证验证启动政策,进一步锁定解决方案,并改用生产机密空间映像。

在测试环境中让工作负载正常运行后,您可以切换到数据协作者的项目中进行测试,使用真实资源(但使用虚构数据),以便向数据协作者演示所有操作的运作方式。此时,您可以开始使用独立的工作负载运维方。

当一切正常且输出符合预期时,您就可以开始使用生产数据进行测试了。测试完成并获得所有相关方的签收后,工作负载就可以正式投入使用了。

请谨慎处理输出

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

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

使用 Docker 构建容器化映像

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

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

磁盘和内存限制

使用较大的启动磁盘大小时,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 始终为 tmpfsdestination 是挂载点,可与 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_cmd_override

与以下各项互动

布尔值(默认值为 false 确定工作负载容器的 Dockerfile 中指定的 CMD 是否可被使用 tee-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-memory-monitoring-enable 设置为 true 时,工作负载内存用量监控的工作原理。

有效值包括:

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

多个工作负载运行

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

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

可重现的容器映像

以可重现的方式构建容器映像有助于增强相关方之间的信任。您可以使用 Bazel 构建可重现的映像

不受 Google Cloud IAM 管理的资源

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

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

已签名的容器映像

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

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

您可以使用 Sigstore 联合签名对容器映像进行签名。为了确保 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