Trusted Space 程式碼研究室

1. 總覽

準備好提升 GPU 加速工作負載的安全性和隱私權了嗎?本程式碼研究室將引導您瞭解 Trusted Space 的功能,這項服務可為機密 AI/ML 工作負載提供強大的運算子隔離和加速器支援。

保護有價值的資料、模型和金鑰比以往更為重要。Trusted Space 提供的解決方案,可確保工作負載在安全可靠的環境中執行,即使工作負載操作員也無法存取。

Trusted Space 提供以下功能:

  • 強化隱私權和安全性:Trusted Space 提供受信任的執行環境,可透過加密編譯證明,保護您的機密資產 (例如模型、重要資料和金鑰)。
  • 操作員隔離:不必擔心操作員干擾問題。有了信任空間,即使工作負載操作員也無法存取,因此無法透過 SSH 存取資料、安裝軟體或竄改程式碼。
  • 加速器支援:Trusted Space 可與多種硬體加速器完美搭配運作,包括 H100、A100、T4 和 L4 等 GPU。確保效能至關重要的 AI/機器學習應用程式順暢運作。

課程內容

  • 瞭解 Trusted Space 的主要服務。
  • 瞭解如何部署及設定信任空間環境,保護 AI/ML 工作負載中的寶貴資產。

軟硬體需求

使用 Primus Company 保護機密的程式碼產生提示

在本程式碼研究室中,我們將扮演 Primus 的角色,該公司會優先考量員工資料的隱私權和安全性。Primus 希望部署程式碼產生模型,協助開發人員處理程式設計工作。不過,他們擔心無法保護員工提交的提示內容機密性,因為這些提示內容通常包含敏感程式碼片段、內部專案詳細資料或專屬演算法。

為什麼 Primus 公司不信任經銷商?

Primus Corp 在競爭激烈的市場中營運,他們的程式碼集包含寶貴的智慧財產,包括專屬演算法和敏感程式碼片段,可提供競爭優勢。他們擔心工作負載作業人員可能會從事企業間諜活動。此外,員工提示可能會包含 Primus Corp 想保護的機密「Need To Know」程式碼部分。

為解決這個問題,Primus Corp 將利用信任空間,隔離執行模型的推論伺服器,以便產生程式碼。運作方式如下:

  • 提示加密:在向推論伺服器傳送提示之前,每位員工都會使用 Primus Corp 在 Google Cloud 中管理的 KMS 金鑰加密提示。這可確保只有可信任空間環境 (提供對應的解密金鑰) 才能解密並存取明文提示。在實際使用情況中,用戶端加密作業可由可用的程式庫 (例如 tink) 處理。在本程式碼研究室中,我們會使用這個範例用戶端應用程式,並搭配信封加密功能。
  • 操作員隔離:只有在信任空間環境中執行的推論伺服器,才能存取用於加密的金鑰,並在信任環境中解密提示。加密金鑰的存取權將受到 Workload Identity 集區的保護。由於 Trusted Space 可保證隔離,即使是工作負載操作員也無法存取用於加密的金鑰和解密內容。
  • 使用加速器進行安全推論:推論伺服器會在受防護的 VM 上啟動 (做為信任空間設定的一部分),確保工作負載執行個體未遭受啟動或核心層級的惡意軟體Rootkit 入侵。這項伺服器會在受信任空間環境中解密提示,使用程式碼產生模型執行推論,並將產生的程式碼傳回給員工。

2. 設定雲端資源

事前準備

  • 使用下列指令複製 這個存放區,取得用於本程式碼研究室的必要指令碼。
git clone https://github.com/GoogleCloudPlatform/confidential-space.git
  • 變更本程式碼研究室的目錄。
cd confidential-space/codelabs/trusted_space_codelab/scripts
  • 請確認您已設定必要的專案環境變數,如下所示。如要進一步瞭解如何設定 GCP 專案,請參閱 這個程式碼研究室。您可以參閱這篇文章,進一步瞭解如何擷取專案 ID,以及專案 ID 與專案名稱和專案編號的差異。
export PRIMUS_PROJECT_ID=<GCP project id of Primus>
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')
  1. 您可以使用 Primus 專案中現有的雲端資源名稱設定下列變數。如果變數已設定,系統會使用 Primus 專案中對應的現有雲端資源。如果未設定變數,系統會根據專案名稱產生雲端資源名稱,並以該名稱建立新的雲端資源。以下是支援的資源名稱變數:

$PRIMUS_PROJECT_REGION

要為 Primus 公司建立區域資源的區域。

$PRIMUS_SERVICE_LOCATION

要為 Primus 公司建立資源的位置。

$PRIMUS_PROJECT_ZONE

系統會為 Primus 公司在這個區域建立區域資源。

$PRIMUS_WORKLOAD_IDENTITY_POOL

Primus 公司的 Workload Identity Pool,用於保護雲端資源。

$PRIMUS_WIP_PROVIDER

Primus 公司的 Workload Identity Pool 供應商,其中包含驗證條件,可用於由驗證工具驗證服務簽署的權杖。

$PRIMUS_SERVICEACCOUNT

Primus 公司用來存取受保護資源的服務帳戶。$PRIMUS_WORKLOAD_IDENTITY_POOL在這個步驟中,它有權查看儲存在 $PRIMUS_INPUT_STORAGE_BUCKET 儲存桶中的客戶資料。

$PRIMUS_ENC_KEY

KMS 金鑰用於加密 Primus 公司員工提供的提示。

$PRIMUS_ENC_KEYRING

用於為 Primus 公司建立加密金鑰 $PRIMUS_ENC_KEY 的 KMS 鑰匙圈。

$PRIMUS_ENC_KEYVERSION

加密金鑰 $PRIMUS_ENC_KEY 的 KMS 金鑰版本。預設值為 1。如果您使用的是先前已輪替過的現有鍵,且該鍵的版本已更新,請更新此值。

$PRIMUS_ARTIFACT_REPOSITORY

工作負載 Docker 映像檔會推送至的構件存放區。

$PRIMUS_PROJECT_REPOSITORY_REGION

包含已發布工作負載 Docker 映像檔的構件存放區區域。

$WORKLOAD_VM

工作負載 VM 的名稱。

$WORKLOAD_IMAGE_NAME

工作負載 Docker 映像檔的名稱。

$WORKLOAD_IMAGE_TAG

工作負載容器映像檔的標記。

$WORKLOAD_SERVICEACCOUNT

服務帳戶具備執行工作負載的機密 VM 存取權。

$CLIENT_VM

用戶端 VM 的名稱,用於執行推論伺服器的用戶端應用程式。

$CLIENT_SERVICEACCOUNT

$CLIENT_VM 使用的服務帳戶

  • 您需要具備專案 $PRIMUS_PROJECT_ID 的「儲存空間管理員」、「Artifact Registry 管理員」、「Cloud KMS 管理員」、「服務帳戶管理員」、「IAM Workload Identity Pool 管理員」角色。如要瞭解如何使用 GCP 主控台授予 IAM 角色,請參閱這份指南
  • 針對 $PRIMUS_PROJECT_ID,執行以下指令碼,將其餘變數名稱設為資源名稱的值,並根據專案 ID 設定值。
source config_env.sh

設定 Primus 公司資源

在這個步驟中,您將為 Primus 設定必要的雲端資源。執行下列指令碼,為 Primus 設定資源。指令碼執行時會建立下列資源:

  • KMS 中的加密金鑰 ($PRIMUS_ENC_KEY) 和金鑰環 ($PRIMUS_ENC_KEYRING),用於加密 Primus 公司的客戶資料檔案。
  • Workload Identity Pool ($PRIMUS_WORKLOAD_IDENTITY_POOL),可根據提供者下所設定的屬性條件驗證要求。
  • 服務帳戶 ($PRIMUS_SERVICE_ACCOUNT) 已連結至上述工作負載身分資料集區 ($PRIMUS_WORKLOAD_IDENTITY_POOL),因此可使用 KMS 金鑰解密資料 (使用 roles/cloudkms.cryptoKeyDecrypter 角色)、使用 KMS 金鑰加密資料 (使用 roles/cloudkms.cryptoKeyEncrypter 角色)、讀取雲端儲存值區的資料 (使用 objectViewer 角色),以及將服務帳戶連結至工作負載身分資料集區 (使用 roles/iam.workloadIdentityUser)。
./setup_primus_resources.sh

3. 建立工作負載

建立工作負載服務帳戶

接下來,您將為工作負載建立服務帳戶,並設定必要的角色和權限。執行下列指令碼,在 Primus 專案中建立工作負載服務帳戶。這個服務帳戶會由執行推論伺服器的 VM 使用。

這個工作負載服務帳戶 ($WORKLOAD_SERVICEACCOUNT) 將具備下列角色:

  • confidentialcomputing.workloadUser 取得認證權杖
  • logging.logWriter 將記錄檔寫入 Cloud Logging。
./create_workload_service_account.sh

建立工作負載

在這個步驟中,您將建立工作負載 Docker 映像檔。工作負載是由 Primus 公司編寫。本程式碼研究室使用的負載是 Python 程式碼,該程式碼會使用 公開可用的 GCS 儲存桶 (頂點模型花園) 中的 codegemma 模型。工作負載會載入 codegemma 模型,並啟動推論伺服器,以便處理 Primus 開發人員的程式碼產生要求。

在程式碼產生要求中,工作負載會取得已包裝的 DEK 和加密提示。工作負載會呼叫 KMS API 來解密 DEK,然後使用這個 DEK 解密提示。加密金鑰 (適用於 DEK) 會透過工作負載身分集區受到保護,並授予符合屬性條件的各工作負載存取權。下一節將詳細說明這些屬性條件,說明如何授權工作負載。推論伺服器取得解密的提示後,就會使用已載入的模型產生程式碼,並傳回回應。

執行下列指令碼,建立工作負載,並執行下列步驟:

  • 建立 Primus 擁有的 Artifact Registry($PRIMUS_ARTIFACT_REGISTRY)。
  • 更新工作負載程式碼,加入必要的資源名稱。
  • 建構推論伺服器工作負載,並建立 Dockerfile,以便建構工作負載程式碼的 Docker 映像檔。這裡是本程式碼研究室使用的 Dockerfile。
  • 建構並發布 Docker 映像檔至 Primus 擁有的 Artifact Registry ($PRIMUS_ARTIFACT_REGISTRY)。
  • $WORKLOAD_SERVICEACCOUNT 的讀取權限授予 $PRIMUS_ARTIFACT_REGISTRY。這項設定是工作負載容器從 Artifact Registry 提取工作負載 Docker 映像檔所需。
./create_workload.sh

以下是本程式碼研究室中建立及使用的負載的 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 金鑰,以便根據下列資源的屬性進行快速加密:

  • What:已驗證的程式碼
  • 地點:安全的環境
  • Who:可信任的運算子

Primus 會使用 Workload Identity 聯盟,根據這些需求強制執行存取權政策。您可以透過 Workload Identity 聯盟指定屬性條件。這些條件會限制哪些身分可以透過工作負載身分集區 (WIP) 進行驗證。您可以將認證驗證服務新增至 WIP,做為工作負載身分集區供應商,以呈現評估結果並強制執行政策。

在雲端資源設定步驟中,我們已先建立工作負載身分識別集區。Primus 會建立新的 OIDC 工作負載身分集區提供者。指定的 --attribute-condition 會授予工作負載容器的存取權。它需要:

  • 內容:最新的 $WORKLOAD_IMAGE_NAME 已上傳至 $PRIMUS_ARTIFACT_REPOSITORY 存放區。
  • 適用範圍:Confidential Space 受信任執行環境在完全支援的 Confidential Space VM 映像檔上執行。
  • :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_digestimage_reference,可強化安全性並確保執行中工作負載的完整性。

執行工作負載

在這個步驟中,我們會在已連接加速器的 Trusted Space VM 中執行工作負載。系統會使用中繼資料標記傳遞必要的 TEE 引數。工作負載容器的引數會透過旗標的「tee-cmd」部分傳遞。如要為工作負載 VM 配備 Nvidia Tesla T4 GPU,我們會使用 --accelerator=type=nvidia-tesla-t4,count=1 標記。這會將一個 GPU 連結至 VM。我們也需要在中繼資料標記中加入 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 公司的員工現在可以將程式碼產生要求傳送至推論伺服器。

在本程式碼研究室中,我們會使用以下指令碼設定用戶端應用程式,以便與推論伺服器互動。執行這個指令碼,即可設定用戶端 VM。

./setup_client.sh

以下步驟說明如何透過 SSH 連線至用戶端 VM,並在 Python 虛擬環境中執行用戶端應用程式範例。這個應用程式範例使用信封式加密和 Fernet 程式庫,但請注意,特定加密程式庫可視不同用途進行調整。

gcloud compute ssh ${CLIENT_VM} --zone=${PRIMUS_PROJECT_ZONE}

執行下列指令,即可在用戶端 VM 中啟用 Python 虛擬環境,並執行用戶端應用程式。

source venv/bin/activate
python3 inference_client.py

此範例用戶端應用程式的輸出內容會顯示加密和純文字提示要求,以及相應的加密和解密回應。

5. 清除

這裡提供的程式碼可用於清除我們在本程式碼研究室中建立的資源。在本次清理作業中,系統會刪除下列資源:

  • Primus 服務帳戶 ($PRIMUS_SERVICEACCOUNT)。
  • Primus 加密金鑰 ($PRIMUS_ENC_KEY)。
  • Primus 的構件存放區 ($PRIMUS_ARTIFACT_REPOSITORY)。
  • Primus 工作負載身分集區 ($PRIMUS_WORKLOAD_IDENTITY_POOL) 及其提供者。
  • Primus 的工作負載服務帳戶 ($WORKLOAD_SERVICEACCOUNT)。
  • 工作負載 VM ($WORKLOAD_VM) 和用戶端 VM ($CLIENT_VM)。
./cleanup.sh

如果您已完成探索,請考慮刪除專案。

  • 前往 Cloud Platform Console
  • 選取要關閉的專案,然後按一下頂端的「刪除」:這會排定專案的刪除作業