工作负载由工作负载作者创建,用于处理数据协作者想要处理的机密数据。
工作负载作者需要将以下资源组合在一起才能创建工作负载:
用于处理机密数据的应用。您可以使用任意语言编写应用,前提是您构建的容器化映像支持该语言。
Artifact Registry 中的代码库,用于存储 Docker 映像。
在容器映像上设置的启动政策用于控制工作负载的运行方式,并限制恶意工作负载操作者的能力。
如需部署工作负载,工作负载操作员会基于 Confidential Space 映像运行机密虚拟机。此命令会从 Artifact Registry 中检索容器化映像并运行它。
数据协作者必须先验证工作负载的证明,然后才能访问其数据。
准备工作
为 Confidential Space 编写工作负载不仅仅是编写代码和调试。您还需要与数据协作者沟通,以评估他们的需求、设置环境、将代码打包到容器化映像中,并与工作负载运营商合作,确保所有内容都能正确部署。
与数据协作者交流
在开始编写应用之前,您需要与数据协作者讨论他们希望您处理的私密数据。 您可以提出以下问题:
涉及哪些组织 ID?
涉及哪些项目编号?
我需要访问哪些 Google Cloud 资源,以及这些资源的 ID 和名称是什么?
是否有我需要访问但不受 Google CloudIAM 管理的资源?
应用应如何比较和处理私密数据?
输出应采用什么格式?
输出应存储在哪里,是否应加密?
所有数据协作者看到的结果是否相同,还是每个人的输出都是唯一的?
此外,每个数据协作者可能还有您需要满足的独特隐私权要求。至关重要的是,工作负载不得导致任何私密数据泄露。
构建 Confidential Space 解决方案
最好设置两个(或更多)具有适当权限的项目作为测试环境,如创建您的第一个 Confidential Space 环境中所述。 尽量模仿数据协作者的项目设置。这样,您就可以体验跨项目权限,并从特定 Google Cloud 资源中检索所需的数据。您还可以借此了解工作负载操作员和数据协作者的角色及其职责。
在早期构建阶段,遵循以下做法非常有用:
作为数据协作者,为了提高开发速度,请尽量减少证明验证。
作为工作负载操作员,在部署工作负载时,请使用 Confidential Space 调试映像,而不是生产映像。这样,您就可以通过更多方式来排查工作负载问题。
随着应用日趋成熟,其状态变得更加可预测,您可以逐步通过证明验证和启动政策来锁定解决方案,并切换到生产 Confidential Space 映像。
在测试环境中使工作负载正常运行后,您可以切换到在数据协作者的项目中使用真实资源但虚假数据进行测试,以便向数据协作者演示一切如何运作。此时,您可能需要开始使用独立的工作负载运算符。
当一切正常运行且输出符合预期时,您就可以开始测试生产数据了。在测试完成后,所有相关方都对结果表示认可,工作负载即可投入生产。
谨慎处理输出内容
在测试代码时,您可能会想通过打印到 STDOUT
或 STDERR
来进行调试。如果您选择这样做,请注意不要泄露其他方可以通过访问日志读取的私密数据。在代码开始在生产环境中运行之前,请确保它不会输出任何不必要的内容。
最终输出也是如此。仅提供不会泄露原始数据隐私权和敏感性的最终结果。
使用 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 装载,方法是使用以英文分号分隔的配置。type
和 source
始终为 tmpfs
。destination
是挂载点,它与 tee.launch_policy.allow_mount_destinations
启动政策进行交互。您可以选择指定 tmpfs
大小(以字节为单位)。默认大小为虚拟机内存的 50%。
入站端口
默认情况下,Confidential Space 虚拟机使用防火墙规则来阻止所有入站端口。使用 230600 或更高版本的 Confidential Space 映像时,可以在构建工作负载映像时指定入站端口在 Dockerfile
中保持打开状态。
如需打开端口,请将 EXPOSE
关键字添加到 Dockerfile
,同时添加要保持打开状态的端口号以及可选协议 tcp
或 udp
。如果未指定端口的协议,则允许 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"}
...
)
可用的启动政策如下表所示:
政策 | 类型 | 说明 |
---|---|---|
互动对象:
|
布尔值(默认值为 false ) |
确定工作负载操作员是否可以向工作负载容器添加其他 Linux 功能。 |
互动对象:
|
布尔值(默认值为 false ) |
确定工作负载容器是否允许在 /sys/fs/cgroup 处包含命名空间的 cgroup 装载。
|
互动对象:
|
布尔值(默认值为 false ) |
确定工作负载容器的 Dockerfile 中指定的
CMD 是否可被具有
tee-cmd 元数据值的工作负载运算符替换。
|
互动对象:
|
以英文逗号分隔的字符串 |
允许被工作负载运算符通过
tee-env-ENVIRONMENT_VARIABLE_NAME 元数据值设置的允许的环境变量名称构成的字符串(以英文逗号分隔)。 |
互动对象:
|
以英文冒号分隔的字符串 |
以英文冒号分隔的字符串,其中包含工作负载操作员可以使用 例如: |
互动对象:
|
已定义的字符串 |
确定在工作负载操作器将
有效值包括:
|
互动对象:
|
已定义的字符串 |
确定在工作负载运算符将
有效值包括:
|
多个工作负载运行
为了确保环境整洁,必须重启虚拟机,才能重启工作负载。这意味着,系统会使用临时密钥加密虚拟机磁盘,以防有攻击途径在下载和衡量磁盘上的工作负载映像之后对其进行修改。
不过,这也会增加启动时间和将工作负载映像拉取到每个工作负载运行等开销。如果这些开销对工作负载性能的影响太大,您可以将一个工作负载重启操作编码到工作负载中,但代价是所承担的风险也会相应增加。
命名空间型 cgroup
默认情况下,机密空间工作负载在没有 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。