別把 API Key 推上 GitHub:AI 寫程式時代的密鑰外洩防坑指南

整理 AI 編程和 vibe coding 流行後 API Key 外洩的風險:為什麼 .env、設定檔和前端程式碼容易把密鑰暴露到 GitHub,以及發現外洩後該如何補救。

AI 寫程式降低了動手門檻,也把很多原本只會發生在工程團隊裡的安全問題,帶到了新手和非工程使用者面前。

最常見的一類事故,是把 API KeySecretToken、資料庫連線字串或 .env 設定檔一起推到公開倉庫。對本機專案來說,這些檔案只是「能讓程式跑起來的設定」;一旦進了 GitHub 公開倉庫,它們就變成了可以被自動掃描、自動呼叫、自動濫用的憑證。

密鑰外洩不是小機率事件。GitGuardian 的 2026 年度報告提到,2025 年公共 GitHub 提交裡出現了約 2865 萬個新增硬編碼憑證,AI 服務相關憑證外洩同比成長 81%。這說明問題不只是「有人粗心」,而是 AI 編程、快速原型和公開託管疊加後,外洩規模正在被放大。

為什麼新手更容易外洩 Key

很多 AI Agent 或小工具都有兩套「倉庫」:一套在本機硬碟裡,另一套在 GitHub 上。問題在於,新手經常沒有意識到兩者的邊界。

本機執行時,config.json.envsettings.yaml 裡放著 API Key,好像只是開發習慣;執行 git add .git commitgit push 之後,這些檔案就可能被完整上傳。倉庫一旦公開,掃描機器人不需要理解你的業務,只要匹配到密鑰格式,就能把它抓走。

AI 編程還會放大這個問題:

  1. AI 生成範例程式碼時,可能直接把 OPENAI_API_KEY = "sk-..." 這類寫法放進原始碼。
  2. 新手為了「先跑起來」,容易把密鑰硬編碼在前端、腳本或設定檔裡。
  3. 很多 vibe coding 平台可以直接部署應用,不一定經過 GitHub 的推送保護流程。
  4. 使用者可能不知道 AI 生成的專案裡到底有哪些檔案、哪些介面、哪些預設權限。

換句話說,AI 可以幫你更快寫出能跑的東西,但不會自動替你承擔安全責任。

.gitignore 不是裝飾

Git 負責版本管理,GitHub 負責託管程式碼,.gitignore 則是告訴 Git 哪些檔案不要納入版本歷史。

一個最基本的 AI 專案,至少應該把這些內容排除掉:

1
2
3
4
5
6
7
.env
.env.*
*.key
*.pem
config.local.*
secrets.*
credentials.*

但只寫 .gitignore 還不夠。它只能阻止「尚未被 Git 追蹤」的檔案繼續進入提交。如果某個密鑰檔案已經被提交過,後來再把它寫進 .gitignore,並不能把歷史記錄裡的密鑰抹掉。

更穩妥的習慣是:

  1. 新專案一開始就建立 .gitignore
  2. API Key 只放在環境變數或本機設定裡。
  3. 範例檔案只提供 .env.example,裡面寫佔位符,不寫真實密鑰。
  4. 提交前執行一次密鑰掃描工具,比如 gitleakstrufflehog 或 GitHub Secret Scanning。

Key 推上去以後,刪除檔案不等於安全

如果密鑰已經推到公開倉庫,第一反應不應該是「刪掉檔案再提交一次」,而應該是立刻吊銷或輪換密鑰。

原因很簡單:Git 記錄的是歷史。即使你在最新提交裡刪除了檔案,舊提交、fork、clone、快取和掃描系統裡仍可能保留那段內容。GitHub 官方文件也明確建議:如果外洩的是密碼、Token 或憑證,第一步應該撤銷或輪換。

處理順序建議這樣做:

  1. 立即去服務商後台吊銷舊 Key,生成新 Key。
  2. 檢查帳單、呼叫日誌、異常 IP 和異常用量。
  3. 從程式碼中移除硬編碼密鑰,改用環境變數或密鑰管理服務。
  4. git filter-repo 或 BFG 清理倉庫歷史中的敏感檔案。
  5. 開啟 GitHub Secret Scanning 和 Push Protection。
  6. 檢查 CI/CD、部署平台、雲函式、前端建置產物裡是否也包含舊 Key。

對於 OpenAI、Anthropic、DeepSeek、雲廠商、支付、郵件、資料庫等服務,外洩 Key 的後果可能不只是被刷額度,還可能包含資料讀取、服務濫用、供應鏈污染或業務帳號封禁。

前端程式碼裡不能放真正的密鑰

很多新手以為「只要頁面能跑就行」,於是把 API Key 寫進前端 JavaScript:

1
const apiKey = "sk-xxxxxxxx";

這基本等於公開。瀏覽器裡的程式碼、網路請求、Source Map、建置產物都可以被查看。只要是真正需要保密的 Key,就不應該出現在客戶端。

正確做法是讓前端請求自己的後端介面,由後端讀取環境變數並呼叫第三方 API:

1
2
3
4
5
// frontend
await fetch("/api/chat", {
  method: "POST",
  body: JSON.stringify({ message })
});

後端再使用環境變數:

1
2
// server
const apiKey = process.env.OPENAI_API_KEY;

這樣做不是為了形式好看,而是為了把密鑰留在伺服器環境裡,避免直接暴露給所有訪問頁面的人。

Vibe Coding 的安全責任不會自動消失

vibe coding 的問題不只是 GitHub 外洩。很多應用直接從 AI 編程平台發布到公網,跳過傳統程式碼審查、倉庫掃描和安全測試。

RedAccess 近期披露的研究顯示,公開網路上可以找到大量由 AI 編程工具生成或託管的應用資產,其中一部分暴露了企業資料、個人資訊或內部檔案。它提醒的是同一件事:當「能上線」變得太容易,「是否應該上線」「是否只該內網訪問」「是否有權限控制」就更容易被忽略。

如果你用 AI 生成應用,至少要在發布前問自己幾個問題:

  1. 這個應用是否真的需要公開訪問?
  2. 是否有登入、鑑權和權限隔離?
  3. 是否把資料庫、API Key、Token、Webhook 地址暴露在前端?
  4. 是否限制了第三方 API 的額度、網域、權限和有效期?
  5. 是否能在發現異常後快速停用密鑰和回滾部署?

AI 寫出來的程式碼也需要安全審查。越是「我一行程式碼都沒寫」,越不能假設它天然安全。

現在就該做的檢查

可以先從自己的 GitHub 帳號查起。搜尋使用者名稱加上這些關鍵字:

1
2
3
4
5
6
7
8
9
API_KEY
SECRET
TOKEN
OPENAI_API_KEY
ANTHROPIC_API_KEY
DEEPSEEK_API_KEY
.env
config
credentials

如果發現真實密鑰,不要猶豫:先輪換,再清理。只要它進過公開倉庫,就按已經外洩處理。

以後新建 AI 專案時,也建議固定一套流程:

  1. 先寫 .gitignore,再寫業務程式碼。
  2. .env.example 說明需要哪些變數。
  3. 所有密鑰放環境變數,不寫進原始碼。
  4. 給 API Key 設定最小權限、額度限制和過期時間。
  5. 開啟 GitHub Secret Scanning 和 Push Protection。
  6. 發布前讓 AI 再幫你做一次安全檢查,但不要只相信 AI 的結論。

AI 編程真正危險的地方,不是它會寫錯程式碼,而是它讓很多人第一次擁有了把不安全應用快速發布到公網的能力。寫得快不是問題,把密鑰、資料和權限一起交出去才是問題。

參考資料

记录并分享
使用 Hugo 建立
主題 StackJimmy 設計