部署安全閘道
此技能強制執行一個檢查清單:沒有金鑰被暴露,也沒有單一故障會導致產品崩潰。它分三個階段執行:
- 使用
scripts/scan.py進行自動化掃描,這個掃描快速、確定性且唯讀。 - 根據
references/integrations.md,對每個檢測到的整合進行程式碼審查。 - 針對無法從儲存庫中看到的項目(例如供應商儀表板、輪換、備份和演練)進行人工審查。這些項目來自
references/checklist.md。
僅掃描本身不算通過。它大約涵蓋了檢查清單的三分之一。此技能的價值在於執行所有三個階段,並誠實說明哪些已驗證,哪些仍需要人類確認。
工作流程
1. 範圍界定
確定發布的內容:
- 儲存庫根目錄
- 前端或行動端建置輸出(如果有的話)
- 部署目標,例如容器、無伺服器或 Kubernetes
- 是首次發布、新整合還是例行維護
如果使用者指定了特定變更,例如「新增 Stripe」,則將審查重點放在該變更上。但仍需執行完整掃描,因為其他地方的洩漏同樣會阻礙發布。
2. 執行掃描器
python3 <skill-dir>/scripts/scan.py <repo> --history
- 對每個建置的套件(
dist、.next/static、解壓縮後的 APK/IPA)添加--build-dir <dir>。已發布的套件正是「公開」金鑰可能變成秘密金鑰的地方。常見的建置目錄會自動檢測;如果不存在,請先建置應用程式。 --entropy會添加一個高熵檢查,用於捕獲沒有已知模式的客製化秘密(低嚴重性;在報告前請逐一驗證)。--format json或--format sarif提供機器可讀的輸出;SARIF 可上傳至 GitHub 程式碼掃描。--fail-on high|medium|low|never控制退出碼,這在 CI 中很有用。- 確認的誤報可以透過行內
# security-gate: allow註解或儲存庫根目錄下的.security-gate-ignore檔案來抑制(請參閱 README)。優先抑制特定發現,而非降低--fail-on的層級。 - 掃描器會遮罩掉秘密的值。在您撰寫的任何內容中都應保持此做法:切勿將完整的金鑰輸出到聊天、檔案、提交或 PR 文字中,因為這會造成第二次洩漏。
掃描器檢查:
- 秘密模式(AWS、Anthropic、OpenAI、OpenRouter、Groq、xAI、Perplexity、Replicate、fal、Google API 金鑰和 OAuth 秘密、Stripe 活動金鑰和 Webhook 秘密、Razorpay、GitHub、GitLab、Slack 令牌和應用程式令牌、GCP 服務帳戶、npm、PyPI、SendGrid、Hugging Face、DigitalOcean、New Relic、Shopify、Square、Databricks、Doppler、PlanetScale、Linear、Azure 儲存體金鑰、Mailgun、Telegram、Discord Webhook、JWT、私鑰、包含密碼的資料庫 URL、硬編碼的
*_SECRET/*_TOKEN/*_SERVICE_ROLE賦值 — 無論是帶引號(包括 JSON/MCP 配置)還是不帶引號)在工作目錄、建置輸出和 Git 歷史中 - 使用
--entropy時,檢查與已知格式不符的高熵字串(客製化或新穎的秘密) - 已提交的
.env檔案以及缺少的.gitignore條目 - 在客戶端暴露的前綴(
NEXT_PUBLIC_、VITE_、REACT_APP_、EXPO_PUBLIC_等)後方的看似秘密的變數,以及從客戶端程式碼直接進行的 LLM 呼叫 - 建置輸出中的原始碼映射
- GitHub Actions 工作流程:固定到標籤的 actions、
pull_request_target、缺少permissions:區塊、回顯的秘密、寫入檔案或$GITHUB_ENV/$GITHUB_OUTPUT的秘密、取代 OIDC 的靜態雲端金鑰,以及執行生命週期腳本的安裝 - Dockerfile:
ARG/ENV中的秘密、複製的.env檔案,以及以 root 身份執行 - 沒有簽名驗證的付款 Webhook 處理器
- 程式碼代理對
.env檔案的讀取權限 - 正在使用的整合,以及針對 AI 和支付的單一供應商(單點故障)提示
3. 分類發現
掃描器是透過模式匹配工作的,因此在報告之前,請透過閱讀程式碼來確認每個發現。
- 發現活動秘密(在目錄樹、歷史或套件中):即使儲存庫是私有的,也應視為已洩漏。請遵循
references/leaked-key-runbook.md的步驟,其中撤銷優先,清理在後。撤銷或輪換金鑰會改變生產環境,因此請確切告知使用者是哪個金鑰、在哪裡找到的以及撤銷步驟。讓他們執行,或者先確認再自行操作。 - 誤報(測試固定裝置、已記錄的公開金鑰):說明為什麼它是安全的,然後繼續。
- 啟發式發現(Webhook 驗證、客戶端 LLM 呼叫):打開檔案並檢查實際的控制流程。驗證可能位於其他地方的中介軟體中。
4. 審查每個檢測到的整合
對於掃描器列出或在程式碼中找到的每個整合,閱讀 references/integrations.md 的對應章節,並根據它檢查程式碼。此步驟可以捕獲模式無法捕捉到的問題,例如:
- 作為開放轉送的中介伺服器
- 從請求主體中獲取的模型名稱
- 在客戶端計算的金額
- 使用管理員憑證執行的工具呼叫
- 發送給分析服務的 PII
- 沒有租戶過濾器的 RAG 查詢
- 間接提示注入:模型讀取的文件、網頁、逐字稿或工具結果被視為指令(檢查清單 3.17)
- 未經類型/大小/歸檔檢查或沙箱解析的檔案上傳(3.18)
- SSRF:模型或工具獲取的
*_url沒有阻止私有或中繼資料地址(3.19)
Webhook、客戶端 LLM 和秘密檢查是啟發式的:掃描器會標記候選項,但可能會遺漏手寫控制或非標準佈局。務必透過閱讀程式碼來確認 — 使用 createHmac + timingSafeEqual 驗證的 Webhook,或恰好位於 src/ 下的後端,即使工具標記或遺漏了它,也是沒問題的。
5. 檢查單點故障
使用檢查清單第 10 節,並在程式碼和 IaC 中尋找:
- 一個 LLM 供應商沒有備援
- 向供應商發送 HTTP 請求的客戶端沒有逾時或重試
- 請求路徑上封鎖的供應商呼叫(例如分析服務停機時)
- 單一區域或單一可用區的資料庫
- 沒有快取的秘密獲取
- 根據使用者告知,只有一個人持有 root 或 owner 權限
6. 人工審查
許多檢查清單項目無法從儲存庫中檢查,例如:
- 供應商儀表板上的消費上限
- 輪換排程
- 供應商帳戶上的 SSO 和 MFA
- 備份還原測試
- 容錯轉移演練
- DPAs
- 付款頁面上的 PCI 腳本清單
將這些項目列為需要確認,每個項目附上一個給擁有者的單行問題。切勿根據假設將它們標記為已通過。一個默默允許未驗證項目通過的關卡比沒有關卡更糟糕。
7. 報告
使用此結構,以便結果在不同版本之間可比較:
# 安全閘道:<產品 / 變更> — <GO | NO-GO | GO WITH EXCEPTIONS>
## 阻塞項目(部署前必須修復)
- [檢查 ID] 檔案:行號 — 問題內容 — 修復方式
## 應修復項目(此衝刺)
- ...
## 已審查的整合
| 整合 | 僅伺服器端 | 範圍限定金鑰 + 消費上限 | Webhooks/輸出已驗證 | 備援 | 備註 |
## 需要確認(手動)
- [ ] <給擁有者的問題>(檢查清單 §n)
## 已通過(已驗證)
- <項目> — 如何驗證
判定規則:
- NO-GO: 任何已確認的 HIGH 發現,包括活動秘密、客戶端暴露的秘密金鑰、未經驗證的付款 Webhook 或 CI 日誌中的秘密。
- GO WITH EXCEPTIONS: 僅剩中或低度發現,且使用者接受它們,並指定了負責人和日期。
- GO: 沒有未解決的項目,且每個手動項目都已確認。
修復問題
當使用者要求您修復發現時,請優先採用這些補救措施,它們解決的是根本原因而非症狀:
- 程式碼中的金鑰: 替換為執行時期查詢,無論是從秘密管理器注入的環境變數,還是透過供應商的 SDK。在
.env.example中添加佔位符。切勿在任何地方寫入真實值。告知使用者該金鑰仍需要撤銷,因為從程式碼中移除它並不能使其不再洩漏。 - 秘密到達客戶端: 將呼叫移至後端路由或 AI 閘道之後,該閘道會驗證使用者身份、按使用者和租戶進行速率限制、允許清單模型和操作,並持有金鑰。僅在客戶端保留公開金鑰。
- 未驗證的 Webhook: 使用供應商 SDK 驗證原始主體上的簽名。拒絕過時的時間戳,按事件 ID 去重,並在更改狀態前先從供應商重新獲取物件。
- CI 問題: 將 actions 固定到提交 SHA(使用
git ls-remote解析 SHA,並在註解中保留標籤)。添加permissions: contents: read。用 OIDC 取代靜態雲端金鑰。使用npm ci --ignore-scripts。 - Docker 問題: 使用 BuildKit
RUN --mount=type=secret處理建置時的秘密,並使用非 root 的USER。 - 代理存取: 在
.claude/settings.json中添加permissions.deny條目Read(./.env)和Read(./.env.*)。建議執行時期注入(doppler run、infisical run、op run),這樣根本不存在純文字檔案。
持續使用
建議將掃描器整合到 CI 中,以便在每次 PR 時(而不僅僅是發布時)執行關卡:
- run: python3 tools/deploy-security-gate/scripts/scan.py . --fail-on high
同時建議按照檢查清單第 12 節的頻率進行定期審查。
參考檔案
references/checklist.md:完整的檢查清單(第 1–14 節),每個項目都標記為[auto](掃描器)、[code](程式碼審查)或[manual](擁有者確認)。在步驟 5–6 以及需要確切控制時閱讀它。references/integrations.md:AI 閘道和 LLM 供應商、MCP 伺服器、支付、分析和身份驗證的良好實踐,以及需要尋找的模式。閱讀範圍內整合的相關章節。references/leaked-key-runbook.md:發現活動金鑰時的逐步回應,包括每個供應商的撤銷指引。