這篇是〈Zeabur 搬家前先換金鑰〉第二步的詳細版。還沒看過總表的,建議先看那篇,知道換金鑰在整個搬家流程的哪個位置。
文中 Zeabur 的說法引自官方狀態頁與官方報告,各家服務的做法引自各家官方文件,查詢日期都是 2026 年 10 月 18 日。各家介面常改,實際操作以官方頁面為準。
狀態頁說外洩了什麼、要你做什麼
Zeabur 狀態頁〈Unauthorized Access to Zeabur Infrastructure and User Data〉在 10 月 16 日(台北時間)的更新寫明,攻擊者可讀平台資料庫,外洩項目包括服務的環境變數、帳號資料、API token 與 zSend API key。同一頁要用戶做的事共 7 項,第一項就是輪換環境變數裡的所有密鑰。
8 月那次事件的官方報告也說了兩件事,這次一樣適用:
- 要換的是所有曾存放在 Zeabur 環境變數、而且仍然有效的憑證,包括通知中沒列出的項目。
- 環境變數改存在別的地方,不會讓舊憑證失效,仍然要換。
哪些一定要換?
判斷很簡單:曾經放進 Zeabur 環境變數、現在還有效的,都換。 不管是哪個服務、多久以前放的、你覺得重不重要。
8 月事件時,狀態頁列過一份外洩變數名稱的例子,可以拿來對照自己的清單:AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、CF_API_TOKEN、CLOUDFLARE_API_TOKEN、GITHUB_TOKEN、OPENAI_API_KEY、ANTHROPIC_API_KEY、GEMINI_API_KEY、STRIPE_SECRET_KEY、DATABASE_URL、MONGODB_URI、POSTGRES_PASSWORD、REDIS_PASSWORD、JWT_SECRET、PRIVATE_KEY、SECRET_KEY 等。狀態頁也說,名稱自訂的變數,只要值符合 AWS、GitHub、Anthropic、OpenRouter、OpenAI、Stripe 的憑證格式,一樣算在內。
兩種容易漏掉的:
- 連線字串裡的密碼:DATABASE_URL、MONGODB_URI、REDIS_URL 這類,密碼藏在網址裡,名稱看不出是密碼。
- 已經從 Zeabur 刪掉、但在原服務還有效的金鑰:環境變數刪了,不代表金鑰失效。8 月事件後沒換過的,這次一定要換。
換金鑰的通用順序:先建新的、換上去、確認、再撤舊的
大部分金鑰照這四步,服務可以不停:
- 到發金鑰的服務建立一組新的。
- 把新的設進你的服務(還在 Zeabur 上就設在 Zeabur,已經搬了就設在新環境)。
- 確認服務正常,舊金鑰的用量歸零。
- 撤銷或刪除舊的。只建新的、不撤舊的,等於沒換。
有些服務一換舊的就失效,那就排在離峰時間做。下一節的表格標出了哪些可以新舊並存。
例外:已經發現被盜用,或該服務官方建議外洩時先撤銷(例如 Resend),就先撤銷、再建新的,服務停一下比繼續被盜用便宜。
各家服務怎麼換、去哪查舊金鑰有沒有被用
| 服務 | 怎麼換 | 新舊能不能並存 | 去哪查舊的有沒有被用 |
|---|---|---|---|
| AWS IAM access key | 建第二把 → 更新程式 → 舊的先停用(Deactivate)→ 確認沒問題再刪除 | 可以,每個使用者最多兩把 | IAM 的「Last used」欄位;CloudTrail 事件會記錄 access key ID 與來源 IP |
| Google Cloud 服務帳戶金鑰 | 先停用再刪除;刪除後無法還原,而且不會撤銷這把金鑰已經簽發的短效憑證 | 可以,建新金鑰後舊的先停用 | Activity Analyzer 看金鑰最後驗證時間;Metrics Explorer 看金鑰驗證事件 |
| Stripe secret key | API keys 頁按 Rotate key,選舊金鑰多久後失效 | 可以,新舊最多並存 7 天 | 每把金鑰的「View request logs」 |
| Stripe webhook 簽章金鑰 | Workbench 的 Webhooks 分頁選 endpoint,按 Roll secret | 可以,舊的最多延後 24 小時失效 | endpoint 的 Event deliveries |
| Anthropic(Claude)API key | Console 的 API keys 頁停用(Disable,可恢復)或刪除(永久)舊的,建立新的 | 先建新的再停用舊的;官方沒寫停用後多久生效 | Console 的 Usage 頁可選單一金鑰看用量 |
| OpenAI API key | API keys 頁建立新的、刪除舊的;官方說撤銷幾秒內生效 | 先建新的再刪舊的 | Usage 頁可依專案、使用者篩選;要依金鑰查,用 Admin 的 Usage API(api_key_ids 參數) |
| Gemini API key | 在 Google AI Studio 或 Cloud console 建新的,確認可用後停用舊的;建議限制只能用 Gemini API。Google 2026 年起收緊未加限制的金鑰(例如封鎖長期閒置、未加限制的金鑰),新金鑰記得加限制 | 可以 | Google Cloud console 的帳單與 API 用量;建議設帳單警示 |
| GitHub personal access token | 刪除舊 token,建立新的;Deploy key 沒有到期日,要手動刪。用某個 PAT 建立的 deploy key,刪掉那個 PAT 時會一起被刪,記得重建 | 先建新的再刪舊的 | 個人 Security log(保留 90 天) |
| GitLab access token | Rotate 產生權限相同的新 token | 舊的隨即失效 | token 頁的最近使用 IP;Authentication log |
| GitHub OAuth app client secret | 產生新 secret → 程式改用新的 → 刪除舊的 | 可以 | 個人 Security log |
| Google OAuth client secret | Add Secret 加第二組 → 程式改用新的 → 停用舊的 → 刪除 | 可以,最多兩組;官方提醒換完要儘快停用舊的 | 官方沒有查舊 secret 用量的地方 |
| LINE Messaging API | Channel access token 重新發行;channel secret 在 LINE Developers Console 的 Basic settings 重新發行 | 長期 token 重發時,舊的可延後最多 24 小時失效;channel secret 官方公開文件沒寫 | 官方沒有查舊憑證用量的地方 |
| Discord bot token | Bot 頁按 Reset Token | 舊 token 何時失效,官方文件沒寫 | 官方沒有查舊 token 用量的地方 |
| Telegram bot token | 官方寫外洩時在 @BotFather 用 /token 產生新的 | 官方沒寫舊 token 何時失效 | 官方沒有查舊 token 用量的地方 |
| Cloudflare API token | My Profile → API Tokens → Roll | Roll 會讓舊的失效 | Audit Logs:紀錄保留 18 個月,後台可查最近 90 天,更早的用 API 查 |
| Resend API key | 官方建議先刪除外洩的金鑰(刪除立即撤銷)再建新的;服務還在用那把才先換再刪 | 可以 | API keys 頁的最後使用時間;Logs 可依金鑰篩選 |
| Supabase | 改用新式 secret key 取代 service_role,停用舊的 legacy key;JWT secret 改用 signing keys 輪換 | legacy key 停用可恢復 | 官方沒有查舊金鑰用量的地方 |
| MongoDB Atlas | Database Access 改密碼或刪除使用者 | 依使用者 | Access tracking 看認證請求的 IP |
| Docker Hub/npm token | Docker 可停用 token;npm 用 npm token delete | 先建新的再刪舊的 | Docker token 清單的最後使用時間 |
| SSH 私鑰 | 環境變數裡存的是私鑰,就要把對應的公鑰從所有主機的 authorized_keys 與 Git 平台撤掉 | 先加新公鑰再刪舊的 | 主機的登入紀錄 |
資料庫密碼怎麼換
資料庫密碼要在資料庫裡改,改完再更新連線字串。
PostgreSQL:用 psql 的 \password 帳號 指令改。官方文件提醒,直接下 ALTER ROLE ... PASSWORD '新密碼',明文密碼可能留在用戶端的指令紀錄或伺服器日誌裡。
MySQL 8:可以讓新舊密碼暫時並存,服務不用停:
ALTER USER '帳號'@'%' IDENTIFIED BY '新密碼' RETAIN CURRENT PASSWORD;
-- 所有服務都換成新密碼後
ALTER USER '帳號'@'%' DISCARD OLD PASSWORD;
換完順便看一下資料庫裡有沒有陌生的帳號、資料表或排程,以及目前有哪些連線:PostgreSQL 看 pg_stat_activity 的 client_addr,MySQL 看 SHOW PROCESSLIST 的 Host 欄,有不認得的來源就要追。在 Zeabur 共享叢集上跑 PostgreSQL 或 MySQL 的要特別仔細:狀態頁第一則更新寫明,這次最早確認遭未授權存取的,就是仍跑在已淘汰共享叢集上的 PostgreSQL 與 MySQL。
應用程式自己的金鑰:分清楚「簽章」和「加密」
環境變數裡常有 JWT_SECRET、SESSION_SECRET、APP_KEY、ENCRYPTION_KEY 這類你自己產生的金鑰。它們要換,但要先分清楚用途:
- 簽章用的(JWT、session):換掉後,所有使用者要重新登入,資料不受影響。排在離峰時間做即可。
- 加密資料用的(有些框架與工具會用環境變數裡的金鑰,加密存在資料庫裡的資料或憑證):不能直接換。換了之後,舊資料會解不開。要先查那個軟體官方的換金鑰做法,通常是先用舊金鑰解密、再用新金鑰重新加密。
不確定某個金鑰是哪一種,先在程式碼裡搜尋它被用在哪裡,或查該軟體的官方文件,再動手。
發現舊金鑰被用過,怎麼辦?
- 立刻撤銷被盜用的金鑰,不等新金鑰設好。服務停一下,比繼續被盜用便宜。
- 截圖保存證據:用量圖、帳單、請求紀錄,記下時間與金額。
- 聯絡發金鑰的服務,詢問盜刷費用能不能處理。
- 向 Zeabur 申請資安事件損失賠償:依官方停運公告,賠償透過 Zeabur Support 申請,要註明是賠償、不是退款。官方沒寫這次要附什麼;8 月事件時官方要的是供應商用量紀錄、時間與金額,並請用戶先撤銷憑證、只提供遮蔽過的識別資訊,可以照這個方式準備。
輪換紀錄表
邊換邊記,之後申請賠償、搬家設定、下次輪換都用得到。只記名稱與狀態,不記金鑰的值:
| 變數名稱 | 發行的服務 | 新金鑰建立日 | 舊金鑰撤銷日 | 外洩期間有沒有異常用量 | 備註 |
|---|---|---|---|---|---|
| OPENAI_API_KEY | OpenAI | ||||
| DATABASE_URL | 自家 PostgreSQL | ||||
| STRIPE_SECRET_KEY | Stripe |
搬到新環境後,建議再換一次:在新環境產生一組新的,把在 Zeabur 用過的那組撤銷。這樣不管 Zeabur 端之後發生什麼,都跟你的服務無關。
揭露
火曜領航有提供金鑰輪換與資安檢查服務。這篇的步驟不需要找任何人也能自己做。
如果您的服務還在 Zeabur 上,需要人幫忙盤點、搬遷或輪換金鑰,可以到〈PaaS 停運搬家與資安檢查服務〉看四種做法,或直接填寫詢價表單,我們會在一個工作日內回覆搬遷順序建議。
常見問題
我的服務一直正常,也沒收到 Zeabur 的通知,還要換嗎?
要。狀態頁寫明可能外洩的是服務的環境變數,第一項處置就是輪換環境變數裡的所有密鑰。官方說受影響的客戶會另外直接聯絡,但沒收到聯絡不代表金鑰沒被讀走。
8 月事件後已經換過了,這次還要再換嗎?
要。10 月是另一次事件,8 月換上的新金鑰如果放在 Zeabur 環境變數裡,這次一樣在外洩範圍內。
換金鑰會讓服務停掉嗎?
多數不會。先建新的、換上去、確認正常後再撤舊的,服務可以不停。Roll 之後舊的就失效的(例如 Cloudflare API token),排在離峰時間做。
只換 AI 的 API key 夠嗎?
不夠。AI 的 API key 被盜用最容易從帳單看出來,但資料庫密碼、雲端存取金鑰、OAuth secret 外洩,影響可能更大,也更難發現。
金鑰的值可以貼給 AI 工具幫我整理嗎?
不建議。整理清單只需要變數名稱。金鑰的值貼到任何聊天或 AI 工具,都等於多了一個外洩的地方。
參考來源
- Zeabur Status:Unauthorized Access to Zeabur Infrastructure and User Data(2026 年 10 月事件)
- Zeabur Status:Unauthorized Access to Project Environment Variable Data(2026 年 8 月事件)
- Zeabur:Zeabur 2026 年八月資安事件(2026-09-07)
- Zeabur,2026-10-17:Zeabur 停止營運公告與服務遷移安排
- AWS:Update access keys
- Google Cloud:Create and delete service account keys
- Stripe:API keys、Webhooks
- Anthropic:API key 外洩處理
- Google AI for Developers:Using Gemini API keys
- GitHub:Managing your personal access tokens
- Google Cloud 說明:OAuth client secret 輪換
- LINE Developers:Channel access token
- Telegram:Bot features
- Cloudflare:Roll API token
- PostgreSQL:ALTER ROLE
- MySQL:ALTER USER
- GitLab:Personal access tokens
- Supabase:API keys
- MongoDB Atlas:Access tracking
- Docker:Access tokens;npm:Revoking access tokens
- PostgreSQL:Monitoring stats
- Resend:How to handle a leaked API key
以上資料皆於 2026 年 10 月 18 日查詢。
最後更新: