AI 程式開發與代理

[Vibe Coder #2] API 到底是什麼,為什麼要隱藏 API 金鑰?

上一篇把 App 比喻成餐廳:用餐區(前端)、廚房(後端)、倉庫(DB)。這次要談 Vibe Coding 最容易出問題的主題:API,以及 API 金鑰。大家都看過「絕對不要公開金鑰」的警告,但很少有人說明金鑰是什麼、在哪裡,以及外洩後會發生什麼事。本文一次整理清楚。

閱讀 5 分鐘
[Vibe Coder #2] API 到底是什麼,為什麼要隱藏 API 金鑰? 封面圖

上一篇把 App 比喻成餐廳:用餐區(前端)、廚房(後端)、倉庫(DB)。這次要談 Vibe Coding 最容易出問題的主題:API,以及 API 金鑰。大家應該都看過「絕對不要公開金鑰」的警告,但真正說明金鑰是什麼、在哪裡,以及外洩後會發生什麼事的文章並不多。本文一次整理清楚。

API 就是點餐櫃檯

API 是 Application Programming Interface 的縮寫,忘記全名也沒關係。重點是這個。API 是讓程式彼此交辦工作的點餐櫃檯。

回到餐廳的比喻,客人不能進廚房,只能用規定的格式送出訂單:「泡菜鍋一份,少辣。」接著廚房會自行製作並送出。API 正是這個櫃檯。向指定網址送出指定格式的請求,就會收到指定格式的回應。

Vibe Coder 製作的 App 中,API 存在於兩個方向。

  • 我的 App 的 API:我的前端向我的後端交辦工作的櫃檯。上一篇提到的 app/api/ 資料夾就是它。
  • 別人的 API:我的 App 向其他公司的服務交辦工作的櫃檯。請 ChatGPT 寫文章(OpenAI API)、顯示地圖(地圖 API)、處理付款(付款 API),全都是向別人的櫃檯送出訂單。

用 Vibe Coding 製作的 App,大多是組合這些「別人的 API」來運作。而要向別人的櫃檯下單,有一樣東西是不可或缺的。

展示 FRONTEND、MY BACKEND、EXTERNAL API 之間請求流程的結構圖,API KEY 只放在 .env 與部署儀表板,絕不放在前端
金鑰能走的路只有一條:從後端前往外部 API

API 金鑰就是公司卡

別人的 API 不是免費櫃檯。每向 OpenAI 發送一次請求,就會產生費用。因此每個請求都帶著一張身分證,說明「這筆訂單要向誰請款?」那就是 API 金鑰,也就是像 sk-proj-... 這樣又長又隨機的字串。

API 金鑰的特性和公司卡完全一樣。

  • 不論是誰刷卡,帳單都會寄給持卡人。
  • 只要知道卡號就能使用。不需要人臉確認,也不需要簽名確認。
  • 所以把卡號寫在公開場所,就等於讓全世界任何人都能用我的錢付款。

「要隱藏金鑰」這個警告之所以如此嚴重,原因就在這裡。金鑰外洩和密碼外洩不同。密碼改掉就好,但從金鑰遭竊到重新簽發期間產生的所有費用,都會累積到我的帳單上。

外洩後實際會發生什麼

很容易想:「誰會找到我小 App 的金鑰?」但這是最危險的誤解。找出金鑰的不是人,而是機器人

機器人掃描公開程式碼儲存庫並找出 sk- 金鑰的插圖,搭配「BOTS FIND LEAKED KEYS IN MINUTES」文字
找出金鑰的不是人,而是全天候運作的機器人

GitHub 等公開程式碼儲存庫,每天 24 小時都有數千個機器人掃描新程式碼。如果不小心把含有金鑰的程式碼上傳到公開儲存庫,機器人通常會在幾分鐘內收走。被收走的金鑰會立即被用來免費呼叫 AI、支付加密貨幣挖礦費用、發送垃圾訊息等。社群持續出現一夜之間被收取數百萬韓元帳單的事故案例,就是因為這個原因。

另一條外洩途徑就是上一篇談過的:**把金鑰放進前端。**前端程式碼會傳送到使用者的瀏覽器,因此只要按一次滑鼠右鍵選擇「檢查」,任何人都能取出金鑰。讓 AI「幫我串接 OpenAI」時,AI 確實可能為了方便把金鑰硬編碼到前端,因此一定要親自確認。

金鑰應該放在哪裡

原則在上一篇已經出現過:**秘密放在後端。**具體如下。

  • 把金鑰寫在專案的.env檔案中。這是只有後端能讀取的秘密值保管庫。
  • .env檔案登錄到.gitignore,讓 Git 不要追蹤它。如此即使把程式碼上傳到 GitHub,金鑰也只會留在我的電腦上。AI 產生的專案通常已經登錄,但仍值得親自確認一次。
  • 部署後的 App 無法讀取我電腦上的.env,因此要到 Vercel 等部署服務的儀表板,在「Environment Variables」選單中另外登錄金鑰。這部分會在第 4 篇(部署)再次說明。

Next.js 還有另一個陷阱。如果環境變數名稱以NEXT_PUBLIC_開頭,該值也會傳送到**前端。**顧名思義,就是 public、公開的意思。只有地圖顯示用金鑰等設計上可以公開的金鑰才能放在這裡;OpenAI 等會產生費用的金鑰絕對不能加上NEXT_PUBLIC_。如果是 AI 加上的,這本身就是危險訊號。

我的 App 自我檢查方法

現在就能確認的有 3 項。

  1. 瀏覽器檢查:在已部署的網站按滑鼠右鍵 → 檢查,接著在上方的 Network 或 Sources 分頁搜尋sk-keysecret等詞。如果搜尋到我的秘密金鑰,就代表已經外洩。
  2. GitHub 檢查:如果儲存庫是公開(Public)狀態,就在儲存庫搜尋欄搜尋金鑰的前段。即使只留在過去的 commit 中,也算外洩。
  3. 請 AI 進行稽核:「請找出這個專案中所有會將 API 金鑰或秘密值傳送到前端的地方。」建立時犯錯的 AI,在尋找時也可能找得很好。

如果已經外洩

把外洩的金鑰藏起來沒有用。必須假設機器人已經複製走了。順序如下。

  1. 在該服務的儀表板中**刪除(撤銷)**該金鑰。從這一刻起,盜用就會停止。
  2. 簽發新的金鑰,這次只放在.env和部署儀表板中。
  3. 設定服務的使用量上限(spending limit)。這會成為下一次事故的損失上限。這部分會在第 7 篇(費用爆炸)詳細說明。

總結

  • API 是程式彼此之間的點餐櫃檯,而我的 App 是組合別人的 API 來運作。
  • API 金鑰就是公司卡。不管誰使用,帳單都會寄給我。
  • 機器人會在幾分鐘內找出金鑰。「我的 App 很小」不能成為防護措施。
  • 金鑰只能放在兩個地方:.env(本機)和部署儀表板的環境變數。帶有NEXT_PUBLIC_的計費金鑰就是危險訊號。
  • 如果外洩,不要只把它藏起來,應依序撤銷 → 重新簽發 → 設定上限。

下一篇是 Git。我們會談 AI 明明能寫完所有程式碼,為什麼大家仍叫你使用 Git,以及 AI 把原本正常的 App 弄壞時,如何在 1 分鐘內復原。