iT邦幫忙

2026 iThome 鐵人賽

DAY 19
0
IT Operation

迎接 AI 開發爆發期:告別手動部署,帶領企業團隊從 Git 規範到 CI/CD 實戰系列 第 19

Day 19 安全無死角:Jenkins 整合 HashiCorp Vault 的密鑰管理實作

  • 分享至 

  • xImage
  •  

在自動化流程中,我們不可避免地需要調用 API Token、資料庫密碼或 SSH 私鑰。將這些敏感資訊硬編碼在 Jenkinsfile 或儲存在 Jenkins 內建的 credentials 系統中雖然可行,但當規模擴大到跨團隊、多環境時,這種做法會產生「密鑰碎片化」與「權限失控」的風險。

本篇將介紹如何整合 HashiCorp Vault 進行專業級的秘密管理。

為什麼選擇 HashiCorp Vault?

相較於傳統方案,Vault 提供了更強大的安全性與管理能力:

  1. 中心化秘密管理:不論是建置測試還是生產環境,所有秘密都統一儲存於加密的 KV (Key-Value) 引擎中。
  2. 秘密版本控制 (KV Engine v2):支援秘密的版本化,若誤刪或修改,可快速回溯。
  3. 動態秘密與生命週期:支援動態生成短效期的資料庫憑證或 Token,即便洩漏也會在短時間內失效。
  4. 強大的審計機制 (Audit Logs):精確記錄「誰在什麼時候存取了哪個秘密」。

技術架構:AppRole 驗證機制

雖然可以使用 Token 進行驗證,但針對 Jenkins 這種自動化系統,我們推薦使用 AppRole。這是一種類似於 OAuth2 的機器對機器 (M2M) 驗證方式,透過 RoleIDSecretID 的組合來換取臨時 Token,安全性更高。

Vault 端基礎配置範例

# 定義 Jenkins 專屬 Policy
path "secret/data/jenkins/*" {
  capabilities = ["read"]
}

在 Jenkins 中配置 Vault 插件

  1. 進入 Manage Jenkins -> System
  2. 找到 Vault Plugin 區塊:
    • Vault URL: http://<VAULT_IP>:8200
  3. 建立對應的 Vault TokenAppRole 憑證。

在 Pipeline 中動態調取秘密

透過 withVault 指令,我們可以實現「隨取隨用」且「不留痕跡」的密鑰調度。

node('dotnet') {
    // 定義要讀取的路徑與對應鍵值
    // engineVersion: 2 代表使用支援版本控制的 KV v2 引擎
    def secrets = [
        [path: 'secret/jenkins/gitlab', engineVersion: 2, secretValues: [
            [envVar: 'GIT_TOKEN', vaultKey: 'token']
        ]]
    ]

    withVault(configuration: [vaultUrl: 'http://<VAULT_IP>:8200', vaultCredentialId: 'vault-approle'], secrets: secrets) {
        // 取得的 GIT_TOKEN 會被注入為環境變數
        sh "curl -H 'PRIVATE-TOKEN: ${GIT_TOKEN}' https://gitlab.com/api/v4/projects"
    }
}

關鍵機制:日誌遮罩 (Log Masking)

Jenkins 插件會自動將從 Vault 取得的字串標記為敏感資訊。在 Console Output 中,任何嘗試印出 ${GIT_TOKEN} 的行為都會被轉換為 ****。這確保了密鑰不會在 CI 日誌中留下任何蹤跡。

總結

透過 Jenkins 與 Vault 的整合,我們將「秘密管理」從「開發流程」中剝離,移交給專業的安全系統處理。這種做法降低了金鑰外洩的可能性,並讓環境遷移(如從 Test 到 Prod)變得更加透明與安全。

下一天,我們將把這套安全機制應用在實戰的品質掃描 Workflow 中,完成從建置、分析到品質門檻(Quality Gate)的完整聯動。


上一篇
Day 18 Jenkins 程式碼化:Shared Library 建立重複使用的 Pipeline 架構
系列文
迎接 AI 開發爆發期:告別手動部署,帶領企業團隊從 Git 規範到 CI/CD 實戰19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言