1. 概览
准备好提升 GPU 加速工作负载的安全性和隐私权了吗?此 Codelab 将引导您了解可信空间的功能,该产品可为您的敏感 AI/机器学习工作负载提供强大的操作员隔离和加速器支持。
保护有价值的数据、模型和密钥比以往任何时候都更加重要。Trusted Space 提供了一种解决方案,可确保您的工作负载在安全可信的环境中运行,即使是工作负载操作员也无法访问。
可信空间提供以下功能:
- 增强了隐私权和安全性:可信空间提供了一个可信的执行环境,可信空间由加密证明提供支持,可确保您的敏感资产(例如模型、宝贵的数据和密钥)受到保护。
- 操作员隔离:消除对操作员干扰的担忧。借助可信空间,即使是工作负载操作员也无法访问,从而防止他们通过 SSH 连接、访问数据、安装软件或篡改您的代码。
- 加速器支持:Trusted Space 旨在与各种硬件加速器(包括 H100、A100、T4 和 L4 等 GPU)无缝协作。这可确保性能关键型 AI/ML 应用顺畅运行。
学习内容
- 了解可信空间的主要功能。
- 了解如何部署和配置可信空间环境,以保护 AI/ML 工作负载的宝贵资产。
所需条件
- 一个 Google Cloud Platform 项目
- 具备 Google Compute Engine 和加速器方面的基础知识。
- 具备服务账号、密钥管理、工作负载身份联合和属性条件方面的基本知识。
- 具备 容器和 Artifact Registry 方面的基础知识
使用 Primus Company 保护敏感的代码生成提示
在此 Codelab 中,我们将扮演 Primus 的角色。Primus 是一家非常重视员工数据隐私和安全的公司。Primus 希望部署一个代码生成模型,以帮助其开发者完成编码任务。不过,他们担心员工提交的提示的保密性,因为这些提示通常包含敏感的代码段、内部项目详细信息或专有算法。
为什么 Primus 公司不信任运营商?
Primus Corp 在竞争激烈的市场中运营。其代码库包含宝贵的知识产权,包括专有算法和敏感的代码段,可提供竞争优势。他们担心工作负载运营商可能会进行商业间谍活动。此外,员工提示可能包含 Primus Corp 希望保护的机密“需要了解”部分的代码。
为解决此问题,Primus Corp 将利用可信空间来隔离运行代码生成模型的推理服务器。具体操作过程如下:
- 提示加密:在将提示发送到推理服务器之前,每位员工都会使用 Google Cloud 中由 Primus Corp 管理的 KMS 密钥对其进行加密。这样可确保只有可信空间环境(其中提供相应的解密密钥)才能解密该提示并访问明文提示。在实际应用场景中,客户端加密可以由可用的库(例如 tink)处理。在此 Codelab 中,我们将使用此示例客户端应用进行信封加密。
- 运营商隔离:只有在可信空间环境中运行的推理服务器才能访问用于加密的密钥,并且能够在可信环境中解密提示。加密密钥的访问权限将受到工作负载身份池的保护。由于可信空间具有隔离保证,即使是工作负载操作员也无法访问用于加密的密钥和解密后的内容。
- 使用加速器的安全推理:推理服务器将在安全强化型虚拟机上启动(作为可信空间设置的一部分),这将确保工作负载实例不会受到启动级或内核级恶意软件或 rootkit 的攻击。该服务器会在可信空间环境中解密提示,使用代码生成模型执行推理,并将生成的代码返回给员工。
2. 设置 Cloud 资源
准备工作
- 使用以下命令克隆 此代码库,以获取用作此 Codelab 一部分的必需脚本。
git clone https://github.com/GoogleCloudPlatform/confidential-space.git
- 更改此 Codelab 的目录。
cd confidential-space/codelabs/trusted_space_codelab/scripts
- 确保您已设置必需的项目环境变量,如下所示。如需详细了解如何设置 GCP 项目,请参阅 此 Codelab。您可以参阅这篇文章,详细了解如何检索项目 ID,以及项目 ID 与项目名称和项目编号有何不同。
export PRIMUS_PROJECT_ID=<GCP project id of Primus>
- 为您的项目启用结算功能。
- 为这两个项目启用 Confidential Computing API 和以下 API。
gcloud services enable \
cloudapis.googleapis.com \
cloudresourcemanager.googleapis.com \
cloudkms.googleapis.com \
cloudshell.googleapis.com \
container.googleapis.com \
containerregistry.googleapis.com \
iam.googleapis.com \
confidentialcomputing.googleapis.com
- 使用以下命令为上述资源名称的变量分配值。借助这些变量,您可以根据需要自定义资源名称,还可以使用已创建的现有资源。(例如
export PRIMUS_SERVICE_ACCOUNT='my-service-account')
- 您可以使用 Primus 项目中的现有云资源名称设置以下变量。如果设置了该变量,则会使用 Primus 项目中相应的现有云资源。如果未设置该变量,系统会根据项目名称生成云资源名称,并使用该名称创建新的云资源。以下是资源名称支持的变量:
| Primus 公司的区域资源将在哪个区域下创建。 |
| Primus 公司的资源将创建在哪个位置。 |
| Primus 公司的可用区级资源将在哪个可用区下创建。 |
| Primus 公司的 Workload Identity 池,用于保护云资源。 |
| Primus 公司的 Workload Identity Pool 提供商,其中包含用于由证明验证器服务签名的令牌的授权条件。 |
| Primus 公司的服务账号, |
| KMS 密钥用于加密 Primus 公司员工提供的提示。 |
| 将用于为 Primus 公司创建加密密钥 |
| 加密密钥 |
| 将推送工作负载 Docker 映像的制品库。 |
| 制品库的区域,其中包含已发布的工作负载 Docker 映像。 |
| 工作负载虚拟机的名称。 |
| 工作负载 Docker 映像的名称。 |
| 工作负载容器映像的标记。 |
| 有权访问运行工作负载的保密虚拟机的服务账号。 |
| 将运行推理服务器的客户端应用的客户端虚拟机的名称。 |
|
|
- 您需要拥有项目
$PRIMUS_PROJECT_ID的 Storage Admin、Artifact Registry Administrator、Cloud KMS Admin、Service Account Admin、IAM Workload Identity Pool Admin 角色。您可以参阅本指南,了解如何使用 GCP 控制台授予 IAM 角色。 - 对于
$PRIMUS_PROJECT_ID,请运行以下脚本,以根据您的项目 ID 为资源名称设置剩余的变量名称值。
source config_env.sh
设置 Primus Company 资源
在此步骤中,您将为 Primus 设置所需的云资源。运行以下 脚本以设置 Primus 的资源。在执行脚本时,系统会创建以下资源:
- KMS 中的加密密钥 (
$PRIMUS_ENC_KEY) 和密钥环 ($PRIMUS_ENC_KEYRING),用于加密 Primus 公司的客户数据文件。 - 工作负载身份池 (
$PRIMUS_WORKLOAD_IDENTITY_POOL),用于根据其提供方下配置的属性条件验证声明。 - 附加到上述工作负载身份池 (
$PRIMUS_WORKLOAD_IDENTITY_POOL) 的服务账号 ($PRIMUS_SERVICE_ACCOUNT) 具有以下权限:使用 KMS 密钥解密数据(使用roles/cloudkms.cryptoKeyDecrypter角色)、使用 KMS 密钥加密数据(使用roles/cloudkms.cryptoKeyEncrypter角色)、从 Cloud Storage 存储分区读取数据(使用objectViewer角色),以及将服务账号连接到工作负载身份池(使用roles/iam.workloadIdentityUser)。
./setup_primus_resources.sh
3. 创建工作负载
创建工作负载服务账号
现在,您将为工作负载创建一个具有所需角色和权限的服务账号。运行以下脚本,在 Primus 项目中创建工作负载服务账号。此服务账号将由运行推理服务器的虚拟机使用。
此工作负载服务账号 ($WORKLOAD_SERVICEACCOUNT) 将具有以下角色:
confidentialcomputing.workloadUser以获取证明令牌logging.logWriter以将日志写入 Cloud Logging。
./create_workload_service_account.sh
创建工作负载
在此步骤中,您将创建一个工作负载 Docker 映像。工作负载将由 Primus 公司创建。本 Codelab 中使用的工作负载是 Python 代码,该代码使用公开提供的 GCS 存储分区(Vertex 模型园)中的 codegemma 模型。工作负载将加载 codegemma 模型并启动推理服务器,该服务器将处理来自 Primus 开发者的代码生成请求。
在代码生成请求中,工作负载将获取封装的 DEK 以及加密的提示。然后,工作负载将调用 KMS API 来解密 DEK,并使用此 DEK 解密提示。加密密钥(针对 DEK)将通过工作负载身份池受到保护,并且只有满足属性条件的工作负载才能获得访问权限。下一部分将更详细地介绍这些属性条件,其中涉及工作负载授权。推理服务器获得解密的提示后,会使用已加载的模型生成代码,然后返回响应。
运行以下脚本以创建工作负载,其中执行以下步骤:
- 创建由 Primus 拥有的 Artifact Registry(
$PRIMUS_ARTIFACT_REGISTRY)。 - 使用所需的资源名称更新工作负载代码。
- 构建推理服务器工作负载,并创建 Dockerfile 以构建工作负载代码的 Docker 映像。此处是此 Codelab 使用的 Dockerfile。
- 构建 Docker 映像并将其发布到 Primus 拥有的 Artifact Registry (
$PRIMUS_ARTIFACT_REGISTRY)。 - 为
$PRIMUS_ARTIFACT_REGISTRY授予$WORKLOAD_SERVICEACCOUNT读取权限。这是工作负载容器从 Artifact Registry 中拉取工作负载 Docker 映像所必需的。
./create_workload.sh
为供您参考,以下是此 Codelab 中创建和使用的工作负载的 generate() 方法(您可以在此处找到完整的工作负载代码)。
def generate():
try:
data = request.get_json()
ciphertext = base64.b64decode(data["ciphertext"])
wrapped_dek = base64.b64decode(data["wrapped_dek"])
unwrapped_dek_response = kms_client.decrypt(
request={"name": key_name, "ciphertext": wrapped_dek}
)
unwrapped_dek = unwrapped_dek_response.plaintext
f = Fernet(unwrapped_dek)
plaintext = f.decrypt(ciphertext)
prompt = plaintext.decode("utf-8")
tokens = tokenizer(prompt, return_tensors="pt")
outputs = model.generate(**tokens, max_new_tokens=128)
generated_code = tokenizer.decode(outputs[0])
generated_code_bytes = generated_code.encode("utf-8")
response = f.encrypt(generated_code_bytes)
ciphertext_base64 = base64.b64encode(response).decode("utf-8")
response = {"generated_code_ciphertext": ciphertext_base64}
return jsonify(response)
except (ValueError, TypeError, KeyError) as e:
return jsonify({"error": str(e)}), 500
4. 授权并运行工作负载
授权工作负载
Primus 希望根据以下资源的属性,授权工作负载访问其用于提示加密的 KMS 密钥:
- 内容:已验证的代码
- 地点:安全的环境
- 谁:受信任的运营商
Primus 使用工作负载身份联合来根据这些要求强制执行访问政策。借助工作负载身份联合,您可以指定特性条件。这些条件用于限制哪些身份可以使用工作负载身份池 (WIP) 进行身份验证。您可以将证明验证器服务作为工作负载身份池提供方添加到 WIP,以提供测量结果并强制执行政策。
工作负载身份池已在之前作为云资源设置步骤的一部分创建。现在,Primus 将创建一个新的 OIDC 工作负载身份池提供方。指定的 --attribute-condition 授权对工作负载容器的访问权限。它需要:
- 内容:最新
$WORKLOAD_IMAGE_NAME已上传到$PRIMUS_ARTIFACT_REPOSITORY代码库。 - 其中:Confidential Space 可信执行环境在完全受支持的 Confidential Space 虚拟机映像上运行。
- 谁:Primus
$WORKLOAD_SERVICE_ACCOUNT服务账号。
export WORKLOAD_IMAGE_DIGEST=$(gcloud artifacts docker images describe ${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/$PRIMUS_PROJECT_ID/$PRIMUS_ARTIFACT_REPOSITORY/$WORKLOAD_IMAGE_NAME:$WORKLOAD_IMAGE_TAG --format="value(image_summary.digest)" --project ${PRIMUS_PROJECT_ID})
gcloud iam workload-identity-pools providers create-oidc $PRIMUS_WIP_PROVIDER \
--location="global" \
--project="$PRIMUS_PROJECT_ID" \
--workload-identity-pool="$PRIMUS_WORKLOAD_IDENTITY_POOL" \
--issuer-uri="https://confidentialcomputing.googleapis.com/" \
--allowed-audiences="https://sts.googleapis.com" \
--attribute-mapping="google.subject='assertion.sub'" \
--attribute-condition="assertion.swname == 'HARDENED_SHIELDED' && assertion.hwmodel == 'GCP_SHIELDED_VM' &&
assertion.submods.container.image_digest == '${WORKLOAD_IMAGE_DIGEST}' &&
assertion.submods.container.image_reference == '${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/$PRIMUS_PROJECT_ID/$PRIMUS_ARTIFACT_REPOSITORY/$WORKLOAD_IMAGE_NAME:$WORKLOAD_IMAGE_TAG' &&
'$WORKLOAD_SERVICEACCOUNT@$PRIMUS_PROJECT_ID.iam.gserviceaccount.com' in assertion.google_service_accounts"
上述命令通过检查 hwmodel 是否设置为“GCP_SHIELDED_VM”以及 swname 是否设置为“HARDENED_SHIELDED”,来验证工作负载是否在可信空间环境中运行。此外,它还包含工作负载特定的断言(例如 image_digest 和 image_reference),以增强安全性并确保运行的工作负载的完整性。
运行工作负载
在此步骤中,我们将在附加了加速器的可信空间虚拟机中运行工作负载。必需的 TEE 实参通过 元数据标志传递。工作负载容器的实参通过标志的“tee-cmd”部分传递。为了让工作负载虚拟机配备 Nvidia Tesla T4 GPU,我们将使用 --accelerator=type=nvidia-tesla-t4,count=1 标志。这会将一个 GPU 挂接到虚拟机。我们还需要在元数据标志中添加 tee-install-gpu-driver=true,以触发相应 GPU 驱动程序的安装。
gcloud compute instances create ${WORKLOAD_VM} \
--accelerator=type=nvidia-tesla-t4,count=1 \
--machine-type=n1-standard-16 \
--shielded-secure-boot \
--image-project=conf-space-images-preview \
--image=confidential-space-0-gpupreview-796705b \
--zone=${PRIMUS_PROJECT_ZONE} \
--maintenance-policy=TERMINATE \
--boot-disk-size=40 \
--scopes=cloud-platform \
--service-account=${WORKLOAD_SERVICEACCOUNT}@${PRIMUS_PROJECT_ID}.iam.gserviceaccount.com \
--metadata="^~^tee-image-reference=${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/${PRIMUS_PROJECT_ID}/${PRIMUS_ARTIFACT_REPOSITORY}/${WORKLOAD_IMAGE_NAME}:${WORKLOAD_IMAGE_TAG}~tee-install-gpu-driver=true~tee-restart-policy=Never"
运行推理查询
工作负载推理服务器成功启动后,Primus 公司的员工现在可以向推理服务器发送代码生成请求。
在此 Codelab 中,我们将使用以下脚本来设置将与推理服务器交互的客户端应用。运行此脚本以设置客户端虚拟机。
./setup_client.sh
以下步骤演示了如何通过 SSH 登录到客户端虚拟机,并在 Python 虚拟环境中执行示例客户端应用。此示例应用使用 Fernet 库进行信封加密,但请注意,您可以根据不同的使用情形调整具体的加密库。
gcloud compute ssh ${CLIENT_VM} --zone=${PRIMUS_PROJECT_ZONE}
运行以下命令以在客户端虚拟机中激活 Python 虚拟环境并执行客户端应用。
source venv/bin/activate
python3 inference_client.py
此示例客户端应用的输出将显示加密和纯文本提示请求,以及相应的加密和解密响应。
5. 清理
点击此处可查看用于清理我们在本 Codelab 中创建的资源的脚本。在此清理过程中,系统将删除以下资源:
- Primus 服务账号 (
$PRIMUS_SERVICEACCOUNT)。 - Primus 加密密钥 (
$PRIMUS_ENC_KEY)。 - Primus 的制品库 (
$PRIMUS_ARTIFACT_REPOSITORY)。 - Primus 工作负载身份池 (
$PRIMUS_WORKLOAD_IDENTITY_POOL) 及其提供方。 - Primus 的工作负载服务账号 (
$WORKLOAD_SERVICEACCOUNT)。 - 工作负载虚拟机 (
$WORKLOAD_VM) 和客户端虚拟机 ($CLIENT_VM)。
./cleanup.sh
如果您已完成探索,请考虑删除项目。
- 前往 Cloud Platform 控制台
- 选择要关停的项目,然后点击顶部的“删除”:系统会安排删除该项目