產生 GPG 金鑰

由IBM Cloud DevSecOps持續整合工具鏈建置並記錄在清單中的工件必須在部署到生產之前進行簽署。 連續整合管線使用 Skopeo 作為預設工具來提供構件簽署功能。

建立並儲存DevSecOps持續整合管道自動或手動使用的 GPG 金鑰。

自動產生 GPG 金鑰

使用此方法,範本會為您產生 GPG 金鑰。 完成下列步驟,以輸入金鑰產生的 名稱電子郵件:

  1. 移至 構件簽署,然後按一下 新建

    圖像簽名
    工件簽名

  2. 在視窗中,名稱電子郵件 欄位會預先移入工具鏈名稱及電子郵件 ID。 變更名稱及電子郵件 ID,以反映您的 GPG 金鑰需求。 您也可以透過選取方框,將金鑰儲存在密鑰提供者中。

    更改姓名和電子郵件
    更改姓名和電子郵件

  3. 產生金鑰之後,您可以複製它供您參照。

    影像簽署憑證
    圖 3 構件簽署憑證

複製的金鑰採用 base64 格式。 在將密鑰導入 密鑰環 之前對其 進行解碼echo <encoded_gpg_key> | base64 --decode

手動產生 GPG 金鑰

下載並安裝 GPG 指令行工具

下載並安裝適用於您作業系統的 GPG 指令行工具。 移至 GnuPG 二進位版次 區段,以下載適用於您作業系統的工具。

Mac OS X

  • 下載並安裝 Mac GPG
  • 驗證已安裝 GPG 的版本。 從指令行執行下列指令:
$ gpg --version
gpg (GnuPG) 2.3.1
libgcrypt 1.9.3
Copyright (C) 2021 Free Software Foundation, Inc.
  • 對於 2.3.1之前的 GPG 版本,可能無法使用 -- passphrase = '' 選項。 在此情況下,您可以在提示時按 Enter 鍵,以省略下列對話框中的密碼。

Windows™

  • 下載並安裝 GitBash ( base64 編碼需要)。
  • 驗證已安裝 GPG 的版本。 在 Git bash 命令提示字元中執行下列指令:
$ gpg --version
gpg (GnuPG) 2.2.27
libgcrypt 1.8.7
Copyright (C) 2021 g10 Code GmbH

產生 GPG 金鑰

如果 generate-key 指令開啟一個對話框,要求輸入通行詞組,請將通行詞組和欄位保留空白。 這是 skopeo 工具在圖片簽名功能上的限制,即該處理流程無法接受受密碼短語保護的私鑰。 如果您在建立期間提供通行詞組,則您的管線無法解碼憑證,且您的管線在映像檔簽署步驟中失敗。 請注意,這也適用於 GIT 標籤簽署。

Mac OS X 和 Linux™

從 Shell 提示中,執行下列指令:

gpg --pinentry-mode loopback --passphrase='' --generate-key
  • 請輸入您的姓名和電子郵件地址。
  • 輸入 O 以起始建立金鑰。
  • 產生金鑰之後,請選取選項 O

Windows™

GPG 版本> 1.4

從 Git Bash 命令提示字元,執行下列指令:

gpg --pinentry-mode loopback --passphrase='' --generate-key
  • 請在「真實姓名」欄位中輸入您的姓名。
  • 電子郵件位址中輸入您的電子郵件位址。
  • 輸入 O 以起始金鑰建立。
  • 產生金鑰之後,請選取選項 O

GPG 版本 < 1.4 (或之前的指令有任何失敗)

從 Git Bash 命令提示字元,執行下列指令:

gpg --gen-key
  • 金鑰類型: 選取「預設」選項 (1) RSA 和 RSA (預設值)
  • keysize: 保留預設值 (2048)
  • key validity: 將預設值保留為 0。 這是因為值索引鍵 0 不會到期。
  • 確認您的選擇: 輸入 y
  • 實際名稱 欄位中輸入您的名稱。
  • 電子郵件位址中輸入您的電子郵件位址。
  • 輸入 O 以起始建立金鑰。
  • 產生金鑰之後,請選取選項 O

驗證金鑰建立

驗證已建立 GPG 金鑰。 在命令提示字元中,執行以下指令:

gpg --list-keys

請確定已列出您的金鑰。 Windows 上的輸出範例:

$ gpg --list-keys
/c/Users/FredSmith/.gnupg/pubring.gpg
-------------------------------------
pub   2048R/1BB354B5 2021-06-08
uid   Fred Smith <fred@company.com>
sub   2048R/F91C39A6 2021-06-08

匯出金鑰

這是選用步驟。 執行此指令以確保可以匯出 GPG 金鑰。

gpg --export-secret-key <Email Address>

匯出的原始金鑰不得直接複製。 建議您將此步驟所產生的金鑰安全地儲存於您的 Key Protect 實例或 Secrets Manager 實例中。 詳情請參閱以下各節。

儲存金鑰

必須以下列其中一種方式將 GPG 金鑰提供給 CI 管線:

  • 儲存在 IBM® Key Protect for IBM Cloud® 中
  • 儲存在 IBM Cloud® Secrets Manager 中
  • 直接儲存在 CI 工具鏈中

請確定以正確的格式複製金鑰,以防止因匯入失敗而發生 CI 管線簽署錯誤。 請在以下指令中使用 pbcopy ( Mac OS X )或 clip (Windows Git bash),將金鑰內容複製到剪貼簿。

將金鑰儲存在 Key Protect 中

匯出 GPG 金鑰並複製到剪貼簿。

在將 GPG 金鑰儲存至您的 Key Protect 實例之前,必須先對該金鑰進行雙重 base64 編碼。

OS X

gpg --export-secret-key <Email Address> | base64 | base64 | pbcopy

Windows™

gpg --export-secret-key <Email Address> | base64 -w0 | base64 -w0 | clip

Linux™

gpg --export-secret-key <Email Address> | base64 | base64
  1. 在 IBM Cloud 主控台中,選取 Key Protect 實例,以儲存從先前步驟產生的 GPG 金鑰。

  2. 按一下 新增 + 圖示,以將新的金鑰新增至實例。

  3. 選取 匯入您自己的金鑰 選項。

  4. 選取 選取金鑰類型 作為 標準金鑰

  5. 金鑰名稱 欄位中提供適當的名稱。 稍後可以透過此金鑰名稱來擷取儲存的 GPG 金鑰。

  6. 複製先前在 金鑰資料 欄位中匯出的金鑰。

    當您複製金鑰並將它貼到 金鑰資料 欄位時,金鑰尾端不會有額外的一行。

  7. 選取 選擇金鑰環 選項作為預設值。

  8. 按一下 新增金鑰,將金鑰新增至 金鑰保護

    將金鑰加入到金鑰保護
    將金鑰加入到金鑰保護

如需 Key Protect的相關資訊,請參閱 Key Protect 文件

將金鑰儲存在 Secrets Manager 中

在將 GPG 金鑰儲存至您的 Secrets Manager 實例之前,必須先對該金鑰進行單一的 base64 編碼。

匯出 GPG 金鑰並複製到剪貼簿。

OS X

gpg --export-secret-key <Email Address> | base64 | pbcopy

Windows™

gpg --export-secret-key <Email Address> | base64 -w0 | clip

Linux™

gpg --export-secret-key <Email Address> | base64
  1. 在 IBM Cloud 主控台中,選取 Secrets Manager 實例,以儲存從先前步驟產生的 GPG 金鑰。

  2. 按一下 新增 + 圖示,以將新的金鑰新增至實例。

  3. 選取 其他密鑰類型 選項。

    其他秘密類型
    其他秘密類型

  4. 選取 選取金鑰類型選項的 標準金鑰 類型。

  5. 名稱 欄位中提供適當的名稱。 稍後可以透過此名稱來擷取儲存的 GPG 金鑰。

  6. 選擇選項作為 密鑰值,並在 密鑰值 欄位中貼上先前匯出的金鑰。

    請確保當您複製金鑰並將其貼在 密碼值 欄位中時,金鑰結尾沒有額外的行。

  7. 按一下 新增 圖示,將金鑰新增至 Key Protect 實例。

    新增密鑰
    新增密鑰

如需 Secrets Manager 的相關資訊,請參閱開始使用 Secrets Manager

匯出私密金鑰並直接儲存在 CI 管線中

不建議使用此方法,且應該僅用於實驗。 使用 Key ProtectSecrets Manager 來儲存金鑰。 如需相關資訊,請參閱 配置密鑰儲存庫

在將 GPG 金鑰儲存為安全管線內容之前,需要 GPG 金鑰的單一 base64 編碼。

請將 GPG 金鑰安全地儲存於 Key Protect 或 Secrets Manager 實例中。

Mac OS X / Linux™

gpg --export-secret-key <Email Address> | base64

Windows™

gpg --export-secret-key <Email Address> | base64 -w0

設定用於簽名的登錄檔憑證

在簽署容器映像檔時,建置流程需要憑證來向容器註冊表進行驗證。 DevSecOps 管道支援執行階段的動態憑證解析,讓您能夠透過多種方式配置憑證,並具備自動備用機制。

憑證解析層級結構

該處理流程會在執行時,依照以下層級結構動態解析使用者名稱和 API 金鑰憑證。

當使用 gara-destination-registrygara-destination-namespace 配置簽署目標覆寫,且同時提供 gara-destination-apikey 時,管道會優先使用 gara-destination-apikey 來對目標註冊表進行驗證。 否則,系統將回退至以下針對目標映像的憑證解析機制。

API 金鑰解析順序:

  1. 特定於命名空間的 API 金鑰signing-token-apikey-{registry}-{namespace} (密鑰)
  2. 註冊表專用 API 金鑰signing-token-apikey-{registry} (密鑰)
  3. Docker JSON 設定檔signing-dockerconfigjson (機密)
  4. ICR 專用的備用方案
    • ciso-ibmcloud-api-key (秘密)
    • ibmcloud-api-key (秘密)

使用者名稱解析順序:

  1. 特定於命名空間的使用者名稱signing-token-username-{registry}-{namespace} (環境變數)
  2. 登錄檔專用使用者名稱signing-token-username-{registry} (環境變數)
  3. 預設值iamapikey (若未設定使用者名稱)

其中:

  • {registry} 是註冊表的主機名稱(例如:us.icr.iode.icr.io
  • {namespace} 這是完整的命名空間路徑,其中斜線和點號已替換為底線(例如:my_namespace_path

設定命名空間專屬的憑證

若要實現細粒度的存取控制,您可以針對特定登錄空間設定專屬的憑證:

API 金鑰(密鑰)signing-token-apikey-{registry}-{namespace}

使用者名稱(環境變數)signing-token-username-{registry}-{namespace}

範例:關於圖片 us.icr.io/my-namespace/my-app:latest

  • 登錄: us.icr.io
  • 命名空間:my-namespace
  • API 金鑰密鑰:signing-token-apikey-us.icr.io-my_namespace
  • 使用者名稱環境變數:signing-token-username-us.icr.io-my_namespace
  • 若未提供使用者名稱,預設值為:iamapikey

設定登錄檔專用憑證

若要在註冊表中的所有命名空間中獲得更廣泛的存取權限:

API 金鑰(密鑰)signing-token-apikey-{registry}

使用者名稱(環境變數)signing-token-username-{registry}

範例:對於任何位於 us.icr.io

  • API 金鑰密鑰:signing-token-apikey-us.icr.io
  • 使用者名稱環境變數:signing-token-username-us.icr.io
  • 若未提供使用者名稱,預設值為:iamapikey

設定 Docker 的 JSON 配置檔

您可以提供一個包含多個註冊表憑證的 base64-encoded Docker 配置 JSON 檔案:

秘密名稱signing-dockerconfigjson

格式:Base64-encoded 符合 Docker 網站上 config.json 格式的 JSON:

{
  "auths": {
    "us.icr.io": {
      "username": "iamapikey",
      "password": "your-api-key"
    },
    "us.icr.io/my-namespace": {
      "username": "iamapikey",
      "password": "namespace-specific-key"
    }
  }
}

此處理流程會優先匹配最具體的路徑,允許在 Docker 設定中進行命名空間層級的覆寫。

範例配置

關於圖片 us.icr.io/production/my-app:v1.0.0

選項 1:命名空間專用(建議用於生產環境)

  • API 金鑰密鑰:signing-token-apikey-us.icr.io-production = your-namespace-api-key
  • 使用者名稱環境變數(可選):signing-token-username-us.icr.io-production = iamapikey
  • 若未指定使用者名稱,預設值為 iamapikey

選項 2:整個登錄檔範圍

  • API 金鑰密鑰:signing-token-apikey-us.icr.io = your-registry-api-key
  • 使用者名稱環境變數(可選):signing-token-username-us.icr.io = iamapikey
  • 若未指定使用者名稱,預設值為 iamapikey

選項 3:Docker 設定 JSON

  • 祕密:signing-dockerconfigjson = base64-encoded-docker-config
  • 使用者名稱是從 Docker 的設定 JSON 檔案中擷取的

選項 4:IBM Cloud 預設值(ICR 模式下自動)

  • API 金鑰密鑰:ibmcloud-api-key = your-ibmcloud-api-key
  • 使用者名稱預設為 iamapikey