建立及自訂工作負載

工作負載由工作負載作者建立,會處理資料協作者要使用的機密資料。

工作負載作者必須整合下列資源,才能建立工作負載:

  • 應用程式:用於處理機密資料。您可以使用任何語言編寫應用程式,只要建構支援該語言的容器映像檔即可。

  • 容器化映像檔:使用 Docker 將應用程式封裝到容器化映像檔。

  • Artifact Registry 中的存放區,用於儲存 Docker 映像檔。

  • 啟動政策:在容器映像檔上設定,控管工作負載的執行方式,並限制惡意工作負載操作者的能力。

如要部署工作負載,工作負載操作員會根據 Confidential Space 映像檔執行 Confidential VM。這會從 Artifact Registry 擷取容器化映像檔並執行。

資料協作者必須驗證工作負載的認證,工作負載才能存取其資料。

事前準備

為 Confidential Space 編寫工作負載,不只是編寫程式碼和偵錯。您也需要與資料協作者溝通,評估他們的需求、設定環境、將程式碼封裝成容器映像檔,並與工作負載操作員合作,確保所有項目都能正確部署。

與資料協作者交談

開始編寫應用程式前,您需要與資料協作者討論他們希望您處理的私人資料。您可以提出以下問題:

  • 相關組織 ID 為何?

  • 涉及哪些專案編號?

  • 我需要存取哪些 Google Cloud 資源?這些資源的 ID 和名稱為何?

  • 我需要存取的資源是否不受 Google CloudIAM 管理?

  • 您要使用哪項認證服務:Google Cloud Attestation 或 Intel Trust Authority?

  • 應用程式應如何比較及處理私人資料?

  • 輸出內容應採用什麼格式?

  • 輸出內容應儲存在何處?是否應加密?

  • 所有資料協作者是否看到相同的結果,還是每個人看到的輸出內容都不同?

此外,每位資料協作者可能也有您需要滿足的獨特隱私權規定。請務必確保工作負載不會導致任何私人資料外洩。

建構 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 工作負載會在使用 containerd 的 Linux 容器中執行。這個容器會使用預設 Linux 功能執行。

如要新增功能,可以使用 tee-added-capabilities。

磁碟和記憶體限制

使用較大的開機磁碟時,Confidential Space 會自動調整開機磁碟有狀態分區的大小。分區大小約為開機磁碟大小減去 5 GB。

機密空間會將磁碟完整性標記儲存在記憶體中,做為機密空間完整性檔案系統保護措施的一部分。每個磁碟位元組會耗用約 1% 的記憶體。舉例來說,100 GB 的磁碟需要 1 GB 的記憶體,而 10 TB 的磁碟需要 100 GB 的記憶體。

請務必遵守 VM 記憶體限制。機密空間 VM 已停用交換記憶體,因此記憶體用量過多可能會導致工作負載停止運作。確認所選機器除了磁碟完整性負擔外,還支援工作負載記憶體用量。

正常關機

當操作員要求關閉 Confidential Space VM 時,Confidential Space 啟動器會傳送 SIGTERM 信號,嘗試正常關閉工作負載。收到信號後,工作負載最多有 120 秒的時間執行清理作業,之後 Confidential Space 啟動器就會開始關機程序。如果工作負載未實作 SIGTERM 信號處理,則會在收到信號後立即終止。

記憶體內臨時掛接

Confidential Space 支援新增記憶體內臨時空間。這會使用 Confidential Space VM 中的可用記憶體。由於臨時空間使用 Confidential VM 的記憶體,因此具有與 Confidential VM 相同的完整性和機密性屬性。

您可以使用 tee-dev-shm-size 增加工作負載的 /dev/shm 共用記憶體掛接大小。/dev/shm 大小以 KB 為單位。

您可以使用 tee-mount,以分號分隔的設定指定執行中容器的 tmpfs 掛接。type 和 source 一律為 tmpfs。destination 是掛接點,會與 tee.launch_policy.allow_mount_destinations 啟動政策互動。您可以選擇以位元組為單位指定 tmpfs 大小。預設大小為 VM 記憶體的 50%。

傳入通訊埠

根據預設,Confidential Space VM 會透過防火牆規則運作,封鎖所有傳入通訊埠。使用 230600 以上版本的 Confidential Space 映像檔時,您可以在建構工作負載映像檔時,指定要在 Dockerfile 中保持開啟的傳入通訊埠。

如要開啟通訊埠,請在 Dockerfile 中加入 EXPOSE 關鍵字,以及要保持開啟的通訊埠編號,並視需要加入 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 只會公開其他通訊埠,無法封鎖基本映像檔已開啟的通訊埠。

工作負載操作人員應確保公開的通訊埠在虛擬私有雲防火牆中開啟,再執行工作負載。通訊埠編號可由工作負載作者提供,或從 Docker 映像檔資訊中提取。

使用 tee-container-log-redirect 中繼資料變數時,公開的通訊埠會記錄在控制台中,並重新導向至 Cloud Logging。

推出政策

啟動政策會覆寫工作負載操作員設定的 VM 中繼資料變數,以限制惡意動作。工作負載作者可以在建構容器映像檔時,使用標籤設定政策。

例如,在 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_capabilities

互動對象:

布林值 (預設為 false) 決定工作負載運算子是否能為工作負載容器新增額外的 Linux 功能。

tee.launch_policy.allow_cgroups

互動對象:

布林值 (預設為 false) 決定是否允許工作負載容器在 /sys/fs/cgroup 包含命名空間 cgroup 掛接。

tee.launch_policy.allow_cmd_override

互動對象:

布林值 (預設為 false) 決定工作負載運算子是否能使用 tee-cmd 中繼資料值,覆寫工作負載容器 Dockerfile 中指定的 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 (預設):使用偵錯映像檔時,僅允許 stdout 和 stderr 重新導向。
  • always:一律允許 stdout 和 stderr 重新導向。
  • never:一律不允許 stdout 和 stderr 重新導向。

tee.launch_policy.monitoring_memory_allow

互動對象:

定義的字串

如果工作負載運算子將 tee-monitoring-memory-enable 設為 true,這項設定會決定工作負載記憶體用量監控功能的運作方式。

有效值如下:

  • debugonly (預設):僅允許在使用偵錯映像檔時監控記憶體用量。
  • always:一律允許監控記憶體用量。
  • never:一律不允許監控記憶體用量。

tee.launch_policy.nonroot_container

互動對象:

定義的字串

決定是否要限制容器的執行權限。

有效值如下:

  • unrestricted (預設):工作負載作者允許容器以 root 或非 root 身分執行。工作負載運算子選擇使用 tee-nonroot-container。
  • nonrootonly:工作負載作者要求容器以非超級使用者身分執行。工作負載運算子必須將 tee-nonroot-container 設為 true,否則 VM 無法啟動工作負載。

多個工作負載執行作業

如要重新執行工作負載,工作負載運算子必須重新啟動 VM 執行個體。這項功能會在最乾淨的環境中啟動工作負載,並使用新的臨時金鑰加密 VM 執行個體的磁碟。

重新啟動可解決在下載並測量磁碟上的工作負載映像檔後,修改該映像檔的攻擊向量。不過,這也會增加啟動時間等負擔,並將工作負載映像檔提取至每個工作負載執行作業。如果這些負擔對工作負載效能的影響過大,您可以將工作負載重新啟動編碼至工作負載本身,但這會增加風險。

命名空間 cgroup

根據預設,Confidential Space 工作負載執行時不會掛接 cgroup。

如要管理工作負載容器中的 cgroup,可以使用 tee-cgroup-ns。這個中繼資料鍵會指示 VM 執行個體在容器檔案系統的 /sys/fs/cgroup 建立掛接。

非超級使用者容器執行作業

您可以選擇以非超級使用者身分執行容器,降低容器逃逸的影響。啟用非根容器執行功能後,Confidential Space 會為工作負載設定 Linux 使用者命名空間和網路命名空間。容器 UID 和 GID 0-65535 會對應至 Confidential VM 上從 100000 開始的非特殊權限 ID。在容器中以根權限執行的程序,或逸出容器的程序,只能以非特殊權限存取 VM。您不需要在 Dockerfile 中加入 USER 指令。

如要以非超級使用者身分執行,必須使用 Confidential Space 映像檔 confidential-space-261001 以上版本。您可以將其設為選填或必填:

  • 工作負載作者:在容器映像檔中使用 tee.launch_policy.nonroot_container 啟動政策標籤。如果將這項政策設為 nonrootonly,工作負載運算子就必須以非超級使用者身分執行容器。

  • 工作負載運算子:建立 VM 時,傳遞 tee-nonroot-container=true 中繼資料變數。如果工作負載作者設定 nonrootonly,則必須提供這個中繼資料變數,否則 VM 無法啟動工作負載。

可重現的容器映像檔

以可重現的方式建構容器映像檔,有助於提高各方之間的信任度。您可以使用 Bazel 建構可重現的映像檔。

不受 Google Cloud IAM 管理的資源

如要存取非 Google Cloud IAM 管理的資源,工作負載必須指定自訂目標對象。

詳情請參閱「存取非由 Google Cloud IAM 管理的資源」。

已簽署的容器映像檔

您可以使用公開金鑰簽署容器映像檔,資料協作者就能使用該金鑰進行認證,而不必在工作階段政策中指定映像檔摘要。

這表示資料協作者不必在每次更新工作負載時更新 WIP 政策,工作負載也能繼續存取受保護的資源,不會中斷。

您可以使用 Sigstore Cosign 簽署容器映像檔。為確保 Confidential Space 能擷取簽章,工作負載運算子必須先將簽章資訊新增至 tee-signed-image-repos 中繼資料變數,再部署工作負載。

在執行階段,簽章會傳送至認證服務進行驗證。認證服務會傳回認證宣告權杖,其中包含已驗證的簽章宣告。以下是簽名聲明範例:

"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",
  }
]

如要設定容器映像檔簽署,請參閱「程式碼實驗室:已簽署的容器映像檔」。