创建机密资源并授予对其的访问权限


数据协作者必须设置以下资源,才能使工作负载能够访问其保密数据:

  • 存储在 Google Cloud中的加密数据

  • 工作负载身份池 (WIP),用于授权工作负载。工作负载获得 WIP 授权后,便可访问数据协作者的机密数据并对其进行操作。

此外,数据协作者还需要选择 Confidential Space 工作负载的结果存储位置,以及这些结果是每个协作者独有还是共享。例如,您可以选择将同一结果输出到属于每位数据协作者的多个 Cloud Storage 存储分区。

存储加密数据

您可以使用任何可存储数据的 Google Cloud 服务来托管您的机密数据。例如,您可以使用以下某项服务:

您应确保这些数据在静态时已加密,无论是使用内置功能还是使用 Cloud Key Management Service (Cloud KMS) 等服务。

使用 WIP 为工作负载授权

WIP 是 Confidential Space 使用的机制,可让外部工作负载以联合身份访问和处理您的机密数据。联合身份是一种外部实体,在您自己的项目中,它被视为主账号,因此您可以向其授予 IAM 角色,以授予对特定资源的访问权限,或者模拟服务账号来执行相同的操作。

作为数据协作者,您可以在 WIP 中设置一个提供方,用于为以联合身份进行身份验证的实体设置规则。对于 Confidential Space,您必须在提供程序中定义以下内容:

  • 证明服务:此服务验证工作负载是否为 Confidential VM 实例,并最终向 WIP 提供方返回 OpenID Connect (OIDC) 证明令牌。工作负载操作员设置所用的证明服务,该服务必须与添加到 WIP 提供方的证明服务相匹配,才能授予访问权限。

  • 属性映射:安全令牌服务访问令牌中映射到身份验证实体(在本例中为运行工作负载的虚拟机实例)所做断言的属性。断言由虚拟机实例本身、Confidential Space 映像和工作负载容器做出,并由工作负载传递给 WIP 提供方。这些属性用于 Cloud Logging 中的审核轨迹等,还可用于根据经过身份验证的实体断言(例如工作负载映像容器摘要)通过 IAM 授予角色。详细了解属性映射

  • 证明政策:一系列条件,身份验证实体需要通过这些条件才能根据其做出的断言获得访问权限。

当工作负载启动时,Confidential Space 启动器会将其证明报告发送给工作负载操作员定义的证明服务,该服务会验证 Confidential VM 实例,然后返回 OIDC 证明令牌。此令牌的有效期为 1 小时,会自动刷新。

然后,工作负载会将证明令牌传递给 WIP 提供方,而提供方会使用该令牌来检查断言是否通过了提供方中定义的证明政策。如果工作负载具有这些权限,则允许其访问保密资源。

外部工作负载访问权限

在设置 WIP 和提供方之前,您需要选择工作负载将如何访问您的资源:直接资源访问权限或服务账号模拟。

直接资源访问权限

我们建议为工作负载使用直接资源访问方法。

此方法涉及在与身份验证实体的断言相关联的 WIP 提供程序中设置联合身份。这样一来,工作负载就可以根据工作负载的容器映像摘要等属性,通过 IAM 绑定直接获得访问资源的授权。

直接资源访问权限具有以下优势:

  • 设置 Confidential Space 环境所需的步骤更少,因为数据协作者无需设置服务账号来模拟工作负载服务账号。

  • 工作负载只能访问 IAM 确定的特定资源。这种方法比服务账号模拟方法更安全,因为在服务账号模拟方法中,权限过高的服务账号或模拟权限可能会为不法分子提供超出预期范围的访问权限。

  • 每次资源访问都会使用工作负载虚拟机实例的联合身份进行记录,而不是可能由多个工作负载共享的模拟服务账号的身份。工作负载虚拟机实例的身份可以包含容器的映像摘要、工作负载运行的项目编号以及运行工作负载的虚拟机实例的 ID 等详细信息,从而提供更详细的审核轨迹。

  • 您无需在 WIP 提供方中将虚拟机实例的 selfLink 属性映射到 google.subject 属性。过长的 selfLink 值可能会超出此属性的 127 字节限制,导致 WIP 提供程序身份验证失败。

服务账号模拟

服务账号模拟方法涉及每个数据协作者设置一个服务账号来解密其私密数据,然后将该服务账号附加到其自己的 WIP。它们还在 WIP 提供程序中指定了工作负载服务账号,这允许工作负载服务账号模拟数据协作者服务账号,以便检索和操作其机密数据。

服务账号模拟仅应在以下场景中使用:

如果虚拟机实例的 selfLink 属性非常长,服务账号模拟方法可能无法向 WIP 提供方进行身份验证。这是因为证明令牌中的 sub 声明(设置为 selfLink 值)在 WIP 提供程序中映射到 google.subject 属性,该属性的限制为 127 字节。

对于超过 127 字节的虚拟机实例 selfLink 值,您必须重命名虚拟机实例以缩短 selfLink,或者改用直接资源访问方法。

设置 WIP 和提供方

设置提供程序的步骤因您使用的是直接资源访问还是服务账号模拟而异。

直接资源访问权限

直接资源访问方法涉及设置 WIP 和提供方,然后根据特定的工作负载容器映像摘要设置 IAM 角色。

设置 WIP 和提供方

如需设置 WIP 和提供方,请完成以下说明:

  1. 创建 WIP:

    gcloud iam workload-identity-pools create DATA_COLLABORATOR_POOL_NAME \
        --location=global
    
  2. 在 WIP 中创建 OIDC 提供方:

    gcloud iam workload-identity-pools providers create-oidc attestation-verifier \
        --location=global \
        --workload-identity-pool=DATA_COLLABORATOR_POOL_NAME \
        --issuer-uri="https://confidentialcomputing.googleapis.com/" \
        --allowed-audiences="https://sts.googleapis.com" \
        --attribute-mapping="google.subject=\"gcpcs::\"+assertion.submods.container.image_digest+\"::\"+assertion.submods.gce.project_number+\"::\"+assertion.submods.gce.instance_id,attribute.image_digest=assertion.submods.container.image_digest" \
        --attribute-condition="assertion.swname == 'CONFIDENTIAL_SPACE' \
            && 'STABLE' in assertion.submods.confidential_space.support_attributes"
    

    此示例使用以下值:

    • issuer-urihttps://confidentialcomputing.googleapis.com/,表示使用 Google Cloud 证明作为证明服务。

    • https://sts.googleapis.comallowed-audiences。这是 Google 的 Security Token Service,用于将凭据交换为访问令牌。

    • 值为 google.subjectattribute-mapping,具有以下值:

      \"gcpcs::\"+assertion.submods.container.image_digest+\"::\"+assertion.submods.gce.project_number+\"::\"+assertion.submods.gce.instance_id,attribute.image_digest=assertion.submods.container.image_digest
      

      此值是使用通用表达式语言 (CEL) 构建的。以下值会分配给 gcpcs 属性,并在工作负载访问资源时显示在 Cloud Logging 中:

      • assertion.submods.container.image_digest:工作负载容器映像摘要。

      • assertion.submods.gce.project_number:虚拟机实例的项目编号。

      • assertion.submods.gce.instance_id:虚拟机实例的 ID。

      此外,attribute.image_digest 设置为 assertion.submods.container.image_digest,即工作负载容器映像摘要。此属性经过映射,因此您可以根据特定映像摘要向联合身份授予 IAM 角色

      您可以映射任何可用的工作负载断言,只要 google.subject 值的总长度小于 127 字节即可。

    • 以下 attribute-conditions 构成证明政策。如果这些条件与工作负载的断言相符,则允许工作负载以联合身份访问机密资源:

      • assertion.swname == 'CONFIDENTIAL_SPACE':验证 Confidential Space 是否是虚拟机上运行的软件,并具有所有内置安全保证

      • 'STABLE' in assertion.submods.confidential_space.support_attributes: 验证是否使用了生产 Confidential Space 映像,以及该映像是否具有 STABLE 支持属性

      如需了解可使用的更多属性条件,请参阅创建证明政策

向联合身份授予 IAM 角色

创建 WIP 提供方后,您可以根据联合身份的工作负载映像容器摘要是否与预期值匹配,向该身份授予 IAM 角色。

以下示例演示了如何向联合身份授予解密特定 Cloud Key Management Service 密钥的权限:

gcloud kms keys add-iam-policy-binding \
    projects/DATA_COLLABORATOR_PROJECT_ID/locations/global/keyRings/DATA_COLLABORATOR_KEYRING_NAME/cryptoKeys/DATA_COLLABORATOR_KEY_NAME \
    --member="principalSet://iam.googleapis.com/projects/DATA_COLLABORATOR_PROJECT_NUMBER/locations/global/workloadIdentityPools/DATA_COLLABORATOR_POOL_NAME/attribute.image_digest/WORKLOAD_CONTAINER_IMAGE_DIGEST" \
    --role=roles/cloudkms.cryptoKeyDecrypter

服务账号模拟

服务账号模拟方法涉及以下步骤:

  1. 在每个数据协作者项目中创建服务账号,并授予这些服务账号解密保密数据的权限。

  2. 在每个数据协作方项目中创建 WIP,然后将刚刚创建的每个项目的服务账号附加到其 WIP。

  3. 在每个 WIP 中创建 WIP 提供程序,将工作负载服务账号指定为允许模拟数据协作者服务账号的账号。

设置服务账号以解密机密数据

  1. 在数据协作者项目中创建服务账号:

    gcloud iam service-accounts create DATA_COLLABORATOR_SERVICE_ACCOUNT_NAME
    

    向服务账号授予解密机密数据所需的权限。例如,您可以使用 Cloud KMS 对 Cloud Storage 中的机密文件进行加密,因此需要向服务账号授予解密相应数据的权限:

    gcloud kms keys add-iam-policy-binding \
        projects/DATA_COLLABORATOR_PROJECT_ID/locations/global/keyRings/DATA_COLLABORATOR_KEYRING_NAME/cryptoKeys/DATA_COLLABORATOR_KEY_NAME \
        --member=serviceAccount:DATA_COLLABORATOR_SERVICE_ACCOUNT_NAME@DATA_COLLABORATOR_PROJECT_ID.iam.gserviceaccount.com \
        --role=roles/cloudkms.cryptoKeyDecrypter
    

设置 WIP 和提供方

如需设置 WIP 和提供方,请在每个数据协作方项目中完成以下说明:

  1. 创建 WIP:

    gcloud iam workload-identity-pools create DATA_COLLABORATOR_POOL_NAME \
        --location=global
    
  2. 将要冒充的服务账号附加到 WIP,并授予 roles/iam.workloadIdentityUser 角色:

    gcloud iam service-accounts add-iam-policy-binding \
        DATA_COLLABORATOR_SERVICE_ACCOUNT_NAME@DATA_COLLABORATOR_PROJECT_ID.iam.gserviceaccount.com \
        --member="principalSet://iam.googleapis.com/projects/DATA_COLLABORATOR_PROJECT_NUMBER/locations/global/workloadIdentityPools/DATA_COLLABORATOR_POOL_NAME/*" \
        --role=roles/iam.workloadIdentityUser
    
  3. 在 WIP 中创建 OIDC 提供方,并在其中定义工作负载服务账号,以便该账号可以模拟数据协作者服务账号:

    gcloud iam workload-identity-pools providers create-oidc attestation-verifier \
        --location=global \
        --workload-identity-pool=DATA_COLLABORATOR_POOL_NAME \
        --issuer-uri="https://confidentialcomputing.googleapis.com/" \
        --allowed-audiences="https://sts.googleapis.com" \
        --attribute-mapping="google.subject=assertion.sub" \
        --attribute-condition="assertion.submods.container.image_digest == 'WORKLOAD_CONTAINER_IMAGE_DIGEST' \
    && 'WORKLOAD_SERVICE_ACCOUNT_NAME@WORKLOAD_OPERATOR_PROJECT_ID.iam.gserviceaccount.com' in assertion.google_service_accounts \
    && assertion.swname == 'CONFIDENTIAL_SPACE' \
    && 'STABLE' in assertion.submods.confidential_space.support_attributes"
    

    此示例使用以下值:

    • issuer-urihttps://confidentialcomputing.googleapis.com/,表示使用 Google Cloud 证明作为证明服务。

    • https://sts.googleapis.comallowed-audiences。这是 Google 的 Security Token Service,用于将凭据交换为访问令牌。

    • 值为 assertion.subgoogle.subject attribute-mapping。这是虚拟机实例的 selfLink,如证明令牌中的 sub 声明所定义。

      每当工作负载访问资源时,Cloud Logging 中都会显示虚拟机实例 selfLink

    • 以下 attribute-conditions 构成证明政策。如果这些条件与工作负载的断言相符,则允许工作负载以联合身份访问资源:

      • assertion.submods.container.image_digest == 'WORKLOAD_CONTAINER_IMAGE_DIGEST':验证工作负载容器映像摘要是否与预期值一致。

      • 'WORKLOAD_SERVICE_ACCOUNT_NAME@WORKLOAD_PROJECT_ID.iam.gserviceaccount.com' in assertion.google_service_accounts:验证附加到工作负载的服务账号是否与预期服务账号匹配,然后使用该服务账号模拟数据协作者服务账号。

      • assertion.swname == 'CONFIDENTIAL_SPACE':验证 Confidential Space 是否是虚拟机上运行的软件,并具有所有内置安全保证

      • 'STABLE' in assertion.submods.confidential_space.support_attributes: 验证是否使用了生产 Confidential Space 映像,以及该映像是否具有 STABLE 支持属性

      如需了解可使用的更多属性条件,请参阅创建证明政策

创建证明政策

在创建 WIP 的过程中,您需要创建证明政策。身份验证实体的断言必须与您的政策相符,才能访问您的数据。

政策采用通用表达式语言 (CEL) 编写,并由一系列可使用 && 运算符链接的语句组成。

这些语句使用 Confidential Space 映像、工作负载容器映像或虚拟机实例中的断言作为变量,并使用您指定的值作为表达式。例如,以下政策强制规定工作负载必须使用 Confidential Space,必须使用 STABLE Confidential Space 映像,并且工作负载虚拟机实例运行的可用区必须为 us-central1-a

assertion.swname == 'CONFIDENTIAL_SPACE' \
&& 'STABLE' in assertion.submods.confidential_space.support_attributes" \
&& assertion.submods.gce.zone == "us-central1-a"

如需了解详情,请参阅证明断言

证明断言

下表详细介绍了构建证明政策的可用断言。政策可以验证 Confidential Space 映像、工作负载容器和虚拟机实例做出的断言。

图片断言

断言 类型 说明

assertion.dbgstat

互动对象

已定义的字符串

验证 Confidential Space 映像是调试版本还是生产版本。

有效值包括:

  • enable:检查是否使用了调试映像。
  • disabled-since-boot:检查是否正在使用生产映像。
示例

以下代码验证是否使用了调试版本的 Confidential Space 映像:

assertion.dbgstat == "enable"

以下代码验证是否使用了生产版本的 Confidential Space 映像:

assertion.dbgstat == "disabled-since-boot"
assertion.submods.confidential_space.support_attributes 字符串数组

验证 TEE 的安全版本是否为生产 Confidential Space 映像。调试 Confidential Space 映像没有设置支持特性。

有三种支持特性:

  • LATEST:这是最新版本的映像,受支持。LATEST 映像同时也是 STABLEUSABLE
  • STABLE:此版本的映像受支持,并且我们会监控其漏洞情况。STABLE 映像同时也是 USABLE
  • USABLE:仅包含此特性的映像已不再受支持,并且我们不会再监控其漏洞情况。使用时需自行承担风险。
  • EXPERIMENTAL:仅具有此属性的图片会使用预览功能。此渠道仅用于测试目的,绝不应在生产环境中使用。EXPERIMENTAL 图片永远不会具有 LATESTSTABLEUSABLE 属性。
示例

以下代码验证是否使用了稳定版本的 Confidential Space 映像:

"STABLE" in assertion.submods.confidential_space.support_attributes
assertion.swname 已定义的字符串

验证在证明实体上运行的软件。值始终为 CONFIDENTIAL_SPACE

示例
assertion.swname == "CONFIDENTIAL_SPACE"
assertion.swversion 字符串数组

验证 Confidential Space 映像的软件版本。建议使用 assertion.submods.confidential_space.support_attributes 来定位映像的最新版本。

示例
int(assertion.swversion[0]) == 230103

容器断言

断言 类型 说明

assertion.submods.container.cmd_override

互动对象

字符串数组

验证工作负载映像中使用的 CMD 命令和参数。

示例

以下代码验证了工作负载映像的 CMD 是否未被覆盖:

size(assertion.submods.container.cmd_override) == 0

以下代码验证 program 是 CMD 覆盖中的唯一内容:

assertion.submods.container.cmd_override == ['program']

assertion.submods.container.env

互动对象

JSON 对象

验证环境变量及其值是否已明确传递给容器。

示例

以下代码验证了环境变量 example-env-1 是否设置为 value-1,以及 example-env-2 是否设置为 value-2

assertion.submods.container.env == {"example-env-1": "value-1", "example-env-2": "value-2"}

assertion.submods.container.env_override

互动对象

字符串

验证工作负载 operator 是否覆盖了容器中的环境变量。

示例

以下代码用于验证工作负载运算符是否未替换 example 环境变量:

!has(assertion.submods.container.env_override.example)

以下代码可验证工作负载运算符是否未覆盖任何环境变量:

size(assertion.submods.container.env_override) == 0
assertion.submods.container.image_digest 字符串

验证工作负载容器的映像摘要。指定此条件可让多方就允许访问其数据的授权工作负载达成共识。

示例
assertion.submods.container.image_digest == "sha256:837ccb607e312b170fac7383d7ccfd61fa5072793f19a25e75fbacb56539b86b"
assertion.submods.container.image_id 字符串

验证工作负载容器的映像 ID。

示例
assertion.submods.container.image_id == "sha256:652a44b0e911271ba07cf2915cd700fdfa50abd62a98f87a57fdebc59843d93f"

assertion.submods.container.image_reference

互动对象

字符串

验证在 Confidential Space 映像上运行的工作负载容器的位置。

示例
assertion.submods.container.image_reference == "us-docker.pkg.dev/PROJECT_ID/WORKLOAD_CONTAINER:latest"

assertion.submods.container.image_signatures

互动对象

JSON 对象

验证映像是否具有特定签名或是否由公钥和签名算法签名。指定此条件可让多方就允许访问其数据的授权工作负载达成共识。

断言可以包含以下元素:

  • key_id:公钥的十六进制指纹。如需获取指纹,您可以运行以下命令:

    openssl pkey -pubin -in public_key.pem -outform DER | openssl sha256

    其中,public_key.pem 是您的 PEM 格式的公钥。

  • signature:与签名容器关联且遵循 简单签名格式的载荷的签名。
  • signature_algorithm:用于对密钥进行签名的算法。以下项之一:

    • RSASSA_PSS_SHA256(具有 SHA-256 摘要的 RSASSA-PSS)
    • RSASSA_PKCS1V15_SHA256(具有 SHA-256 摘要的 RSASSA-PKCS1 v1_5)
    • ECDSA_P256_SHA256(具有 SHA-256 摘要的 P-256 曲线上的 ECDSA)
示例
assertion.swname == 'CONFIDENTIAL_SPACE' && ['ECDSA_P256_SHA256:PUBLIC_KEY_FINGERPRINT'].exists(fingerprint, fingerprint in assertion.submods.container.image_signatures.map(sig, sig.signature_algorithm+':'+sig.key_id)) && 'serviceaccount.iam.gserviceaccount.com' in assertion.google_service_accounts"

assertion.submods.container.restart_policy

互动对象

已定义的字符串

验证工作负载停止时容器启动器的重启政策。

有效值包括:

  • Never(默认)
  • Always
  • OnFailure
示例
assertion.submods.container.restart_policy == "Never"

虚拟机断言

断言 类型 说明

assertion.google_service_accounts

互动对象

字符串数组

验证指定的服务账号是否已关联到运行工作负载的虚拟机,或者是否已使用虚拟机元数据中的 tee-impersonate-service-accounts 列出。

示例
workload-service-account@my-project.iam.gserviceaccount.com in assertion.google_service_accounts
assertion.hwmodel 字符串

验证底层机密计算技术。支持的平台如下:

  • GCP_AMD_SEV
  • INTEL_TDX
示例
assertion.hwmodel == "GCP_AMD_SEV"

assertion.submods.confidential_space.monitoring_enabled

互动对象

布尔值

验证证明实体上的监控状态。

示例
assertion.submods.confidential_space.monitoring_enabled.memory == true
assertion.submods.gce.instance_id 字符串

验证虚拟机实例 ID。

示例
assertion.submods.gce.instance_id == "0000000000000000000"
assertion.submods.gce.instance_name 字符串

验证虚拟机实例的名称。

示例
assertion.submods.gce.instance_name == "workload-vm"
assertion.submods.gce.project_id 字符串

验证虚拟机是否正在运行具有指定项目 ID 的 Google Cloud 项目。

示例
assertion.submods.gce.project_id == "project-id"
assertion.submods.gce.project_number 字符串

验证虚拟机是否在具有指定项目编号的 Google Cloud 项目中运行。

示例
assertion.submods.gce.project_number == "00000000000"

assertion.submods.gce.zone

互动对象

  • 工作负载运算符 --zone 值。
字符串

验证虚拟机是否正在指定可用区中运行。

示例
assertion.submods.gce.zone == "us-central1-a"

assertion.submods.nvidia_gpu.cc_mode

互动对象

已定义的字符串

验证 NVIDIA 的机密计算驱动程序的状态。 有效值包括:

  • OFF:未启用任何 NVIDIA 机密计算功能。
  • ON:NVIDIA H100 硬件、固件和软件已完全激活机密计算功能。
  • DEVTOOLS:GPU 处于部分机密计算模式,该模式与 ON 模式的工作流程相匹配,但会停用安全保护措施。
示例
assertion.submods.nvidia_gpu.cc_mode == "ON"