點樣喺你嘅 App 保護 API 金鑰
要保護 API 金鑰,就將佢哋儲存為你主機上嘅機密或者環境變數,只喺伺服器端程式碼使用,而且絕對唔好貼去聊天、程式檔案、截圖或者 Git 程式碼庫。每條金鑰只畀佢需要嘅最小權限,並喺供應商設定消費上限;如果金鑰真係外洩,就要輪換它,即係建立一條新嘅再刪除舊嘅,而唔係只係將出現過嘅地方藏起來。
API 金鑰就好似一個服務嘅密碼。你嘅 OpenAI 金鑰可以俾人用嚟燒你嘅 AI 錢;你嘅 Stripe 秘密金鑰可以俾人發退款;你嘅電郵服務金鑰可以俾人用你嘅名寄信。AI App builder 好擅長將呢啲金鑰接駁入去,但未必次次都好小心佢哋最後去咗邊度,所以本指南會講點樣保護佢哋,同埋點樣檢查。
公開金鑰同秘密金鑰
並唔係所有金鑰都係秘密。搞清楚分別,就唔會為咗錯嘅金鑰驚惶,而忽略咗真正要保護嘅嗰條。
| 類型 | 例子 | 可以放喺瀏覽器嗎? |
|---|---|---|
| 公開金鑰 / 可公開金鑰 | Stripe 嘅 pk_… 金鑰、只限你網域使用嘅地圖金鑰、某啲分析 ID | 可以,係設計咗俾咁用 |
| 秘密金鑰 | Stripe sk_…、OpenAI 同 Anthropic 金鑰、電郵服務金鑰、資料庫密碼 | 絕對唔可以 |
| 服務 / 管理員金鑰 | 能夠繞過託管資料庫存取規則嘅金鑰 | 絕對唔可以——要當作最敏感嘅金鑰 |
如果你唔確定一條金鑰屬於邊類,請查閱服務供應商嘅文件。拿唔準嘅時候,當佢係秘密處理。
第 1 步:將金鑰儲存為機密,唔好放入程式碼
金鑰應該放喺你主機嘅環境變數或者機密設定入面。你嘅程式碼會喺運行時用名稱讀取(例如 process.env.OPENAI_API_KEY),所以個值永遠唔會出現喺你嘅檔案入面。關於背景,請睇什麼是環境變數同機密。
將每條 API 金鑰由程式碼移去環境變數。列出你搵到嘅每條金鑰、佢喺邊個檔案,以及你用咗嘅變數名稱。唔好顯示個值。
然後檢查有冇遺漏:
搜尋整個專案,包括設定檔同任何 .env 檔案,搵吓有冇似 API 金鑰或者密碼嘅嘢。報告檔案同行號,唔好報告個值。
第 2 步:秘密金鑰只喺伺服器使用
呢個係最重要嘅規則。瀏覽器收到嘅任何嘢,訪客都讀得到——頁面原始碼同 JavaScript 檔案,喺開發者工具入面都睇得到。
所以如果個 App 需要呼叫 OpenAI,瀏覽器應該呼叫你自己嘅伺服器,然後你嘅伺服器用金鑰去呼叫 OpenAI。金鑰永遠唔會離開伺服器。
聊天功能而家直接由瀏覽器呼叫 OpenAI。將呢個呼叫移去一個伺服器 API 路由,由環境讀取 OPENAI_API_KEY。瀏覽器只可以呼叫我哋嘅路由。呢個路由要求登入。
前端框架有一個常見陷阱:帶公開前綴嘅變數——Vite 嘅 VITE_,Next.js 嘅 NEXT_PUBLIC_——係特登被建入瀏覽器程式碼嘅。就算一個秘密金鑰「放喺環境變數」,只要用咗呢類前綴,就會外洩。
第 3 步:測試冇嘢外洩
唔好以為做咗就一定冇問題,去正式網站檢查:
- 喺瀏覽器打開已發佈嘅 App。
- 打開開發者工具,然後去 Sources 或者 Network 分頁。
- 喺所有檔案入面搜尋每條秘密金鑰嘅開頭幾個字(例如
sk_或者sk-)。 - 檢查 App 發出嘅網絡請求。如果有請求由瀏覽器直接去付費嘅 AI 供應商,就係紅旗。
如果你搵到秘密金鑰,就將佢移去伺服器(第 2 步),並且輪換佢(第 6 步),因為佢已經被公開過。
第 4 步:限制每條金鑰可以做嘅嘢
好多供應商容許你限制金鑰:
- 限定範圍或者受限制嘅金鑰,只可以做你個 App 需要嘅嘢。例如 Stripe 支援帶特定權限嘅受限金鑰。
- 網域或者 IP 限制,用於必須公開嘅金鑰,例如地圖金鑰。
- 每個 App、每個環境各用獨立金鑰,咁樣一條外洩都唔會暴露晒所有嘢,撤銷其中一條亦唔會搞壞其他嘅。
- 建構時用測試金鑰,只喺已發佈嘅 App 用正式金鑰。
第 5 步:為損害設定上限
就算金鑰保護得好,都可能透過你自己嘅 App 被濫用——例如有人用腳本,喺你嘅 AI 功能上面打幾千次。
- 喺每個收費嘅供應商設定消費上限或者提示。
- 任何每次呼叫都要收費嘅功能,都要求登入。
- 加入每位用戶嘅速率限制。參閱什麼是速率限制。
為 /api/chat 加入每位用戶每個鐘頭 30 次 AI 請求嘅限制。達到上限時,返回清楚嘅訊息。拒絕未登入用戶嘅請求。
第 6 步:輪換外洩嘅金鑰
如果一條秘密金鑰出現喺唔應該出現嘅地方——一則聊天訊息、一個 commit、一張截圖、一張支援工單、瀏覽器程式碼——就要當佢已經被盜用。
- 喺服務供應商建立一條新金鑰。
- 喺你 App 嘅設定更新機密。
- 重新部署或者重新發佈,令正式 App 用新金鑰。
- 喺服務供應商刪除舊金鑰。
- 檢查供應商嘅用量紀錄,睇吓有冇你唔認得嘅活動。
刪除聊天訊息或者 Git commit 並唔足夠。Git 歷史會保留舊版本,而任何公開過嘅嘢,可能已經俾人複製。
常見錯誤
- 將金鑰貼入提示。 佢已經喺聊天紀錄入面。改用機密表格。
- 秘密變數帶公開前綴。
VITE_OPENAI_API_KEY會將金鑰送俾每個訪客。 - Commit 咗
.env檔案。 首次 push 之前,確保佢喺.gitignore入面。 - 所有地方都用同一條金鑰。 測試同正式、每個 App 都要用獨立嘅金鑰。
- 冇消費上限。 一條外洩或者被濫用、又冇上限嘅金鑰,可以喺你發現之前已經燒掉一大筆錢。
- 隱藏而唔係輪換。 金鑰一旦外洩,只有換一條新嘅先可以真正解決問題。
- 截圖入面有金鑰。 分享去求助之前,先剪裁或者模糊設定頁面。
檢查清單
- 每條金鑰都儲存為機密或者環境變數,唔放喺程式碼入面。
- 冇
.env檔案或者金鑰被 commit 到 Git。 - 秘密金鑰只喺伺服器端程式碼使用。
- 冇秘密變數用
VITE_或者NEXT_PUBLIC_呢類公開前綴。 - 我喺正式網站嘅 JavaScript 度,搜尋過每條金鑰嘅前綴,搵唔到。
- 服務供應商允許嘅話,金鑰都有限定範圍或者受限制。
- 測試同正式金鑰分開。
- 收費功能要求登入,並且有每位用戶嘅限制。
- 每個收費供應商都有消費上限或者提示。
- 我知道點樣輪換每條金鑰,而任何曾經外洩嘅金鑰都已經輪換。
喺 Mythex 保護金鑰
Mythex 有兩種方法令金鑰唔入你嘅程式碼同對話:
- 機密請求卡。 當 Agent 需要金鑰時,佢會喺聊天入面顯示一張卡,你喺表格欄位入面輸入個值,唔係喺訊息框入面輸入,而佢會儲存為專案機密。參閱聊天中嘅機密。
- 專案設定 → 機密,或者聊天入面嘅
/secrets,你可以自己加入或者更改金鑰。參閱環境變數同機密。
改咗已發佈 App 嘅機密之後,要再次發佈,正式 App 先會用到新值。匯出嘅專案唔會包括機密,所以喺你下次運行程式碼嘅地方,要重新加入。如果金鑰曾經出現喺聊天入面,就要去服務供應商輪換佢。
上線前嘅其餘保安檢查,可以跟住 AI 建構 App 保安檢查清單去做。如果你加入 AI 功能,點樣使用 LLM API 會更深入講解金鑰同成本。
常見問題
將 API 金鑰放入前端程式碼安全嗎?
只有當服務供應商設計咗呢條金鑰係公開用嘅先安全,例如 Stripe 嘅可公開金鑰,或者只限你網域使用嘅地圖金鑰。任何可以花錢或者讀取私人資料嘅金鑰,都必須留喺伺服器,因為傳送去瀏覽器嘅嘢,任何人都讀得到。
如果我將 API 金鑰貼咗去聊天或者公開程式碼庫,應該點做?
輪換佢:喺服務供應商建立一條新金鑰,更新你 App 嘅機密,重新發佈,然後刪除舊金鑰。刪除訊息或者 commit 並唔足夠,因為副本可能已經存在。
API 金鑰應該儲存喺邊度?
儲存喺你主機嘅環境變數或者機密設定入面,由伺服器端程式碼喺運行時讀取。佢哋唔應該寫入原始檔、commit 到 Git,或者出現喺截圖入面。
我點樣知道我嘅 API 金鑰有冇喺網站上外洩?
打開你嘅正式網站,喺瀏覽器開發者工具睇頁面原始碼同 JavaScript 檔案,然後搜尋金鑰嘅開頭幾個字。如果搵到,就代表已經外洩,應該移去伺服器,並且輪換。