API Key 放在環境變數就安全了嗎?

把 API Key 從程式碼移到環境變數,擋掉的只有 1 種外洩路徑。這篇拆解環境變數沒有解決的 4 件事,並用我自己外洩過 1 次的經驗,走完撤銷、重發、檢查、改流程這條完整順序,最後給你今天就能做的 3 件事。

30 秒重點

  • 環境變數只解決 1 件事:把祕密從程式碼裡拿出來,讓它不會跟著程式碼被複製、被推上版本控制、被別人看到。
  • 它沒有解決的有 4 件:祕密仍然是明文、你把保管責任交給了平台、一把鑰匙開很多門、用了沒用你不會知道。
  • 我自己外洩過 1 次。走完的流程是:發現、撤銷並重發、檢查用量與帳單、把做法寫成規則。
  • 今天就能做的 3 件事:每個用途發不同的 Key、設用量上限與警示、把載入方式固定成唯一 1 條路。

用 AI 幫忙寫程式、串服務、架網站之後,幾乎每個人都會遇到同一個問題:API Key 要放哪裡。

網路上的答案很一致:不要寫在程式碼裡,放環境變數。

這個答案是對的。我想補的是後半段:放進環境變數之後,你的安全程度到底到哪裡。因為我看過太多人做完這一步就安心了,包括我自己。

環境變數真正解決的是哪一個問題

環境變數解決的是祕密跟著程式碼一起跑掉。

程式碼會被複製、會被推上 GitHub、會被貼進聊天視窗請人幫忙看、會被打包丟給別人。祕密只要寫在裡面,上面每一個動作都是一次外洩機會。而且版本控制會記住歷史,你事後刪掉那一行,舊的紀錄裡還留著。

把祕密抽到環境變數,這條路就斷了。程式碼裡只剩一個名字,值在別的地方。

這一層很有用,也確實比寫死在程式碼裡安全得多。問題是它只擋住這一種外洩路徑。

環境變數沒有解決的 4 件事

1. 它是明文的

環境變數不是加密儲存,它是換個地方放的明文。任何能進到那台機器、那個後台、那個部署平台的人,都看得到完整的值。

2. 你把保管責任交給了平台

當你把 API Key、資料庫密碼、各種 Token 全部貼進某個部署平台的環境變數欄位,你其實是在做一個決定:我信任這個平台會保管好我全部的鑰匙。

這個決定本身沒有錯,畢竟你總得放在某個地方。但要知道自己做了這個決定,因為平台一旦被攻破,你放在裡面的東西會一起出去。這種事這 1 年在好幾個部署平台上都發生過,而且受影響的人往往是被通知了才知道。

3. 一把鑰匙開很多門

很多人只發 1 組 Key,然後測試用它、正式網站用它、寫來玩的腳本也用它。

平常沒感覺,出事的時候差別很大:如果每個用途各自有一把,你只要撤銷出問題的那一把,其他服務照常運作;如果全部共用,你撤銷的瞬間所有東西一起停。這會讓你猶豫該不該撤銷,而猶豫的那幾個小時就是對方還能用的時間。

4. 被用了你不會知道

Key 外洩最麻煩的地方在於,它不會發出聲音。對方拿去用,你的服務照常運作,直到帳單出來。

沒有設用量上限跟警示,你等於沒有任何異常訊號。

我自己外洩過 1 次

我踩過這個坑,而且是用一種很笨的方式。

當時我為了讓一個流程跑起來,臨時想了一個辦法把憑證帶進去。那個做法在當下看起來沒問題,執行也成功了。我沒有想到的是,那種帶法會讓憑證的值出現在執行紀錄裡。

我是事後自己翻工作紀錄的時候看到的。那一刻的感覺很難形容,因為紀錄就攤在那裡,已經寫進去一段時間了。

我當下做的事情照順序是這樣:

  1. 撤銷並重發。 先回到發這把 Key 的原始服務,把舊的停用、發一把新的。這一步不能省略,也不能只在部署平台那邊把環境變數改掉。改掉環境變數只是讓你的程式改用新的值,對方手上那把舊的還是活的,要回原廠停用才會真的失效。
  2. 檢查有沒有被用過。 回頭看用量紀錄、帳單、登入紀錄,確認這段時間有沒有不是我發出的請求。
  3. 檢查同一組祕密還出現在哪裡。 一把鑰匙常常不只複製過一次,要把所有副本都找出來一起換掉。
  4. 把做法寫成規則。 這一步最重要,也是我當時唯一做對的事。

為什麼第 4 步最重要

因為前 3 步處理的是這 1 次,第 4 步處理的是下 1 次。

我的失誤根本不是技術問題。我知道憑證不能亂放,我也不是第一天處理這種事。我出錯的原因很單純:當下沒有一條現成的安全路徑可以走,所以我自己想了一個。

只要安全做法需要當下記得、需要臨時判斷,它遲早會失守。因為出錯的那一刻,人通常正在趕時間。

所以我後來把它改成一條規則:這件事只有 1 種做法,沒有第 2 種。 如果某個服務還沒有對應的安全載入方式,那就代表現在沒有安全路徑,要先把路建好再繼續,而不是繞過去。

聽起來很囉唆,但它把一個要靠自制力的問題,換成了一個只有 1 個選項的問題。後者穩定得多。

我在驗收 AI 做的事這篇裡也提過類似的邏輯:真正有用的檢查,是那種你沒做就會被擋下來的檢查,而不是你記得才會做的檢查。

那到底該怎麼放

先說結論:環境變數可以繼續用,它仍然比寫在程式碼裡好很多。要補的是它周圍那幾層。

做法為什麼有用
每個用途發 1 把不同的 Key出事只需要撤銷 1 把,其他服務不受影響
正式環境與測試環境分開測試用的東西不該碰得到正式資料
權限只開必要的範圍存取權杖只開放指定的專案或指定的資料表
設用量上限與帳單警示給自己 1 個異常訊號,優先選可以儲值、有額度上限的付款方式
把載入方式固定成唯一 1 條路讓安全做法不依賴你當下記不記得
定期換一次就算沒出事也換,因為你不會知道自己有沒有出事

需要同時管很多服務的話,可以再往上走一層,用專門的密鑰管理工具,讓部署平台只保留一張取用憑證,真正的鑰匙放在別處。不過對 1 人公司這個規模來說,把上面那張表做到,已經擋掉絕大多數的情況。

你今天可以做的 3 件事

  1. 打開你的 AI 服務後台,看看你總共發過幾把 Key,各自在哪裡用。 多數人會發現有 2 到 3 把已經忘記是給誰的,那些直接撤銷。
  2. 去設用量上限跟帳單警示。 這件事 5 分鐘就做得完,而它是你唯一的異常訊號。
  3. 想一下你的憑證是怎麼進到程式裡的,那個方法會不會被記錄下來。 執行紀錄、除錯輸出、命令列歷史,都是會留存的地方。

安全這件事很難一次做到位,很多觀念都是踩過才會真的理解。所以不用因為做不完整就焦慮,先把基本的擋起來,遇到事件再順便學起來。

我用 AI 處理網站後台的操作時也是同一套原則:先決定 AI 碰得到什麼、碰不到什麼,再讓 AI 動手。讓危險的做法在流程上就走不通,你才不用每次都靠記憶力去擋。

探索更多來自 下班後一人公司 的內容

立即訂閱即可持續閱讀,還能取得所有封存文章。

繼續閱讀