密鑰的輪替與安全的保管
密鑰
輪替
安全性
金鑰管理
本文的對象
適用於想定期更新(輪替)正式運用中應用程式的密鑰的運用負責人。
適用於想定期更新(輪替)正式運用中應用程式的密鑰的運用負責人。
密鑰有「用越久同一個,洩漏風險就越累積」的性質。離職的成員過去閱覽過、混入日誌輸出、包含在備份中被帶出——都是可能的途徑。以定期的輪替,用時間切割洩漏的影響範圍,是基本策略。
輪替頻率的參考
| 對象 | 建議頻率 | 即時更新的契機 |
|---|---|---|
| 用戶端密鑰 | 每年 1 次 | 疑似洩漏、離職、洩漏事件 |
| Webhook 密鑰 | 每年 1 次 | 同上 |
| 存取權杖 | 自動(1 小時) | ― |
| 刷新權杖 | 自動(90 天) | ― |
用戶端密鑰的輪替步驟
ReceiptRoller 支援「新舊密鑰的並行期間」,因此可無停機地輪替。
- 開發者入口網站 → 應用程式 → 憑證 → 「追加發行密鑰」
- 將新密鑰安全地保管
- 將密鑰管理服務(AWS Secrets Manager 等)的值更新為新密鑰
- 依序部署正式環境(或以滾動重啟反映環境變數)
- 以日誌確認全環境都以新密鑰運作
- 在開發者入口網站將舊密鑰「失效」
並行期間中兩方的密鑰皆有效。部署過程中即使以舊密鑰來了請求,驗證也會通過,因此可無停機切換。
Webhook 密鑰的輪替
Webhook 密鑰同樣可並行期間運用。在接收端做成「以新舊兩方的密鑰嘗試簽章驗證」的實作,切換期間就安全。
function verify(body, signature, ts) {
return verifyWith(body, signature, ts, NEW_SECRET)
|| verifyWith(body, signature, ts, OLD_SECRET);
}
切換完成後,從程式碼刪除 OLD_SECRET 的參照。
保管的最佳實務
- 使用密鑰管理服務:AWS Secrets Manager / Azure Key Vault / GCP Secret Manager / HashiCorp Vault
- 環境變數的加密:登錄至 CI 時使用加密功能(GitHub Secrets、GitLab CI Variables 等)
- 存取稽核:使能追蹤誰在何時取得密鑰的狀態
- 最小權限:正式密鑰僅正式的服務帳戶可取得
- 備份非含有:DB 備份或日誌歸檔中不含密鑰
- 離職時離職手續:離職者曾存取的密鑰即時輪替
不可做的事
| 反模式 | 因應 |
|---|---|
| 將 .env 檔案提交至 git | 加入 .gitignore,過去的混入連歷史一起刪除+密鑰重新產生 |
| 以 Slack 或電子郵件分享密鑰 | 經由密鑰管理服務分享 |
| 嵌入用戶端側程式碼 | 移動至伺服器端,即時重新產生 |
| 在錯誤日誌輸出密鑰 | 遮罩處理、日誌刪除、重新產生 |
| 多年使用同一密鑰 | 將年度輪替登錄至行事曆 |
相關指南
發布日: 2026-04-27
更新日: 2026-07-06