Azure DevOps Services |Azure DevOps Server 2022 |Azure DevOps Server 2020
管線提供強大的功能來執行腳本,並將程式代碼部署至生產環境,但請務必將此能力與安全性平衡。 您永遠不希望管線成為惡意代碼的管道。 平衡安全性與開發小組所需的彈性和能力至關重要。
本文提供必要的安全性相關設定概觀,以保護您的管線抵禦威脅和弱點。
先決條件
類別 | 要求 |
---|---|
Azure DevOps | - 在 讓您的 Azure DevOps 安全無虞中實作建議。 - YAML 和 Azure Pipelines 的基本知識。 如需詳細資訊,請參閱 建立您的第一個管線。 |
權限 | - 若要修改管線許可權: 專案管理員群組的成員。 - 若要修改組織許可權: 專案集合系統管理員群組的成員。 |
限制專案、存放庫和服務連線存取
為了強化安全性,請考慮將專案分開、使用分支原則,以及為分叉新增更多安全措施。 將服務連線的範圍降到最低,並使用最安全的驗證方法。
- 個別專案:在不同的專案中管理每個產品和小組。 這可防止某個產品的管線意外地從另一個產品存取開啟的資源,將橫向風險降至最低。
- 使用專案層級身分識別:針對管線使用以專案為基礎的組建身分識別,而不是使用集合層級身分識別。 專案層級身分識別只能存取其相關聯專案內的資源,將惡意執行者未經授權存取的風險降到最低。 如需詳細資訊,請參閱 限定範圍的組建身分識別 和 作業授權範圍。
- 使用分支原則:若要確保程式碼和管線的安全變更,請套用許可權和分支原則。 此外,請考慮 將管線許可權和檢查新增至存放庫。
-
新增額外的分支安全性:當您從 GitHub 使用公用存放庫時,請仔細考慮您的分支組建方法。 源自您組織外部的分支會造成特定風險。
- 請勿提供分支組建的秘密:根據預設,管線會設定為建置分叉,但秘密和受保護的資源不會自動公開至這些管線中的作業。 請務必不要停用此保護來維護安全性。
- 請考慮手動觸發分支組建:關閉自動分支組建,並使用提取要求批注手動建置這些貢獻。 此設定可讓您在觸發組建之前先檢閱程式代碼。 如需詳細資訊,請參閱 關閉自動分支組建。
- 不要提供秘密給叉子建置:根據預設,與管線相關聯的秘密不會在叉子的拉取請求驗證中提供。 請勿啟用 [ 讓秘密可供分支建置使用] 選項。 如需如何尋找和驗證此設定的指示,請參閱 分叉的貢獻。
- 請考慮手動觸發分支組建:關閉自動分支組建,並使用提取要求批注手動建置這些貢獻。 此設定可讓您在觸發組建之前先檢閱程式代碼。 如需如何執行這項作業的指示,請參閱 關閉自動派生組建。
- 使用 Microsoft 託管的代理程式進行 fork 組建:避免從分支在自行裝載的代理程式上執行組建。 這樣做可讓外部組織在公司網路內的機器上執行外部程序代碼。 盡可能使用Microsoft裝載的代理程式。
- 使用 Azure Pipelines GitHub 應用程式限制令牌範圍:當您建置 GitHub 的已分叉拉取要求時,Azure Pipelines 可確保管線無法更改任何 GitHub 儲存庫的內容。 只有在您使用 Azure Pipelines GitHub 應用程式與 GitHub 整合時,才適用這項限制。
安全服務連線
- 將服務連線的範圍降到最低:服務連線應該只能存取必要的資源。 當您建立新的 Azure Resource Manager 服務連線時,請一律選擇特定的資源群組。 請確定資源群組只包含組建所需的 VM 或資源。 如需如何設定服務連線的指示,請參閱 使用 Azure Resource Manager 服務連線。
- 使用工作負載身分識別同盟進行驗證:盡可能使用工作負載身分識別同盟,而不是 Azure 服務連線的服務主體。 工作負載身分識別同盟會使用 Open ID Connect (OIDC),這是業界標準技術,可協助 Azure 與 Azure DevOps 之間的驗證,而不需要依賴秘密。 如需如何執行這項作的方式的指示,請參閱使用工作負載身分識別同盟建立服務連線(自動)。
- 將 GitHub 應用程式存取降至最低:當您將 GitHub 應用程式設定為 Azure DevOps 時,請僅將存取權授與您想要使用管線建置的存放庫。
使用YAML管線而非傳統管線
為了增加安全性並降低意外設定的風險,請使用 YAML 管線,而不是傳統管線。 這項預防措施可防止因 YAML 和傳統管線共用相同資源(如服務連接)而引發的安全問題。 如果您的組織使用傳統管 線,請將管線移轉至 YAML。
- YAML 提供基礎結構即程式代碼的優點:將 YAML 管線視為任何其他程式碼,因為步驟和相依性是在程式碼中定義。 也清楚瞭解管線設定,並降低意外設定錯誤的風險。
- YAML 管線可以結合增強的安全性措施:透過程式代碼檢閱和提取要求,使用 分支原則 來設定提取要求的檢閱程式,以防止合併錯誤。
-
資源存取管理:資源擁有者控制 YAML 管線是否可以存取特定資源。 這項安全性功能可防止攻擊,例如竊取另一個存放庫。 使用 核准和檢查 來提供每個管線執行的存取控制。
- 受保護的分支檢查:如果您有特定分支的手動代碼檢查流程,您可以將此保護延伸至管道。 資源的受保護分支檢查可防止管線在未經授權的分支上自動執行。
- 手動核准檢查:使用手動核准檢查來封鎖管線要求使用受保護的資源,直到指定的使用者或群組手動核准為止。
- 上班時間檢查:使用此檢查來確保管線部署會在指定的日期和時間範圍內啟動。
- 停用建立傳統管線:獨立停用建立傳統組建管線和傳統發行管線。 停用兩者時,無法透過使用者介面或 REST API 建立任何傳統組建管線、傳統發行管線、工作組或部署群組。 如需詳細資訊,請參閱 停用建立傳統管線。
安全代理
若要保護容器,請將磁碟區標示為唯讀、設定資源限制、使用受信任的映像、掃描弱點,以及強制執行安全策略。
- 使用Microsoft裝載的代理程式,而不是自我裝載的代理程式:Microsoft裝載的代理程式會針對管線的每個執行提供隔離和乾淨的虛擬機。 使用Microsoft裝載的代理程式,而不是自我裝載的代理程式。 如需詳細資訊,請參閱 Microsoft裝載的代理程式。
- 每個專案的個別代理程式:若要降低橫向移動並防止專案之間的交叉污染,請維護個別的代理集區,每個代理集區都專用於特定專案。
- 使用低許可權帳戶來執行代理程式:若要增強系統安全性,請使用最低許可權帳戶來執行自我裝載代理程式。 例如,請考慮使用您的電腦帳戶或受控服務識別。 請勿在具有 Azure DevOps 資源直接存取權的身分識別下執行代理程式。
-
隔離生產產物和敏感代理程式集區:使用不同的代理程式集區來防止安全性問題。
- 將個別的代理程式集區用於生產成品:使用不同的代理程式集區隔離生產成品,防止意外部署非生產分支。
- 區段敏感性集區: 為敏感性和非敏感工作負載建立個別的集區。 只允許與適當集區相關聯的組建定義中的認證。
- 設定自我裝載代理程序的嚴格防火牆:將防火牆設定為盡可能限制,同時仍允許代理程序運作、平衡安全性和可用性。
- 定期更新自我裝載代理程式集區:使用定期更新讓您的自我裝載代理程式保持最新狀態,以確保易受攻擊的程式代碼未執行,降低惡意探索的風險。
安全地使用變數和參數
遵循設定秘密的最佳做法,安全地在管線中使用變數和參數。 最佳做法包括限制秘密使用、使用佇列時間變數,以及啟用殼層工作自變數驗證來保護管線免於威脅和弱點。
- 限制對秘密的存取:移除任何秘密或密鑰,以免出現在管線中。 移至無秘密驗證方法,例如工作負載身分識別同盟,或在UI、變數群組或從 Azure Key Vault 來源的變數群組中設定秘密。
- 啟用 Shell 參數驗證:當啟用了 啟用 Shell 任務參數驗證 設定時,系統會對分號、引號和括號等字元進行額外檢查。 在組織或專案層級的 [設定>管線>設定] 中,開啟 [啟用殼層任務參數驗證]。
- 限制可在佇列時間設定的變數:在組織設定>中啟用限制可在佇列時間設定的變數設定,防止使用者在佇列時間定義新的變數,管線>設定。
-
使用參數而非變數:不同於變數,執行中的管線無法修改管線參數。 參數具有 和 等
number
string
數據類型,而且可以限製為特定值子集。 當管線的用戶可設定層面只接受預先定義清單中的值時,這項限制會很有用,以確保管線不接受任意數據。 - 參考範本中的秘密:不要在管線 YAML 中直接包含具有秘密參數的內嵌腳本,而是使用範本從主要管線中擷取機密資訊。 若要實作此方法,請為您的腳本建立個別的 YAML 檔案,然後將該腳本儲存在個別的安全存放庫中。 然後,您可以參考範本,並在 YAML 中傳遞秘密變數作為參數。 安全變數應該來自 Azure 金鑰保存庫、變數群組或管線 UI。 如需詳細資訊, 請參閱使用範本。
-
使用分支原則和變數群組許可權限制秘密:您可以使用變數群組許可權、條件式作業插入和分支原則的組合,以確保秘密系結至
main
分支。 如需詳細資訊,請參閱 保護秘密。 -
使用 setvariable 來限制設定變數:使用
settableVariables
屬性來設定管線作者可以在管線中設定哪些變數。 如果沒有此設定,管線作者可以使用記錄命令宣告無限制的新變數setvariable
。 當您指定空白清單with settableVariables
時,不允許所有變數設定。 如需詳細資訊,請參閱settableVariables
YAML 架構中的 屬性。
保護秘密的最佳方法是一開始沒有秘密。 避免盡可能使用秘密,請勿將它們儲存在 YAML 檔案中,並確保它們不會記錄或列印,以維護安全性。
- 避免盡可能使用秘密:請檢查您的管線是否可以使用與使用秘密不同的方法來執行工作,例如使用工作負載身分識別同盟或受控識別的服務連線。 受控識別可讓您的應用程式和服務向 Azure 進行驗證,而不需要明確的認證。 如需詳細資訊,請參閱 使用服務主體和受控識別。 請勿在 YAML 中放置秘密:請勿將機密值儲存為純文字,在 Azure Pipelines .yml 檔案中。
- 請勿記錄或列印秘密:避免將秘密回應至控制台、在命令行參數中使用秘密,或將它們記錄至檔案。 Azure Pipelines 會儘可能嘗試從記錄中清除秘密,但無法攔截秘密洩漏的每一種方式。
- 請勿使用 JSON 之類的結構化數據做為秘密:為每個敏感性值建立個別秘密。 此方法可確保更好的修訂精確度,並將不小心公開敏感數據的風險降到最低。
稽核和輪替秘密
若要保護您的管線,請定期稽核工作和記錄中的秘密處理、檢閱和移除不必要的秘密,以及輪替秘密,以將安全性風險降至最低。
- 稽核任務和日誌中的秘密處理:檢查任務以確保秘密不會傳送至主機或輸出至日誌。 確認任何記錄檔中沒有任何秘密,包括錯誤記錄檔。
- 檢閱已註冊的秘密:確認管線中的秘密仍是必要的,並移除不再需要的任何秘密,以減少雜亂和潛在的安全性風險。
- 輪替秘密:定期輪替秘密,以將遭入侵秘密惡意探索的時間範圍降到最低。
防止惡意代碼執行
為了確保只有經過測試和清理的程式代碼會透過管線執行,請定期檢閱管線中是否有常見問題。
- 程式代碼掃描:在參數中逸出特殊字元,以避免命令注入。 您可以使用 適用於 Azure DevOps 的 GitHub 進階安全性 ,將程式代碼掃描自動化。
- 驗證輸入並使用參數:驗證輸入參數和自變數,以防止非預期的行為。 在文稿中使用參數化查詢來防止 SQL 插入。 運行時間參數 有助於避免與變數相關的安全性問題,例如 自變數插入。
-
請勿在腳本中使用PATH:依賴代理程式的
PATH
設定很危險,因為先前的腳本或工具可以改變它。 請改用完整路徑。 - 控制可用的工作:停用從 Marketplace 安裝和執行工作的能力,這可讓您更充分掌控管線中執行的程式碼。
安全容器
瞭解如何透過設定變更、掃描和原則來保護容器。
-
將磁碟區標示為唯讀:容器包含系統提供的磁碟區掛接,適用於使用主機代理程式所需的工作、工具和外部元件。 將
externals
、tasks
和tools
設定為唯讀,以增加安全性。 - 設定容器特定的資源限制:設定 CPU 和記憶體的限制,以防止容器耗用過多的資源,這可能會導致阻斷服務或安全性弱點。
-
使用信任的映像:使用來自 Azure Container Registry 或 Docker Hub 等知名來源的官方和已驗證映像。 請一律指定特定版本或標籤來維護一致性和可靠性,而不是依賴
latest
標籤。 定期更新基底映像,以包含最新的安全性修補程式和錯誤修正。 - 掃描容器是否有弱點並強制執行運行時間威脅防護:使用 Microsoft Defender for Cloud 之類的工具來監視及偵測安全性風險。 此外,Azure Container Registry 提供整合 式弱點掃描 ,以協助確保容器映射在部署之前安全無虞。 您也可以透過 Azure DevOps 擴充功能整合第三方掃描工具,以進行新增的安全性檢查。
- 實作安全策略以防止許可權提升,並確保容器以最少的許可權執行:例如,Azure Kubernetes Service (AKS)、 角色型訪問控制和 Pod 安全性許可 可讓您強制執行限制容器許可權的原則、確保非根執行,以及限制對重要資源的存取。
- 利用網路原則: 網路 原則可用來限制容器之間的通訊,確保只有授權的容器可以存取您網路內的敏感性資源。 此外, AKS 的 Azure 原則可以套用至強制執行容器安全性最佳做法,例如確保只部署受信任的容器映射。
使用範本來強制執行最佳做法
從最小範本開始,並逐步強制執行延伸模組。 此方法可確保當您實作安全性做法時,會有涵蓋所有管線的集中式起點。
- 使用擴充範本:擴充範本會定義外部結構,並提供目標自定義的特定點。 使用擴充範本 可防止惡意代碼滲透管線。
- 使用步驟限制存取:藉由在容器上執行下載套件等步驟,而非在主機上直接執行,來限制網路存取。 在容器中執行步驟時,您會防止不良動作專案修改代理程式組態,或留下惡意代碼以供稍後執行。